Forum Moderators: phranque

Message Too Old, No Replies

Mod-rewriting my mod-rewrite

Er.... too innefficient or will it do the trick?

         

trillianjedi

9:42 am on May 3, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'm sorry that I always seem to come into this forum to ask questions - but I guess I'm at least learning something about Apache - I've been knee deep in it a couple of weeks now!

We've just made a few adjustments to the mod_rewrite on our forum. I now want to serve a 301 and new URL to any bot or anything requesting an old format URL.

Rewrite rule looks something like this:-

RewriteRule ^widgets_index.html index.php?name=phpBB2&file=index
RewriteRule ^widgets_index_([0-9]*).html index.php?name=phpBB2&file=index&c=$1
RewriteRule ^widgets_view_([0-9]*).html index.php?name=phpBB2&file=viewforum&f=$1
RewriteRule ^widgets_topic_([0-9]*).html index.php?name=phpBB2&file=viewtopic&t=$1

So, I guess what I need is something that serves a 301 and re-written URL to anyone coming in on the unwritten URL, eg, a request for:-

example.com/index.php?name=phpBB2&file=viewforum&forum=20

...gets a 301 "page has moved to":-

example.com/widgets_view_20.html

Can I do that within the mod-rewrite code, or does this need a seperate rule of some kind?

Many thanks,

TJ

jdMorgan

2:48 pm on May 3, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This isn't as simple as it sounds, since a bit of reflection will reveal that adding a "regular" rewrite rule to reverse the static-to-dynamic rewrite would result in a loop. You'd rewrite static URL "A" to dynamic URL "B", but then also rewrite URL "B" back to "A", resulting in an "infinite" rewrite loop.

The solution is to use the server variable {THE_REQUEST}, which tests only the original URL requested by the client. It is not affected by any previous internal rewrites for this HTTP request. As an example, to 301 the directly-requested dynamic URLs rewritten by this rule:


RewriteRule ^widgets_view_([0-9]*[b])\.h[/b]tml$ index.php?name=phpBB2&file=viewforum&f=$1 [b][L][/b]

You could use:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\?name=phpBB2&file=viewforum&f=([0-9])*\ HTTP/
RewriteRule ^index\.php$ /widgets_view_%1.html [R=301,L]

This examines the original request header from the client (browser) and 301-redirects a directly-requested dynamic URL to the static URL equivalent.

An example of the form of the original request header from the browser is:

GET index.php?name=phpBB2&file=viewforum&f=1234 HTTP/1.1

The regular expression I gave above should accept any known HTTP method, i.e. GET, POST, PROPFIND in THE_REQUEST.

Also note that I added an [L] flag to your original rule, and escaped the literal period in the requested URL. Always use the [L] flag unless you need the output of a given rule to be processed through other rules that follow it. Otherwise, you may waste quite a bit of CPU time, and slow down your server unnecessarily.

Jim

trillianjedi

2:01 pm on May 4, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Jim,

Thank you very much for the pointers on what to do, and for cleaning up the existing mod-rewrite code!

TJ