Module mod_rewrite

( Written by Ralf S. Engelschall for The Apache Group )

This module is contained in the mod_rewrite.c file, and is not compiled in by default. It provides for enhanced on-the-fly URI rewriting of requests within the Apache server. You can use the full power of Regular Expressions to rewrite incoming URIs just before the Apache server runs his handler modules to process the request.


Summary

The Apache server has a hook for URI translation which is used by this module to link into the Apache server. For every HTTP request, this module is called with the requested URI. It then applies all Rewriting Patterns and if one fits, translates the URI according to its Rewriting Subsitution part.

Practical Usage

I use this module to

New Features

The rewrite module adds some new features that were not possible with the standard aliasing and rewriting mechanism.


Configuration Directives


RewriteLog

Syntax: RewriteLog Filename
Default: RewriteLog "logs/rewrite_logs"
Context: server config, virtual host
Module: mod_rewrite.c

The RewriteLog directive set the name of the file to which the server log any rewriting actions it performs. If the name does not begin with a slash (/) then it is assumed to be relative to the ServerRoot. The statement should occur only once in the Server Config.

Example:

RewriteLog "/usr/local/var/apache/logs/rewrite.log"
To disable the logging of rewriting actions simply set this Filename to /dev/null. This effectifly disables all rewrite action logs.


RewriteMap

Syntax: RewriteMap Mapname {txt, dbm}:Filename
Default: not used per default
Context: server config, virtual host
Module: mod_rewrite.c

The RewriteMap directive defines a external Rewriting Map file which can be used on the RHS of a Rewriting Rule to substitute fields through a key lookup.

The Filename have to be a valid Unix filepath, containing either a plain Text file with

MatchingKey SubstValue
pairs or a DBM file with the same contents. In the plain text version blank lines and up-to-eol-comments (indicated by # characters) are ignoried. The Mapname is the name of the map. It can be used on the RHS of a Rewriting Rule via
${ Mapname : LookupKey | DefaultValue }
When such a directive occurs on the RHS the Rewrite Map Mapname is consulted and the key LookupKey is looked up. If the key is found, the whole directive is substituted by SubstValue. If the key is not found then it is substituted by DefaultValue. This statement can occur more than once. For each Rewriting Map use one RewriteMap directive to declare it.

Example:

#
#   map.real-to-user -- maps realnames to usernames
#

Ralf.S.Engelschall    rse   # Bastard Operator From Hell 
Dr.Fred.Klabuster     fred  # Mr. DAU


RewriteRule

Syntax: RewriteRule Pattern Output
Default: not used per default
Context: server config, virtual host
Module: mod_rewrite.c

The RewriteRule directive is the real Rewriting workhorse. The directive can occur more than once. Each directive then defines one single Rewriting Rule. The definition order of these Rewriting Rules is important, because this order is used when applying the rules to the URIs under run-time.

Pattern can be a full System V8 Regular Expression. Some hints:

Output is the string which is substituted instead of the original URL for which Pattern matched. The following Rewriting Rules (when the rewriting process is not explicitly terminated by a L flag - see below) are applied to this Output, i.e. the URL is replaced by Output and the rewriting process goes on. You can set special flags for Output by appending

[flags]
to the end of the string (without whitespaces!). Flags is a comma-seperated list of of the following flags:

Example:

We want to rewrite URLs of the form

/ Language /~ Realname /.../ File
into
/u/ Username /.../ File . Language

We take the Rewrite Map file from above and save it under /anywhere/map.real-to-user. Then we only have to add the following lines to our Apache server configuration file:

RewriteLog   /anywhere/rewrite.log
RewriteMap   real-to-user               txt:/anywhere/map.real-to-host
RewriteRule  ^/([^/]+)/~([^/]+)/(.*)$   /u/${real-to-user:\\2|nobody}/\\3\\.\\1


Example: partial httpd.conf

Below you can see the essential parts of the common httpd.conf file as used on all servers at sd&m GmbH & Co. KG in Munich/Germany. It makes heavy use of the URL Rewriting feature this module provides:
   :
   :
   :

RewriteLog           /usr/local/var/apache/log/rewrite.log

   :
   :
   :

#   the way real user directories are determined and found
#   http://<this>/~<realuser>/<dir>/<file> -> $HOME/<realuser>/<UserDir>/
UserDir          .www

   :
   :
   :

#
#   ALIASES, REWRITES and REDIRECTIONS
#   [the ``RewriteXXX'' commands needs mod_rewrite to be compiled into server]
#

#   canonicalize the rootdir 
RewriteRule   ^/$                 /e/sww[R,L]
#   canonicalize the Unix shorthand for user dirs
#   (we don't do a 'L'ast command here because below all
#   /[uge] dirs will be redirected, too)
RewriteRule   ^/~([^/]+)/?(.*)    /u/\\1/\\2[R]
#   always append / to homedirs if the user forgot
#   (if this matches it is the 'L'ast rule and it does a 'R'edirect)
RewriteRule   ^/([uge])/([^/]+)$  /\\1/\\2/[R,L]

#   local shortcuts
RewriteRule  ^/se$             /se/[R]
RewriteRule  ^/se/?$           /se/se.scgi
RewriteRule  ^/se/se.cgi(.*)   /se/se.scgi\\1[R]
RewriteRule  ^/se/(.+)         http://sww.sdm.de/e/sww/se/html/\\1
RewriteRule  ^/mf$             /mf/[R]
RewriteRule  ^/mf/?$           /mf/mf.cgi
RewriteRule  ^/mf/(.+)         http://sww.sdm.de/e/sww/mf/\\1
RewriteRule  ^/ve/?$           /ve/ve.scgi
RewriteRule  ^/ve/ve.cgi(.*)   /ve/ve.scgi\\1[R]
RewriteRule  ^/ve/(.+)         http://sww.sdm.de/e/sww/ve/html/\\1


#   Feature: HOMOGENE URI TREE
#
#   redirect user (/u/<user>), group (/g/<group>) and entity 
#   (/e/<entity>) homedirs to the _REAL_ home-host, i.e. the host 
#   which actually can serve the request because the data is physically 
#   available to him!
#
#   Notice:
#       o   absolute URIs which were expanded to _OUR_ host
#           are automatically reduced to a local URI by mod_rewrite!!
#
#   the map files:
RewriteMap    user-to-host     txt:/usr/local/lib/apache/conf/maps/map.user-to-host
RewriteMap    group-to-host    txt:/usr/local/lib/apache/conf/maps/map.group-to-host
RewriteMap    entity-to-host   txt:/usr/local/lib/apache/conf/maps/map.entity-to-host
#   and the rules:
RewriteRule   ^/u/([^/]+)/?(.*)  http://${user-to-host:\\1|sww.sdm.de}/u/\\1/\\2
RewriteRule   ^/g/([^/]+)/?(.*)  http://${group-to-host:\\1|sww.sdm.de}/g/\\1/\\2
RewriteRule   ^/e/([^/]+)/?(.*)  http://${entity-to-host:\\1|sww.sdm.de}/e/\\1/\\2

#   Feature: VIRTUAL HOMEDIR
#
#   we do a explicit expansion of the effective homedirs by
#   manually inserting the "UserDir" (see above) into the path!
#   this gives us the feature of "virtual homedirs", i.e. homedirs
#   which actually don't have a corresponding user (UID, Homedir).
#
RewriteRule   ^/([uge])/([^/]+)/?$          /\\1/\\2/.www/
RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /\\1/\\2/.www/\\3

#   Feature: SECURE CGI
#
#   we provide a secure and more powerful alternative way for
#   CGI programs: .scgi (Secure CGI). These are called through
#   the "cgiwrap" utility which does a lot of security checks on
#   the actual file, authenticates the user (allow|deny) and
#   finally runs the CGI program under the UID/GID of the _OWNER_
#   of the script!
#
#   Notice! 
#       o   every user, group or entity needs a own unique UID and 
#           Homedir to be able to use this feature. "virtual homedirs"
#           will not work, i.e. they must by physical one (/etc/passwd)!
#
RewriteRule   ^/[uge]/([^/]+)/\\.www/(.+)\\.scgi$   /~\\1/\\2.scgi

#   FEATURE: SWW Index and Logging
#
RewriteRule   ^/([uge])/([^/]+)(/?.*)/\\*    /internal/cgi/user/swwidx?i=/\\1/\\2\\3/
RewriteRule   ^/([uge])/([^/]+)(/?.*)/swwidx /internal/cgi/user/swwidx?i=/\\1/\\2\\3/
RewriteRule   ^/([uge])/([^/]+)(/?.*):swwlog /internal/cgi/user/swwlog?f=/\\1/\\2\\3

   :
   :
   :

#   let files with extension .scgi threated as Secure CGI scripts
#   i.e. scripts which are executed via the "cgiwrap" utility!
#   see the corresponding rewrite rule above!
AddType application/x-httpd-scgi   scgi
Action  application/x-httpd-scgi   /internal/cgi/user/cgiwrap

   :
   :
   :