Forum Moderators: phranque

Message Too Old, No Replies

implicitly forcing redirect / add path info postfix

even if there's no [R] the logfile show "implicitly forcing redirect"

         

BlueBlizz

8:58 pm on Sep 23, 2009 (gmt 0)

10+ Year Member



I've have the following situation:

[domain.com...]
should be rewriten according a rewritemap:txt

if 'test.map' contains:
aaa vvv
the new url should be
[domain.com...]

if 'test.map' contains:
aaa vvv
ccc yyy
the new url should be
[domain.com...]

otherwise the original url must be past forwards

my input is: [domain.com...]
my code is:
RewriteMap testmap txt:/home/epages5/eproot/Shared/test.map

test.map:
aaa vvv
bbb yyy
ccc zzz

RewriteRule ^([a-z0-9-]*)/([a-z0-9-]*)/([a-z0-9-]*) [domain.com...] [NC,L]
RewriteRule ^([a-z0-9-]*)/([a-z0-9-]*)/ [domain.com...] [NC,L]
RewriteRule ^([a-z0-9-]*)/ [domain.com...] [NC,L]

it is not working !

The log-files shows:
map lookup OK: map=testmap[txt] key=aaa -> val=vvv
map lookup OK: map=testmap[txt] key=bbb -> val=yyy
map lookup OK: map=testmap[txt] key=ccc -> val=zzz
rewrite 'aaa/bbb/ccc/' -> 'http://www.domain.com/vvv/yyy/zzz/'
implicitly forcing redirect (rc=302) with 'http://www.domain.com/vvv/yyy/zzz/
escaping [domain.com...] for redirect
redirect to [domain.com...] [REDIRECT/302]

....
map lookup FAILED: map=testmap[txt] key=vvv
map lookup FAILED: map=testmap[txt] key=yyy
map lookup FAILED: map=testmap[txt] key=zzz
implicitly forcing redirect (rc=302) with 'http://www.domain.com/vvv/yyy/zzz/
escaping [domain.com...] for redirect
redirect to [domain.com...] [REDIRECT/302]
...
etc.

Why is there a forced redirect?

And how to fix this loop / problem?

g1smd

9:56 pm on Sep 23, 2009 (gmt 0)

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



Did you mean for the patterns to match "zero or more times", meaning that a request for
example.com////
would satisfy your first rule?

Surely you need "one or more times" there?

If your rule target is another URL (because you included a protocol and/or domain name), then a 302 redirect is generated. If you omit the protocol and domain name, then the target will become an internal filepath - and that operation is commonly known as a rewrite.

Caterham

10:05 pm on Sep 23, 2009 (gmt 0)

10+ Year Member



And how to fix this loop / problem?

Since it looks like you do have access to the main server configuration (in order to define a map), place the rewrite there, too, unless you'd like to overcomplicate things.

RewriteRule ^/([a-z0-9-]+)/([a-z0-9-]+)/([a-z0-9-]+) /${testmap:$1¦$1}/${testmap:$2¦$2}/${testmap:$3¦$3}/ [NC,PT]

etc.

jdMorgan

10:07 pm on Sep 23, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There is a forced 302 redirect because you specified "http://www.example.com/" in the rewriterule substitution. This is documented in the Apache mod_rewrite documentation.

With the patterns in your rule, you've told the rule to translate all possible values of the url-path-parts, so since there is a redirect (which ends the current HTTP transaction and asks the client to start a new one) this rule will loop 'forever' until either the server or the client gives up.

Remove the "http://www.example.com" from the substitution address, and then add a RewriteCond to prevent any internal-rewrite looping. You can do this by making sure that the output path won't match the rule's pattern, by testing the server's current redirect status, or by setting and testing a 'user variable' (See RewriteRule's [E=var:val] flag.) The following example code will execute only once per HTTP request, despite the rule pattern matching its own output path and despite mod_rewrite's recursive behaviour in the .htaccess per-directory context:


RewriteCond %{ENV:RewriteDone} !=Yes
RewriteRule ^(.+\.html)$ ^down-for-maintenence.html$ [E=RewriteDone:Yes,L]

Jim

BlueBlizz

10:16 pm on Sep 23, 2009 (gmt 0)

10+ Year Member



what do you main by protocol?
The ${testmap:$1} is what I need.

changing into:
RewriteRule ^([a-z0-9-]*)/([a-z0-9-]*)/([a-z0-9-]*)/ /${testmap:$1¦$1}/${testmap:$2¦$2}/${testmap:$3¦$3}/ [NC,L]
RewriteRule ^([a-z0-9-]*)/([a-z0-9-]*)/ /${testmap:$1¦$1}/${testmap:$2¦$2}/ [NC,L]
RewriteRule ^([a-z0-9-]*)/ /${testmap:$1¦$1}/ [NC,L]

give in the log:
rewrite 'aaa/bbb/ccc/' -> '/vvv/yyy/zzz/'
trying to replace internal redirect with /vvv/yyy/zzz/ [INTERNAL REDIRECT]

and it goes back into the rules again resulting in a error 500 (internal server error)

jdMorgan

10:25 pm on Sep 23, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Right, and you've apparently ignored the explanation and rather nice example of loop prevention I posted...

Jim

BlueBlizz

10:34 pm on Sep 23, 2009 (gmt 0)

10+ Year Member



rules:
RewriteCond %{ENV:RewriteDone} !=Yes
RewriteRule ^([a-z0-9-]*)/([a-z0-9-]*)/([a-z0-9-]*)/ /${testmap:$1¦$1}/${testmap:$2¦$2}/${testmap:$3¦$3}/ [E=RewriteDone:Yes,L,NC]

RewriteCond %{ENV:RewriteDone} !=Yes
RewriteRule ^([a-z0-9-]*)/([a-z0-9-]*)/ /${testmap:$1¦$1}/${testmap:$2¦$2}/ [E=RewriteDone:Yes,L,NC]

RewriteCond %{ENV:RewriteDone} !=Yes
RewriteRule ^([a-z0-9-]*)/ /${testmap:$1¦$1}/ [E=RewriteDone:Yes,L,NC]

LOG:
RewriteCond: input='' pattern='!=Yes' => matched
setting env variable 'RewriteDone' to 'Yes'
internal redirect with /vvv/yyy/zzz/ [INTERNAL REDIRECT]
RewriteCond: input='' pattern='!=Yes' => matched
setting env variable 'RewriteDone' to 'Yes'
internal redirect with /vvv/yyy/zzz/ [INTERNAL REDIRECT]

The variable is set but not saved during the internal redirect.
rewriteMap is in httpd.conf
rules in htaccess.

Has this anything to do with it?

Caterham

10:44 pm on Sep 23, 2009 (gmt 0)

10+ Year Member



rewriteMap is in httpd.conf
rules in htaccess.

place the rewrite there, too, unless you'd like to overcomplicate things.

ok, so it looks like you want to overcomplicate it.

Has this anything to do with it?

Yes. Don't use directory context for mod_rewrite if you can avoid it and don't use .htaccess files at all if you have access to the httpd.conf.

jdMorgan

10:47 pm on Sep 23, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Weird, but I think I've seen that before... a long time ago.

How about:


RewriteCond %{ENV:[b]REDIRECT_[/b]RewriteDone} !=Yes
RewriteRule ^([a-z0-9-]*)/([a-z0-9-]*)/([a-z0-9-]*)/ /${testmap:$1¦$1}/${testmap:$2¦$2}/${testmap:$3¦$3}/ [E=RewriteDone:Yes,L,NC]

I suggest testing with a single rule only, until you get this bug worked out and have fully-verified the RewriteMap function. Divide and conquer.

Jim

BlueBlizz

11:15 pm on Sep 23, 2009 (gmt 0)

10+ Year Member



The loop seems to stop when using:
RewriteCond %{ENV:REDIRECT_RewriteDone} !=Yes

The url in the addessbar has not changed and .css is not read anymore
Therefor an extra condition fixed the last problem

Now for displaying the new url name in addressbar (for google SEO and getting the clients not confused)

jdMorgan

11:26 pm on Sep 23, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You won't be able to redirect without looping using a RewriteRule pattern that matches the 'new' URL. You'll need to change the new URL so it doesn't match the rule's pattern, change the rule's pattern so the new URL doesn't match, or explicitly exclude all of the new URLs from being redirected.

If you care about telling the search engines to update to use these new URLs, be sure to specify [R=301,L] on the rule to force a 301-Moved Permanently redirect instead of a 302.

Jim

g1smd

12:07 am on Sep 24, 2009 (gmt 0)

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



Also, you missed the very first reply in this thread where I asked you if you really wanted "zero or more" matches.

BlueBlizz

12:21 am on Sep 24, 2009 (gmt 0)

10+ Year Member



02:20 in the Netherlands.
Time for a short sleep.
Will think/dream about all the good suggestions I've got from both of you

BlueBlizz

1:01 pm on Sep 24, 2009 (gmt 0)

10+ Year Member



Is there a possibility to do something like:

RewriteRule ^([a-z0-9-]*)/ /${testmap:$1¦$1}/ if(true)[L] else [PT]

thus:
a different flag for different testmap results?
Or set a variable [E=RewriteDone:] to Yes or No depeding on result?

jdMorgan

1:45 pm on Sep 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No, it's not possible. Mod_rewrite is a special-purpose interpretive module, not a programming language.

But more importantly, you can't use the "RewriteDone" method any more if you're changing the rules from internal rewrites into external redirects -- That variable will be reset in the context of each new HTTP request, and won't help you prevent redirect looping. As I stated above, you need to make some other change to prevent this looping.

Jim

BlueBlizz

2:44 pm on Sep 24, 2009 (gmt 0)

10+ Year Member



any suggestions?

- I've got a text-file containing all old to new url's
- These new url have to be displayed in the addressbar (SEO: redirect 302?)

sometimes the changes in the url are small:
/running/runningshoes/ -> /running/runningschoe/

BlueBlizz

3:12 pm on Sep 24, 2009 (gmt 0)

10+ Year Member



I've heard Google robots only follow 3-4 redirects.
Is this correct? And if so, are both internal and external redirects measured as a redirect?

jdMorgan

3:13 pm on Sep 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



As I stated above:
You won't be able to redirect without looping using a RewriteRule pattern that matches the 'new' URL. You'll need to change the new URL so it doesn't match the rule's pattern, change the rule's pattern so the new URL doesn't match, or explicitly exclude all of the new URLs from being redirected.

If you care about telling the search engines to update to use these new URLs, be sure to specify [R=301,L] on the rule to force a 301-Moved Permanently redirect instead of a 302.

I'm sorry, but your plan cannot be successfully implemented as conceived. To my knowledge, the three options listed are the only solutions that will work.

Jim

g1smd

3:30 pm on Sep 24, 2009 (gmt 0)

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



I've heard Google robots only follow 3-4 redirects.

Whoa! You need to aim for precisely *one* external redirect for any initial URL request to arrive at final URL destination. Any more than one could be a disaster.

Is this correct? And if so, are both internal and external redirects measured as a redirect?

Only external redirects are counted, as those are the only things that ask the user agent to make a new request for a new URL.

The internal rewrite operation simply translates an external URL request into an internal filepath fetch, using a filepth is different to the one that was suggested by the final URL request.