• 2010
  • Nov
  • 28

Apache - mod_rewrite in action

Last week I came across an interesting set of requirements for our new web server configuration.
If finally gave me a reason to work my way through mod_rewrite.

I identified 4 different requirements to satisfy:

1. All calls to www.sap-imagineering.com/X needed to be forwarded to the corresponding page on SCN.
e.g. http://www.sap-imagineering.com/No+Hands+SAP had to forward to http://wiki.sdn.sap.com/wiki/display/Img/No+Hands+SAP

2. Calls to user home directories created using mod_userdir had to be left alone since user directories where to be supported (In general every call containing a “~” is considered a call to a user directory)

3. A call to http://www.sap-imagineering.com(/index.html) was required to forward to a special start page on SCN.

4. Any call to a file, directory or link existing on the server was expected to take priority over the forwarding rules (1 and 3) mentioned above.

This is the site configuration I ended up with:

# Turn on rewrites.
RewriteEngine on

# Enable logging
RewriteLog "/tmp/rewrite.log"
RewriteLogLevel 10

# Only apply to URLs on this domain
RewriteCond %{HTTP_HOST} ^www.sap-imagineering.com$

# Don't apply to URLs that go to existing links, directories or folders.
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-l
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f

# Don't apply to URLs that point to user public_html directories - 
# assuming that home directories start with ~
RewriteCond %{REQUEST_FILENAME} !^/~(.*)$

# Don't apply to /index.html
RewriteCond %{REQUEST_FILENAME} !^/index.html$

# Rewrite all those to SCN
RewriteRule ^(.*)$ http://wiki.sdn.sap.com/wiki/display/Img$1

# handle calls to http://www.sap-imagineering.com(/index.html)
RewriteRule ^/index.html$ http://wiki.sdn.sap.com/wiki/display/Img/

Please not that RewriteCond only affect the first RewriteRule that follows.

Logging remarks

Switching on logging requires two separate setting:

RewriteLog "/tmp/rewrite.log"
RewriteLogLevel 10

The default LogLevel is 0 - which means that logging is effectively deactivated. I found levels >9 to be useful. It took me quite while to realize that the LogLevel setting actually acts as a useful flag in this configuration.