Wednesday, November 16, 2005

mod_rewrite voodoo :)

`` Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool voodoo, but still voodoo. ''

-- Brian Moore
bem@news.cmc.net

The above is one of my best quotes so far, after encountering mod_rewrite. Anyways, onto the meat.

From an anonymous comment on my post yesterday, someone wanted to do something like this using mod_rewrite:

http://www.abc.com/sub ========> http://sub.abc.com

My former solution had to do with some general redirect/MIME forcing and then some PHP trickery, which actually works. But there's even a more mod_rewrite (ty) based solution... the secret is in the use of the RewriteCond expression which I didn't know of when I replied that post initially.

The problem initially was that with RewriteRule, you can only access the part of the url that comes after the host name. For instance, in http://foo.com/bar, you only have access to /bar in RewriteRule. To do this, we actually need access to the foo.com part as well. This is where RewriteCond comes in handdy.

With RewriteCond, you can basically execute a RewriteRule as long as the condition is satisfied. There are special condition variables that you have access to like HTTP_HOST (which we'll be using here), and a bunch of other apache server/environment variables.

Ok... the rule look like this:


RewriteEngine on #this turns on the RewriteEngine... duh!!! :)
RewriteLog /path/to/logfile # i like to turn this on, to see what actually happens
RewriteLogLevel 1 #when testing out a new rule, i set this to 5 so i can see what's happening step by step

RewriteCond %{HTTP_HOST} ^www\.([a-z0-9]+)\.com$ #this will match, www.bleh.com, www.anything.com, www.wassup.com, well...you get the idea. Note that I applied the () grouping so i can access the matched variable later as %1

RewriteRule ^/([a-z0-9]+)$ http://$1.%1.com/ [R,L] #now i pick up the /sub part of the url, and use that to generate the redirect url. The i apply the two flags [R, L]. R means force a redirect. L just makes this the final rule that this match will traverse.

Lets lay it out again without all the nasty/helpfull comments.

RewriteEngine on
RewriteLog /path/to/logfile
RewriteLogLevel 1

RewriteCond %{HTTP_HOST} ^www\.([a-z0-9]+)\.com$
RewriteRule ^/([a-z0-9]+)$ http://$1.%1.com/ [R,L]


Yup... try this out, and see the deep vodoo. On my test apache host, if i do:

http://www.mrouter.com/sub

I end up getting http://sub.mrouter.com

kewl o yeah... voodoo? DEFINITELY!!!

Essien out.

2 Comments:

At Wednesday, November 16, 2005 5:43:00 PM, Anonymous Anonymous said...

Thanks...Essien I will take time to try out your voodoo this weekend!!!

Is your http://www.mrouter.com/sub up and runing.

Can I test it on that site by typing

http://sub.mrouter.com

Cheers man!!!

 
At Thursday, November 17, 2005 10:40:00 AM, Blogger Essien Ita Essien said...

Naaaa, I did all this on my intranet. If you follow my rules though, you'll be able to acheive the same thing.

And its the other way around, http://www.mrouter.com/sub pointing to http://sub.mrouter.com.

Getting it to work the other way around is still easy too.

RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.([a-z0-9]+)\.([a-z0-9]+)$
RewriteCond %1 !www
RewriteRule ^/(.*)$ http://www.%2.%3/%1/$1 [R,L]

This will make all request to http://foo.bar.com/apage.bleh redirect to http://www.bar.com/foo/apage.bleh

Damn!!! I'm really enjoying this stuff...

And finally... lest you forget...

ALL YOUR BASE ARE BELONGS TO ME!!!!

@(^_-)@

 

Post a Comment

<< Home