Forum Moderators: phranque

Message Too Old, No Replies

RewriteCond acting differently on two servers

         

asdf072

3:20 am on Aug 26, 2009 (gmt 0)

10+ Year Member



I have this in my .htaccess:

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^(.*)\.[A-Za-z]{2,4}$
RewriteRule ^(.*)$ index.php [L]

The next-to-last line is the problem. I wrote it to avoid sending requests for missing files (photos, js, etc) to my controller in index.php. (It basically says, if the request ends w/ a dot followed by 2 to 4 letters (as in a file extension), that condition is false.)

On my server(Apache 2.2.9), it works fine. On the production server (Apache1.3.41), it seems to ignore the regex.

So, if I put an <img> tag with a non-existent file, my server returns a 404 error, which is what I want. But, on the production server, I would get an error from my controller as if Apache ignored my condition, or it failed the regex for some reason.

Anyone have an idea?

jdMorgan

3:37 am on Aug 26, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Try re-coding it. This would be far more efficient:

RewriteEngine on
#
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.[a-z]{2,4}$ index.php [NC,L]

The reason it is more efficient is that that the (CPU-intensive, slow) OS filesystem calls to check for file- and directory- exists are now done only if the requested URL-path does not end with a period followed by 2 to 4 letters, case-insensitive matched.

As documented by Apache, RewriteConds are only processed if the RewriteRule pattern matches, and if you must do file- and/or directory-exists checking or reverse-DNS lookups, then the RewriteConds used to do these functions should be the very last ones whenever possible, and the rule pattern should be made as specific as possible to avoid processing any RewriteConds unless necessary.

RewriteBase / is the default, and isn't needed unless preceded in this file by RewriteBase /<something-else> directive, making it necessary to reset it to default for further rule processing.

Jim

asdf072

4:18 am on Aug 26, 2009 (gmt 0)

10+ Year Member



Thanks, Jim. Great suggestion.

However, it's still not cooperating. I double checked to make sure RewriteEngine was on (it is). Still, a request for a missing file like:

www.s.com/img/items/large/i-dont-exist.gif

That still gets sent to index.php.

jdMorgan

12:46 pm on Aug 26, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Have you got MultiViews or AcceptPathInfo enabled? If you don't need these features, turn them off.

See Apache core "Options" directive and (on Apache 2.x only) AcceptPathInfo

Also it may be obvious, but should check to be sure that index.php is not defined as your 404 error document (ErrorDocument directive).

Jim

asdf072

7:23 pm on Aug 26, 2009 (gmt 0)

10+ Year Member



Ok, I'm an idiot. I kept the default CPanel 404 file but didn't check to see if that page existed. It didn't, so the backup was index.php.

Thanks for your help, Jim. (Especially for the improved RewriteRule. I'm going to use that. )

jdMorgan

7:33 pm on Aug 26, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you use an ErrorDocument directive to define a new custom 404 error page to fix that problem, be sure to use a local path when specifying the document.

If you specify a full URL instead, then your server will generate a 302 redirect to the error document, and will not return a proper 404-Not Found response. Although the Apache documentation warns about this specifically, few Webmasters ever bother to read the documentation for the directives they try to use, so this is an extremely common error... and it can really sink a Web site!

Right:

 ErrorDocument 404 /errors/my-custom-404-page.xyz 

Wrong:

 ErrorDocument 404 http://example.com/errors/my-custom-404-page.xyz 

Jim