Apache2 Rewritemap

Apache2 Rewritemap

I love apache mod_rewrite. I often fight with it, but if you really want it you can do whatever you want. This time I wanted to find a way to call a file named after the called subdomain. I have a website called www.yellow-sub.net, and there is some subdomains like the-beatles.yellow-sub.net, john-lennon.yellow-sub.net and so on for each part of the website (That’s a SEO consideration in the beginning). I have only one virtual host for that website because I find it easier to manage like that, and I didn’t want to put the logic in the files for some reasons (and because working with rewrite rules is fun).

This is what I want :

  • you call -> you get
  • www.yellow-sub.net -> index.php?page=somepage
  • the-beatles.yellow-sub.net -> index.php?page=somepage-the-beatles
  • blahblah.yellow-sub.net -> index.php?page=somepage-blahblah

The page parameter will in fact call a different page with name “somepage-blahblah.html”, and I wanted it to work for every single subdomain (if it doesn’t exist it will anyway be redirected to www home page)

The closest way I found was to use %{HTTP_HOST} in my rewriterule :

RewriteCond %{HTTP_HOST} !^www\.yellow-sub\.net$ [NC]
RewriteRule ^/$ /index.php?page=somepage-%{HTTP_HOST} [L]

But this way I had to name my files somepage-the-beatles.yellow-sub.net.html instead of somepage-the-beatles.html, wich is not so bad but quite annoying when I want to copy that from beta (different domain name) to live or from live to beta.

So I found the Rewritemap parameter in the apache documentation website. And That’s just an amazing new feature I didn’t know about : it will let you do whatever you want with your rewrite rules! I let you read the manual page, It’s well written and I won’t explain something already well explained : See that Rewritemap doc

I used the last MapType : External Rewriting Program that allows you to write your own script in whatever programming language you fancy, taking stdin and writing to stdout. Mine is very simple, in bash :

while read line; do
  echo $line |cut -d. -f1

I guess that’s a good practive to Keep It Simple, Stupid, as advised in the manual, cause it will be running as apache child, not called when needed. You can test it by giving it something to process :

$ echo the-beatles.yellow-sub.net |/etc/apache2/scripts/subdomain.sh
$ /etc/apache2/scripts/subdomain.sh
blabla.yellow-sub.net # this is what I wrote
blabla # this is what he said

To use it in you Virtualhost section :

Rewritemap subdomain prg:/etc/apache2/scripts/subdomain.sh
RewriteCond %{HTTP_HOST} !^www\.yellow-sub\.net$ [NC]
RewriteRule ^/$ /index.php?page=somepage-${subdomain:%{HTTP_HOST}} [L]

Don’t be messy with the interesting part ${subdomain:%{HTTP_HOST}}, I sillily wrote a % instead of the $ and spent half an hour to figure it out! (no errors anywhere, the script was launched, it just didn’t work at all).

Reload apache to watch it running now :

 xxxx ?        Ss     0:00 /usr/sbin/apache2 -k start
xxxxx ?        S      0:00  \_ /usr/sbin/apache2 -k start
xxxxx ?        S      0:00  \_ /usr/sbin/apache2 -k start
xxxxx ?        S      0:08  |   \_ /usr/bin/php5-cgi
xxxxx ?        Ss     0:00  |   \_ /usr/bin/php5-cgi
xxxxx ?        S      0:02  |   |   \_ /usr/bin/php5-cgi
xxxxx ?        S      0:00  \_ /bin/bash /etc/apache2/scripts/subdomain.sh
xxxxx ?        Sl     0:46  \_ /usr/sbin/apache2 -k start
xxxxx ?        Sl     0:48  \_ /usr/sbin/apache2 -k start

You can watch it in action using the Rewritelog :

xxx.xxx.xxx.xxx - - [17/Feb/2011:08:39:50 +0100] [the-beatles.yellow-sub.net/sid#c85408][rid#1017528/initial] (5) map lookup OK: map=subdomain key=the-beatles.yellow-sub.net -> val=the-beatles

And now my files are just called the way I wanted to 🙂
I have to say, I love this feature more because I can imagine a lot of new functions in my rewriterules than because it solved my problem, for which I had other options anyway (not as sexy ones, but solutions though.)

The question now is : it is safe? What are the risks of using such a script within apache? If you have anything to say about that, please tell me 🙂

Have fun with mod_rewrite!

One thought on “Apache2 Rewritemap

  1. You should be OK with that. It’s very simple, which is a good thing.
    If you ever used a regular expression in your rewrite program you might like to protect against regular expression injection, which you can achieve by stripping out non word characters from the input.
    Also note that URL input is not escaped before being passed to your rewrite program, or the output from that is also not escaped before going to the browser. Best to handle that within your script if necessary.

    Good luck!

Leave a Reply

Your email address will not be published. Required fields are marked *