Saturday, December 19, 2015

mod rewrite - How to simulate Apache [END] flag on a redirect?



For business-specific reasons I created the following RewriteRule for Apache 2.2.22 (mod_rewrite):



RewriteRule /site/(\d+)/([^/]+)\.html /site/$2/$1 [R=301,L]



Which if given a URL like:



http://www.example.com/site/0999/document.html


Is translated to:



http://www.example.com/site/document/0999.html



That's the expected scenario. However, there are documents which name are only numbers. So consider the following case:



http://www.example.com/site/0055/0666.html


Gets translated to:



http://www.example.com/site/0666/0055.html



Which also matches my RewriteRule pattern, so I end up with "The web page resulted in too many redirects" errors from browsers.



I have researched for a long time, and haven't found "good" solutions. Things I tried:




  1. Use the [END] flag. Unfortunately is not available on my Apache version nor it works with redirects.


  2. Use %{ENV:REDIRECT_STATUS} on a RewriteCond clause to end the rewrite process (L). For some reason %{ENV:REDIRECT_STATUS} is empty all the times I tried.


  3. Add a response header with the Header clause if my rule matches and then check for that header (see: here for details). Seems that a) REDIRECT_addHeader is empty b) headers are can't be set on the 301 response explicitly.





There is another alternative. I could set a query parameter to the redirect URL which indicates it comes from a redirect, but I don't like that solution as it seems too hacky.



Is there a way to do exactly what the [END] flag does but in older Apache versions? Such as mine 2.2.22.


Answer



Add a query parameter to the redirect is the best option. It is done quite often for all kinds of reasons.



For example make the rule like this:



RewriteCond %{QUERY_STRING}  !redirected

RewriteRule /site/(\d+)/([^/]+)\.html /site/$2/$1?redirected [R=301,L]


What now happens is that the redirects are to URLs with "?redirected" added to them. And so the rule isn't applied the second time.


No comments:

Post a Comment

linux - How to SSH to ec2 instance in VPC private subnet via NAT server

I have created a VPC in aws with a public subnet and a private subnet. The private subnet does not have direct access to external network. S...