Apache does not log HTTP status set with PHP header when using mod_rewrite in .htaccess filesApache does not log HTTP status set with PHP header when using mod_rewrite in .htaccess files

Posted April 5th, 2009 in Apache and PHP (Updated April 6th, 2009)

I discovered something rather annoying the other day relating to setting HTTP response codes with PHP's header() function, Apache's mod_rewrite and associated webserver logging. If anyone knows of a solution to the issue I have discovered below I'd love to know it.

A regular PHP script

If you use header() to make the page a 404 using PHP like so:

header("HTTP/1.0 404 Not Found");

then requesting the web page should result in a 404 which is logged in Apache as such.

In the following example a request is made using the lynx command line web browser for the log.php script and a 404 results. This is logged correctly in the Apache log file where I have highlighted the 404 response code in red.

Lynx command:

lynx -head -dump http://www.testing.local/log.php

Lynx Output

HTTP/1.0 404 Not Found
Date: Fri, 03 Apr 2009 00:09:20 GMT
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny2 with Suhosin-Patch
X-Powered-By: PHP/5.2.6-1+lenny2
Vary: Accept-Encoding
Connection: close
Content-Type: text/html

Apache Log Line:

192.168.1.15 - - [03/Apr/2009:13:09:20 +1300] "HEAD /log.php HTTP/1.0" 404 - "-" "Lynx/2.8.7dev.9 libwww-FM/2.14 SSL-MM/1.4.1"

Using mod_rewrite in the Apache config

The second example has a rewrite rule in the Apache config to rewrite /log to /log.php. Again this works as expected, logging a 404 to the Apache log file.

Rewrite rule

The following rewrite rule is what I used when writing this post. This is in the Apache config in a <virtualhost> block.

RewriteEngine On
RewriteRule ^/log$ /log.php

Lynx command

lynx -head -dump http://www.testing.local/log

Lynx Output

HTTP/1.0 404 Not Found
Date: Fri, 03 Apr 2009 00:10:44 GMT
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny2 with Suhosin-Patch
X-Powered-By: PHP/5.2.6-1+lenny2
Vary: Accept-Encoding
Connection: close
Content-Type: text/html

Apache Log Line

192.168.1.15 - - [03/Apr/2009:13:10:44 +1300] "HEAD /log HTTP/1.0" 404 - "-" "Lynx/2.8.7dev.9 libwww-FM/2.14 SSL-MM/1.4.1"

Using mod_rewrite in .htaccess

However, if the rewrite rule is done in an .htaccess file then it doesn't log the request as a 404 but instead as a regular 200. This means any stats software you run (such as AWStats) won't show the request a a file not found.

Rewrite rule:

This is the rewrite rule in the .htaccess file used for writing this post, although the error (not writing the correct error code out to the Apache log file) occured for any rewrite rule where I was remapping URLs to a PHP script:

RewriteEngine On
RewriteRule ^log$ /log.php

Another example from a production website:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !\.(css|gif|ico|jpg|js|php|png|swf|txt)$ index.php

Lynx Command:

lynx -head -dump http://www.testing.local/log

Lynx Output:

HTTP/1.0 404 Not Found
Date: Fri, 03 Apr 2009 00:08:38 GMT
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny2 with Suhosin-Patch
X-Powered-By: PHP/5.2.6-1+lenny2
Vary: Accept-Encoding
Connection: close
Content-Type: text/html

Apache Log Line:

192.168.1.15 - - [03/Apr/2009:13:08:38 +1300] "HEAD /log HTTP/1.0" 200 - "-" "Lynx/2.8.7dev.9 libwww-FM/2.14 SSL-MM/1.4.1"

Conclusion

In each instance the request is reported by the web server to the web browser as a 404, which can clearly be seen from the output from the Lynx command. However, when doing a PHP header() as a 404 (or 301, 302, 410 etc) with a rewrite rule in an .htaccess file it's not actually logged in the Apache log file as such, whereas it is when it's a regular PHP script or the rewrite rule is in the Apache config.

This is a bit of a nuisance and means if you can't put the rewrite rules into the main Apache config then you'll need to log the 404s yourself if you need to keep track of them.

If anyone knows of a way to make sure they are logged correctly when using mod rewrite and .htaccess then I'd love to know and can update this post accordingly.

Related posts:

Comments

blog comments powered by Disqus