Thursday, June 4, 2009

Apache mod_rewrite and the HTTP Host Header

I am involved with a web project that bases some application logic on the hostname of the server. During the development phase we wanted to test host-specific logic without modifying hostname resolution (through /etc/hosts or DNS) or modifying the code with specific development hostname conditionals. To accomplish this task, I crafted some handy Apache mod_rewrite rules:

<VirtualHost>
...
# requires mod_rewrite and mod_headers
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/set_site.html$
RewriteCond %{HTTP_COOKIE} ^.*choose_site=([^;]*).*$
RewriteRule ^(.*)$ $1 [E=SET_SITE:%1]
RequestHeader set Host %{SET_SITE}e
...
</VirtualHost>

The first condition matches anything but the form used to set the site cookie (choose_site). I am not entirely sure why, but if this conditional is omitted an infinite redirect happens. To keep the application code base clean I used mod_alias to alias this form to a location outside of the DOCUMENT_ROOT.

The second condition extracts the hostname from the cookie and places it in magic variable %1. The rule just passes through all requests and sets the apache environmental variable SET_SITE. This step is necessary because mod_headers can't use the mod_rewrite generated %1 variable.

Finally the last directive sets the Host header of the request, which if you're lucky, will get passed up to your scripting language for use in the logic.

No comments: