Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I have a problem with a file test operation in a mod_rewrite RewriteCond entry which is testing whether %{REQUEST_FILENAME} exists. It seems that rather than %{REQUEST_FILENAME} being an absolute path, I'm getting a path which is rooted at the DocumentRoot instead.

Configuration

I have this inside a <VirtualHost> block in my apache 2.2.9 configuration:

RewriteEngine on
RewriteLog /tmp/rewrite.log
RewriteLogLevel 5

#push virtually everything through our dispatcher script
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/([^/]*)/?([^/]*) /dispatch.php?_c=$1&_m=$2 [qsa,L]

Diagnostics attempted

That rule is a common enough idiom for routing requests for non-existent files or directories through a script. Trouble is, it's firing even if a file does exist.

If I remove the rule, I can request normal files just fine. But with the rule in place, these requests get directed to dispatch.php

Rewrite log trace

Here's what I see in the rewrite.log

init rewrite engine with requested uri /test.txt
applying pattern '^/([^/]*)/?([^/]*)' to uri '/test.txt'
RewriteCond: input='/test.txt' pattern='!-f' => matched
RewriteCond: input='/test.txt' pattern='!-d' => matched
rewrite '/test.txt' -> '/dispatch.php?_c=test.txt&_m='
split uri=/dispatch.php?_c=test.txt&_m= -> uri=/dispatch.php, args=_c=test.txt&_m=
local path result: /dispatch.php
prefixed with document_root to /path/to/my/public_html/dispatch.php
go-ahead with /path/to/my/public_html/dispatch.php [OK]

So, it looks to me like the REQUEST_FILENAME is being presented as a path from the document root, rather than the file system root, which is presumably why the file test operator fails.

Any pointers for resolving this gratefully received...

share|improve this question

3 Answers 3

Took me a while to find out as well, but the reason is mentioned in the mod_rewrite documentation:

"REQUEST_FILENAME The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI."

That's why it works in .htaccess but not in the conf file of the vhost. (And that's also why adding the DOCUMENT_ROOT works around the problem).

share|improve this answer
up vote 0 down vote accepted

I resolved this by explicitly writing the document root into the condition

RewriteCond /path/to/my/public_html%{REQUEST_FILENAME} !-f
RewriteCond /path/to/my/public_html%{REQUEST_FILENAME} !-d
share|improve this answer
2  
This is strange considering the documentation says REQUEST_FILENAME contains "the full local filesystem path". Did you try with %{SCRIPT_FILENAME}?. Anyways... consider using %{DOCUMENT_ROOT} rather than a literal path for a more general solution. –  GetFree Oct 25 '09 at 19:25
    
I know, hence my confusion. I think it might because I've done this before via .htaccess, but this time put the rules into the vhost config - perhaps it operates differently at that level. Thanks for the DOCUMENT_ROOT tip though. –  Paul Dixon Oct 26 '09 at 8:27
    
it's an old question, but being the selected answer, can you edit it so as to use %{DOCUMENT_ROOT}? –  tokland Feb 17 '11 at 12:15
RewriteCond     %{REQUEST_URI}     ^(/pathinfo/|/pathinfo)(.*)$
RewriteRule     .*          %{DOCUMENT_ROOT}%{REQUEST_URI} [L]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.