Forum Moderators: phranque

Message Too Old, No Replies

RewriteCond: Problem with End Of Line Anchor ($)

         

localghost

7:26 am on Nov 11, 2005 (gmt 0)

10+ Year Member



Hello there,

I have a regex condition which rewrites the URL from an old scriptiong to new one. Here is it:

RewriteEngine on
RewriteCond %{THE_REQUEST} \?showtopic=(100¦99¦96)
RewriteRule index\.php /articles.php?oldid=%1 [R=301,L]

In fact the old database is a forum board which contains some threads which I do not want rewritten. That is why I isolated the ids of the threads that I want to be rewritten with this RewriteCond:

RewriteCond %{THE_REQUEST} \?showtopic=(100¦99¦96)

The problem that I have now is that in the board there is a new topic with id=960 which matches the regular expression in the RewriteCond.

What I tried to do is put and EOL (end of line) anchor - $

RewriteCond %{THE_REQUEST} \?showtopic=(100¦99¦96)$

For my greatest surprise this now does not match any of the ids in the regular expression. The topic with id=96 is not rewritten, nor is id 100 or 99.

I suspect that for some reason the $ might be interpreted as back reference, but I am not sure at all.

Have you ever had such problem? Or is my regex wrong?

Please, help me solve this.

Thank you

jd01

8:57 am on Nov 11, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The problem is THE_REQUEST compares the entire request EG
GET http://www.yoursite.com/yourfile.php?yourvariable=somestuff HTTP/1.X

So, to solve the problem, you can check for a space followed by HTTP after the last number you would like to match:

RewriteEngine on
RewriteCond %{THE_REQUEST} \?showtopic=(100¦99¦96)\ HTTP/
RewriteRule index\.php /articles.php?oldid=%1 [R=301,L]

I am not sure what your site structure is, but you might gain some efficiency by start/end anchoring your rule EG ^index\.php$ -- If not all page/file requests will be checked for a match anywhere in the request string, where if anchored, they would break after the first letter if the location requested did not start with an i...

Hope this helps.

Justin

jdMorgan

9:11 am on Nov 11, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



localghost,

Welcome to WebmasterWorld!

The problem is that THE_REQUEST for a forum 96 GET request looks like this:


GET /index.php?showtopic=96 HTTP/1.1

THE_REQUEST is the exact request header sent by the browser, including method (GET), URL-path (index.php?showtopic=96), and protocol (HTTP/1.1).

The easiest solution would be to look for the space after showtopic=96. If you might have another parameter after the topic number, then look for an ampersand as well.

This looks for showtopic=96, followed by zero or more groups composed of an ampersand followed by any number of characters not equal to a space, and then followed by a space and "HTTP/":


RewriteCond %{THE_REQUEST} /index\.php\?showtopic=(100¦99¦96)(&[^\ ]+)*\ HTTP/

If you never have another parameter after showtopic=96, then a simplified version will do:

RewriteCond %{THE_REQUEST} /index\.php\?showtopic=(100¦99¦96)\ HTTP/

In either case, your existing RewriteRule is fine. It is safer to include the seemingly-redundant URL-path in both the RewriteCond and the RewriteRule for this type of rewrite. The URL-path in the RewriteRule can match as a result of another rewrite, while the one in RewriteCond will only match if it was actually requested by the client.

Jim

localghost

9:30 am on Nov 11, 2005 (gmt 0)

10+ Year Member



Thanks Justin

I did not realize the %{THE_REQUEST} contains all the HTTP specific words.

And thanks Jim the (&[^\ ]+)*\ HTTP/ helped for some specific cases.

Thank you guys. It was really helpful.