On high-traffic, multi-editor Drupal sites, there can be missing files related to page design. An image gets renamed. A bot spams the site looking for a specific .cgi exploit. And so on.

By design, Drupal is defined as the 404 handler for all instances in the .htaccess file. That code is:

# Customized error messages.
ErrorDocument 404 /index.php

Drupal (and other php-based CMS systems) do this so that index.php handles all URI requests and can generate the right page.

The problem is that using Drupal as the 404 handler invokes a full bootstrap load for any missing file.

Adding the following code to .htaccess eliminates some of this, by telling Apache to handle certain types of 404 errors:

# This overrides the Drupal 404 handler for files that should never be handled by Drupal
<FilesMatch "\.(gif|jpe?g|png|s?html|css|js|cgi)$">
  ErrorDocument 404 default
</FilesMatch>

We also need to put a new line:

RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|s?html|css|js|cgi)$

Just before the line:

RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

This elminates the following file types from invoking Drupal if a 404 is encountered:

- gif
- jpeg
- shtml and html
- css
- js
- cgi

Doing so avoiding invoking Drupal's bootstrap in order to look for missing files. This procedure minimizes database load and helps boost site performance.

-- WARNING --

There is a known issue that occurs if you block .png files with this method. It affects the system_test() function in system.module, which relies on a phantom .png call to the directory '/system/test/'.

If you block Drupal's 404 handling for .png files and do not allow this exception, you lose the ability to configure the site for clean_urls.

Comments

jrabeemer’s picture

This line....

RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|s?html|css|js|cgi|ico|swf|flv)$

It breaks the CCK imagefield module from uploading correctly. If you add this, it'll only accept files with an uppercase extension. If you use this module, don't mod your .htaccess with the line!

Pilot’s picture

Why not also include "php" along with the other files? My server logs note more empty calls for .php files than any other (notably of the "proxy" variety). From what I can tell, the system works fine with php added to the list. If a .php files DOES exist, it is anyway flagged by the first rewrite conditional and anyway wont call up an error 404. Right?

So adjust as follows:

 <FilesMatch "\.(gif|jpe?g|png|s?html?|css|js|cgi|php)$">
 RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|s?html?|css|js|cgi|php)$

Note: also added "?" after "html" to include .htm files

joetsuihk’s picture

maybe you want to exclude index.php, if clean url is turned off.

joetsuihk’s picture

I have test this settings in D6, work, too

ultrabutter’s picture

Description is missing .jpg

This elminates the following file types from invoking Drupal if a 404 is encountered:

- gif
- jpeg and jpg
- shtml and html
- css
- js
- cgi

gausarts’s picture

love, light n laughter