What's the difference between REQUEST_FILENAME and REQUEST_URI in apache configuration?

Rick asked:

I don’t see any posts discuss the differences between REQUEST_URI and REQUEST_FILENAME, while I see many posts use them interchangeably.

I turned on the mod_rewrite log (LogLevel alert rewrite:trace8), replaced REQUEST_FILENAME with REQUEST_FILENAME, looked up the rewrite log in each configuration, and the rewriting process are exactly the same.

So my question is:

Are they the same under 99% circumstances?

I didn’t say 100% because I see from doc(https://httpd.apache.org/docs/current/mod/mod_rewrite.html) mentioning an exception for REQUEST_URI related to something called AcceptPathInfo.


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.
Depending on the value of AcceptPathInfo, the server may have only
used some leading components of the REQUEST_URI to map the request to
a file.

Actually I find it difficult to understand the whole definition, not only the last sentence.

I use REQUEST_FILENAME and REQUEST_URI mainly between <VirtualHost *:443>.

My <VirtualHost *:443> settings:

<VirtualHost *:443>
        ServerAdmin [email protected]
        DocumentRoot /var/www/example.com/public_html
        ServerName example.com
        ServerAlias www.example.com

        LogLevel alert rewrite:trace8
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

RewriteEngine On
#RewriteCond %{REQUEST_URI} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule (.*) /tq_info.php?p=%{REQUSET_URI}

RewriteCond %{REQUEST_FILENAME} !/.*\.php$
RewriteCond %{REQUEST_FILENAME} !/admin/.*
RewriteRule (.*) /index.php/$1 [L]
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

My answer:

These are very different and serve different purposes.

REQUEST_URI is the path component of the URI in the request. For example, /tq_info.php.

REQUEST_FILENAME is the result of trying to find the file in the local filesystem by applying the URI path to the document root or any alias that might have been defined. Thus, if the file exists, this will be set to /var/www/example.com/public_html/tq_info.php. It is used to locate a file in the filesystem. It is only set to match REQUEST_URI if there is no file in the filesystem. In that case the request will be passed to the 404 handler, or to an upstream web application if you have defined one in your web server configuration that matches the URI path.

When you are choosing which one to use, you need to think about whether you are trying to work with the URI path component, or the path of the corresponding file in your filesystem.

View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.