Forum Moderators: phranque

Message Too Old, No Replies

301 Redirect Rule gives different results on different hosting env.

301 Redirect Rule querystring htaccess

         

MonkeeX

11:16 am on Jul 17, 2012 (gmt 0)

10+ Year Member



Hi All,

I have been doing some URL rewriting for a customer in a test environment that work fine in my environment but when I move to theirs I get different results and the rule fails.

I am 301 redirecting legacy dynamic URLs in the following format:

http://www.companyname.com/page.php?pagename=AboutCompany&lang=EN
to
http://www.companyname.com/EN/about-company/

Using the ruleset below this works fine on my 'Heart Internet' shared hosting but fails on their 'Go Daddy' shared hosting (configs below). On the Go Daddy environment the legacy URL gets redirected to:

http://www.companyname.com/GET/about-company/
instead of
http://www.companyname.com/EN/about-company/

where does the 'GET' come? This is a barebones page with no other code influencing these rules.


RewriteCond %{QUERY_STRING} pagename=AboutCompany
RewriteCond %{QUERY_STRING} lang=([^&]+)
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /page.php
RewriteRule ^page.php$ /%1/about-company/? [R=301,L]

RewriteRule ^([A-Za-z]+)/about-company$ page.php?pagename=AboutCompany&lang=$1 [NC,L]
RewriteRule ^([A-Za-z]+)/about-company/$ page.php?pagename=AboutCompany&lang=$1 [NC,L]


The 'lang' querystring differs depending on the user language preference (EN or FR or DE etc...)

Test Enviroment:
Windows
IIS7.5
PHP 5.3.6

Customer Enviroment:
Linux
Apache
PHP 5.2

Thanks, M.

g1smd

7:22 pm on Jul 17, 2012 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Escape literal periods in all RegEx patterns.

The redirect target should include the protocol and hostname.

The 'GET' is loaded in %1 in the previous RewriteCond.
You'll need to change the RewiteCond order so that the lang condition is last.

MonkeeX

7:27 pm on Jul 17, 2012 (gmt 0)

10+ Year Member



Thanks G1. Not quite sure what you mean by the first two comments but you are correct in your assessment of the problem. I managed to fix this now my changing the order of the conditions.

M

g1smd

7:32 pm on Jul 17, 2012 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The other two are just as vital; you just haven't found the problem those coding errors are causing.

Literal periods in patterns should be escaped by writing \. instead of . for each one.

The rule target of the redirect should also include protocol and hostname, not just the path.

MonkeeX

7:37 pm on Jul 17, 2012 (gmt 0)

10+ Year Member



oh, i see. so i should have:

http:\\www.companyname.com\page\.php?pagename=AboutCompany&lang=$1

Is that correct? Newbie. :-)

g1smd

7:43 pm on Jul 17, 2012 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Swap \ for / here.

The literal periods should not be escaped in the rule target, only in the RegEx patterns.

MonkeeX

7:48 pm on Jul 17, 2012 (gmt 0)

10+ Year Member



ooooops. Sorry yes.

[companyname.com...]

Please can you give an example of what you mean by: "The literal periods should not be escaped in the rule target, only in the RegEx patterns. "

Do you mean I should escape it here?

RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /page\.php

Thanks,
Mark

lucy24

12:01 am on Jul 18, 2012 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



where does the 'GET' come

I love questions that can be answered with "It's doing it that way because you told it to" :)

Everything in parentheses is captured. That includes constructions like (GET|HEAD) where the parentheses are only there to deal with the pipes. You have two options:

Change the %1, %2 etc in your target so the (GET) or (HEAD) element doesn't butt in where it isn't wanted,

or (I think this is a better way all around)
make the parentheses non-capturing, like this:
(?:GET|HEAD)

Non-capturing parentheses may also shave a nano-squiggle off of the server load, because it doesn't have to hold the item in its memory for the next two lines.