The following .htaccess file works perfectly on my local server.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} \.cssc
RewriteRule . style.php [L]
RewriteRule ^admin\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . admin.php [L]
I am doing some work for a client and he is using 1and1.com. I do not know anything about his account or what package he has.
All files are rewritten to admin.php (unless they actually exist). The problem is, I am getting a 404.
I know it's reading the .htaccess file because:
I can put garbage in the file and get a 500 error.
If I do a general rewrite (all pages go to admin.php), it works.
Also, it seems that 1and1 does it's own rewriting. If I go to: http://somewhere/afile, it will include afile.js even though I am not requesting the .js.It is super strange.
Does anyone have any experience with this? Or any insight?
To add some information..
1and1 seem to have some sort of default rewriting already in place that can interfere with your own rules - for example:
RewriteRule ^product$ /product.php [L]
It gave a 404 for this, and also for any other rewrite rule that matched a pre-existing .php file in my root folder.
2 things that 'fixed' it:
Change rewrite text to no longer match filename:
RewriteRule ^productz$ /product.php [L]
Or, change filename:
RewriteRule ^product$ /product_.php [L]
Both work - both very annoying.
The answer was simply "Do not nest .htaccess files". I had one in a sub folder.
Related
I already searched for the answer in other questions and tried a few solutions with no luck:
In the root of my website I use the following code in .htaccess and it works fine:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
But now I need to define that when I'm in the /admin directory it has to act normal.
Because when for example I link a stylesheet in a file in /admin, I have to define the src as "/admin/something.css" because else it will look for domain.com/css/something.css
Can someone tell me what to do?
Added:
RewriteRule ^admin - [L,NC]
Before anything else.
The - means do nothing.
The L means this should be last rule; ignore everything following.
The NC means no-case (so "ADMIN" is also matched).
Source
I've got an install of concrete5 living in my site root - the problem is that the C5 file structure is pretty varied, and it's getting mixed in with my subdirs and subdomains. I can't tell what's my code and what's C5, I hate it.
My solution is to move everything to a /_concrete/ folder - but since my domain has to point to the root, I can't use the files here.
Enter .htaccess: I need to write a script to redirect any instance of www.domain.com (ignore subdomains) to www.domain.com/_concrete/ - but not a transparent 301, just an alias. To clarify: www.domain.com/page/ and www.domain.com/_concrete/page/ should display the same thing. www.domain.com/page/ should NOT change it's URL to www.domain.com/_concrete/page/.
I've adapted this from a similar script I use elsewhere:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /_concrete/$1 [L,QSA]
But this only causes a server error. I hope I'm close - can anyone point me in the right direction?
You're telling the server to check if the value is not a filename, but you're not having it ignore the _concrete directory itself (which would also match your script and create a loop).
This might get you closer to what you're trying to do.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !^_concrete
RewriteRule ^(.*)$ _concrete/$1 [L,QSA]
Additionally you might want to have it ignore directories that exist as well. At which point _concrete would no longer be matched because it exists.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ _concrete/$1 [L,QSA]
In my web root (var/www) I have the following in my .htaccess file:
RewriteCond %{REQUEST_URI} ^system.*
RewriteCond $1 !^(index\.php|vges|images|robots\.txt)
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ /test/index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
I then have a subdirectory (/var/www/test) with a codeigniter project. It also has a .htaccess file with the following:
RewriteEngine On
RewriteCond $1 !^(index\.php|quiz|vges|buddy|css|fonts|img|images|js|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
When I visit localhost I can view the test directory and when I go to the test directory I'm displayed with the default controller view. But when I visit localhost/test/controller I get a 404 not found error:
The requested URL /index.php/events was not found on this server.
Edit: I found the solution by changing the last line /var/www/vges.htaccess to:
RewriteRule ^(.*)$ test/index.php/$1 [L]
Although I suspect if I was to upload this test project to a server, where it is not a subdirectory then I may get an error. What's the best solution to this? What should
I change in my .htaccess file so
I can have subdirectories on my local machine
When I upload them as individual projects (such as the test project) to a server I don't have to modify the .htaccess file.
Thanks.
First, .htaccess files apply to the directory they're in, and every child directory. Your CodeIgniter-specific rules should be in the var/www/test/ CI directory -- usually wherever CI's index.php file is.
Second, your root .htaccess is kind of weird. RewriteCond conditions accumulate until there a RewriteRule rule fires, then they are reset. Your two %{REQUEST_URI} conditions conflict with each other, since the URI can't start with both. I'm not really sure what this .htaccess rule is doing, but if your URLs starting at the root have no bearing on your CI application, I don't think it's necessary to have it there in the first place. I can't say for sure without knowing your directory structure and how you want your website to function.
kjetilh is right - unless your environments share exactly the same settings, it's unlikely an .htaccess will be universally functional. Your best bet is to start them as simple as possible, and modify as necessary. A good starting .htaccess for CI 2.1.x is something like:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
You can add your assets directories or any paths that you don't want redirected in the third RewriteCond (remember to properly escape regular expression characters such as periods). A RewriteBase rule definitely comes in handy if CI is in a subdirectory. You also don't need the system and application folder references with 2.1.x, since those folders have their own .htaccess files blocking access to them.
The way my site is currently structured, the actual site is in its own separate folder. Here's what I mean:
/projects
/files
/pictures
/tools
/school
/~webroot
.htaccess
This makes the file-system much easier to manage and navigate. An easy way to utilize this, without having everyone navigate to http://domain.com/~webroot/, and still allow them to access files and such like http://domain.com/projects/, is to use the htaccess I wrote below to check for files in both the real root, and ~webroot directories.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /~webroot/$1 [NC,QSA]
RewriteRule ^/?$ /~webroot/index.php [L,QSA]
However, if the file doesn't exist anywhere (root or ~webroot), an HTTP 500 error is thrown instead of an HTTP 404. In order to display my 404 error page, I have to instead use these lines:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/~webroot/$0 !-F
RewriteRule ^(.*)$ /404.shtml [B,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^/~webroot
RewriteRule ^(.*)$ /~webroot/$1 [NC,QSA]
RewriteRule ^/?$ /~webroot/index.php [L,QSA]
This is all quite messy, and it's only a trick and doesn't actually throw an HTTP 404, which keeps 404s from being documented using my statistics application. Is there a way to: Check if file exists in root, if not check if file exists in ~webroot, if not throw real HTTP 404 error?
I do also have all my ErrorDocument's defined properly.
I know this was a while ago, but wanted to chime in. For a rewrite rule to hit a 404, I always use this:
RewriteRule ^(.*)$ - [R=404,L]
I'm not sure if it's correct, but it works for me. I'm pretty sure it should always be with "L" to prevent further rewriting.
BTW, what is the "B" flag for? I only know the ones listed on the apache mod_rewrite page, so I'm lost on it's meaning.
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
EDIT: ah, my problem is I look at older version docs. Thank you, Swivelgames. I probably would have never even known I was looking at the older docs if you hadn't pointed that out (need to update my bookmarks).
http://httpd.apache.org/docs/2.3/rewrite/flags.html#flag_b
If you can make your 404 page a PHP file, you can add this before any output to get real 404's:
<?php header("HTTP/1.1 404 Not Found"); ?>
This will cause PHP to trigger a 'real' 404 (from the browsers point of view) which gets passed back to the browser. If your statistics package is internal to your server this approach may or may not work, I'm not sure.
The only other solution I can think of is to redirect to a non-existent file:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !/non-existent-404-generator
RewriteCond %{DOCUMENT_ROOT}/~webroot/$0 !-F
RewriteRule ^(.*)$ /non-existent-404-generator [B,L]
I have following rewrite rules for a website:
RewriteEngine On
# Stop reading config files
RewriteCond %{REQUEST_FILENAME} .*/web.config$ [NC,OR]
RewriteCond %{REQUEST_FILENAME} .*/\.htaccess$ [NC]
RewriteRule ^(.+)$ - [F]
# Rewrite to url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^(/bilder_losning/|/bilder/|/gfx/|/js/|/css/|/doc/).*
RewriteRule ^(.+)$ index.cfm?smartLinkKey=%{REQUEST_URI} [L]
Now I have to exclude a script including its eventually querystrings from the above rules, so that I can access and execute it on the normal way, at the moment the whole url is being ignored and forwarded to the index page.
I need to have access to the script shoplink.cfm in the root which takes variables tduid and url (shoplink.cfm?tduid=1&url=)
I have tried to resolve it using this:
# maybe?:
RewriteRule !(^/shoplink.cfm [QSA]
but to be honest, I have not much of a clue of urlrewriting and have no idea what I am supposed to write. I just know that above will generate a nice 500 error.
I have been looking around a lot on stackoverflow and other websites on the same subject, but all I see is people trying to exclude directories, not files. In the worst case I could add the script to a seperate directory and exclude the directory from the rewriterules, but rather not since the script should really remain in the root.
Just also tried:
RewriteRule ^/shoplink.cfm$ $0 [L]
but that didn't do anything either.
Anyone who can help me out on this subject?
Thanks in advance.
Steven Esser
ColdFusion programmer
Please try to put the following line at the top of your config (after RewriteEngine on):
RewriteRule ^shoplink.cfm$ - [L]