Rocking the blogosphere
Apple Online Store

What’s up with REQUEST_FILENAME in mod_rewrite?

I was trying to setup mod_rewrite rules for a CakePHP app running under Apache.

According to the mod\_rewrite docs, REQUEST\_FILENAME is “The full local filesystem path to the file or
script matching the request.”

If that were true, this idiom, which I’ve seen in a number of places,
should work to prevent the RewriteRule underneath it from firing when a request is made for a file which exists in the filesystem:

RewriteCond %{REQUEST_FILENAME} !-f

But it doesn’t. Looking at the rewrite log reveals that REQUEST_FILENAME, on my system at least, is not the full filesystem path; it is actually relative to the document root. Which means that the condition is never true and the rewrite will always happen.

So in order to get it to work, I have to do this ugly hack:

RewriteCond /home/y/share/htdocs%{REQUEST_FILENAME} !-f

Why?

Del.icio.us Digg Reddit Technorati

Possibly related posts

Comments

  1. Jonathan
    February 6th, 2007 | 4:41 am

    Did you ever find the solution to this? I’m having the same problem with a rewrite thing I’m doing at the moment..

    cheers,
    Jonathan.

  2. February 19th, 2007 | 6:51 am

    Looks like -f is context sensitive, I just ran into this problem, when used in .htaccess or inside a tag, it works correctly, outside it has the same behaviour as %{REQUEST_URI}, so:

    DocumentRoot “C:Site”
    ServerName http://www.mysite.com

    <Directory "C:\Site">
        Order allow,deny
        Allow from all
    </Directory>
    
    RewriteEngine On
    RewriteCond $1 (^/images/)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ /admin$1 [QSA,L]
    

    Will behave badly, however:

    DocumentRoot “C:Site”
    ServerName http://www.mysite.com

    RewriteEngine On
    <Directory "C:\Site">
        Order allow,deny
        Allow from all
    
        RewriteCond $1 (^/images/)
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*)$ /admin$1 [QSA,L]
    </Directory>
    

    Will work as it’s supposed to.

    Thanks


    Craig “FrostyCoolSlug” McLure

  3. February 19th, 2007 | 7:17 am

    Disregard my previous comment, seems that some cached stuff was causing confusion on the page..

    A more simple solution, when looking at your example, change:
    RewriteCond %{REQUEST_FILENAME} !-f

    To read:
    RewriteCond %{DOCUMENTROOT}%{REQUESTFILENAME} !-f

    Thus getting a Document Root prefix. It is still context specific, so if you use .htaccess you don’t need %{DOCUMENT_ROOT} but from what i’ve seen, it shouldn’t go in , my apologies for any confusion.

  4. ScottR
    January 9th, 2008 | 1:28 pm

    Your rule works fine, Frosty. However, if you are using Alias’ed resources and wish to do the “-f” test, you’re back in the same boat. :(

    It seems Apache doesn’t know how to check to see if a file exists when it’s being referenced via an alias.

Leave a reply

Apple Online Store
Apple Online Store