Forum Moderators: phranque

Message Too Old, No Replies

Redirecting dynamic URLs to static

ie. matching QUERY_STRING

         

jerz

4:09 am on Jan 6, 2005 (gmt 0)

10+ Year Member



Currently we have:
RewriteCond %{REQUEST_FILENAME}!-d
RewriteCond /home/jabber/www/content/$1.php -f
RewriteRule ^([a-z]+)/?$ /index.php?p=$1 [L]

Which works fine. However, since we've previously used links with /?p=foo I'd like to have these requests redirected (i.e. 301) to the new static URLs. Is it possible?

While we can match %{QUERY_STRING} with RewriteCond it seems that we can't use the query string value in RewriteRule.

Any ideas?

Thanks,

Jeremy

jdMorgan

5:52 am on Jan 6, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Jeremy,

Welcome to WebmasterWorld!

> it seems that we can't use the query string value in RewriteRule.

Correct, you can't test a query string in the pattern of a RewriteRule. But you can back-reference it in the substitution.

Actually, the major problem you have here is avoiding an infinite redirection loop, rewriting static to dynamic and then redirecting dynamic back to static, ad infinitum (mod_rewrite in an .htaccess context is effectively recursive). But luckily, this other question stopped you before you made that unpleasant discovery... :)

To avoid that loop, use the variable %{THE_REQUEST} to get the actual requested URL from the HTTP request header sent by the client, as opposed to using %{REQUEST_URI} or RewriteRule's local URL variable -- both of which are updated on each pass through mod_rewrite.


RewriteCond %{THE_REQUEST} index\.php\?p=([^&])+
RewriteRule ^index\.php$ http://www.yourdomain.com/%1/ [R=301,L]

So, this code will do an external 301 redirect to a static URL only if the dynamic URL was originally requested by a browser or other user-agent, and not if the URL has just been rewritten by the existing rule you posted above.

You can actually leave the "index\.php" out of the RewriteCond pattern; I just left it in to make the code's operation a bit clearer. You may also have to tweak the redirect URL a bit -- I wasn't completely sure what your static URL is supposed to look like. The method is still sound, though.

BTW, you can also make your posted code more "portable" across multiple sites (or test servers) by using the variable %{DOCUMENT_ROOT} instead of the hard-coded path /home/jabber/www... in your RewriteCond.

Jim

jerz

8:14 am on Jan 6, 2005 (gmt 0)

10+ Year Member



Thanks Jim!

That works quite well, with the exception that I modified it slightly:
RewriteCond %{THE_REQUEST} /(index\.php)?\?p=([a-z]+)
RewriteRule ^(index\.php)?$ [ourdomain.com...] [R=301,L]

I don't think we would have got an infinite loop because we were rewriting to index.php?p=request while I was going to only redirect /?p=request but even still %{THE_REQUEST} is much safer. It also means that if anyone perhaps discovered they could use index.php?p=request, they'll be redirected as well.

Thanks again,

Jeremy