mod_rewrite is a module for Apache which allows you to rewrite and manipulate URLs which are sent to your webserver. It has many uses from the simple to the complex. Here we'll introduce the basics of enabling and using the module.

The mod_rewrite module allows you to do almost anything to incoming requests to your Apache or Apache2 server.

The module, once loaded, is configured by a list of rules. These rules allow you to manipulate URLs, and incoming requests.

Enabling mod_rewrite for Apache

Enabling the module for Apache should be a simple matter of adding the following line to your Apache's configuration file /etc/apache/httpd.conf:

LoadModule rewrite_module /usr/lib/apache/1.3/mod_rewrite.so

Once that has been done your server can be restarted to allow these new configuration directives to take effect:

root@lappy:~# /etc/init.d/apache restart
Enabling mod_rewrite for Apache2

To enable the module to be loaded you need to run the following command:

root@lappy:~# a2enmod rewrite
Module rewrite installed; run /etc/init.d/apache2 force-reload to enable.

As the output of the command suggests you need to reload your server to cause the loading to take effect:

root@lappy:~# /etc/init.d/apache2 force-reload
Forcing reload of web server: Apache2.

If all goes well your module is now loaded. Now you just need to add the rewriting rules to your server.

Simple Examples

Once the module has been loaded by your server you can start to use it to alter the way your server handles requests.

To fully understand the way the rules work we'll need a simple example, so we'll use this very website as one!

Right now you'll be reading this article at the following URL:

That's not a terribly friendly URL though, and some web spiders might not actually bother to index it - because they don't like URLs which have "?" characters in them.

To fix this we can add the following to our server configuration file:

RewriteEngine on
RewriteRule ^/articles/([0-9]+)$                /?article=$1    [PT]

This snippet, (inside a virtual host directive so that it's not global), does three things:

  • The first line turns on the rewriting engine, allowing the following line to take effect.
  • The second line has a rewriting rule which we'll cover shortly, as well as the flags 'PT' which we'll also explain.

When it comes to rules there are two things that you should be familiar with - regular expressions, and flags.

Regular expressions are patterns which can be used to match against text, they allow you to specify ranges of characters or specific ones.

In our case the rule we've shown above is:

^/articles/([0-9]+)$

This rule will match any incoming request which starts with "/articles/", and then ends with any number of numerical digits. Because the rule makes use of the "(" and ")" characters to setup a match the number which was at the end of the request will be captured as the first match.

The second half of the rule is what the incoming request will be transformed into, in our case:

?article=$1

(Where the $1 is the numerical digits which were captured from the incoming request).

Finally the flags used at the end of the rule "PT" means to "pass through" the request to the next Apache handler. It's required in our case to make sure that the CGI scripts this site run receive the modifed URI.

With this rule in place the following link should also take you to this article:

Similar rewriting can be applied to fixup other "ugly" URLs, and make them more memorable and bookmarkable:

The preceeding examples are all made possible by the following snippet:

RewriteEngine on
RewriteRule ^/users/([A-Za-z0-9]+)/scratchpad$  /?scratchpad=$1 [PT]
RewriteRule ^/users/([A-Za-z0-9]+)$             /?user=$1       [PT]
RewriteRule ^/articles/([0-9]+)$                /?article=$1    [PT]
RewriteRule ^/polls/([0-9]+)$                   /?poll=$1       [PT]
RewriteRule ^/search/(.*)$                      /?search=$1     [PT]
RewriteRule ^/submit/*$                         /?submit=new    [PT]

mod_rewrite will stop processing at the first line which matches - this is something that you should bear in mind if you wish to make multiple transformations in series.

To avoid the processing of rules stopping at the first match you can use the "[OR]" flag, which will allow the rule to match against the current rule or the next one.

Multiple flags can be combined, seperated by "," characters such as this one:

RewriteRule /foo        /new-location [NC,OR]
RewriteRule /bar        /new-location [NC]

These two rules rewrite the URLs paths /foo or /bar to a new location - ignoring case.

Common Tasks with mod_rewrite

One very common example of using mod_rewrite is to prevent other websites "hotlinking" to images upon your server.

Assuming you run the website "example.com", and you wish to prevent other websites from using your images, and your bandwidth you can stop this with the following snippet:

Rewriteengine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://example.com/.*$ [NC]
RewriteRule .*.(gif|GIF|jpg|JPG)$ - [F]

What this does is to match against the HTTP header which client browsers send to make their requests. First looking for an empty Referer field, and then looking for one which mentions your website - which is assumed to be legitimate. (The "NC" flag means "no case distinction").

If these two rules don't match then the last one which looks for images will be processed - the "F" flag means "send back a forbidden response".

The net effect should be that clients which send no referer header, or those which have a referer of your own website will be allowed to see the images - but hotlinked images from other sites will receive a forbidden error.

(Note that this isn't 100% effective as many people block the HTTP Referer header when surfing, for privacy reasons).

Another common task might be changing extensions on files, moving from .htm files to .html files.

This can be achived with the following rule:

RewriteRule (.*).htm$  $1.html  [PT]

Whilst this is just a simple introduction mod_rewrite is incredibly sophisticated and powerful. To get the best out of it you will almost certainly need to read the mod_rewrite documentation.