mod_rewrite infinite loop problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



URL for product pages used to look like this:

/product?sku=SKU

In our new version, each product is getting a nice looking path
assigned.  New URLs are of the form

/product/PRODUCT_PATH?sku=SKU

I create a txt rewrite map file. Here is an example /etc/httpd/conf/sku_to_path.txt:

000001 Path_To_Product1

In order to redirect from the old to the new form, I have the following
config:

RewriteMap sku_to_path     
txt:/etc/httpd/conf/sku_to_path.txt

RewriteCond %{REQUEST_URI}  ^/product$
RewriteCond %{QUERY_STRING} sku=([0-9A-Z]+)
RewriteRule .* /product/{sku_to_path:%1} [R=301,L]

This works fine, /product?sku=000001 maps to /product/Path_To_Product1?sku=000001 and when the
server gets the request for /product/Path_To_Product1?sku=000001, it's not
rewritten because it fails the match ^/product$

Here is my problem.  I have further requirements that the path for a
product is allowed to change over time (marketers love to change their
minds), and URL with the old path  (which lives in the Google index we
hope) should redirect to the new path.  For example, if my
sku_to_path.txt changes to

000001 New_Path_To_Product1

I need /product/Path_To_Product1?sku=000001 to
redirect to 
/product/New_Path_To_Product1?sku=000001 
If I try removing the $ from the ^/product$ match above to accomplish
this, I get infinite redirects, since the request for /product/New_Path_To_Product1?sku=000001  matches
all the conditions and gets rewritten to itself over and over again.

The following attempt to fix this problem fails because
%{ENV:INCOMING_PATH} on the right side of the RewriteCond is not expanded

RewriteMap sku_to_path     
txt:/static/73/maps/musiciansfriend.com/sku_to_path.txt

RewriteCond %{REQUEST_URI}  ^/product/(.*)
RewriteRule ^ - [E=INCOMING_PATH:%1]

RewriteCond %{QUERY_STRING} sku=([0-9A-Z]+)
RewriteCond ${sku_to_path:%1} !%{ENV:INCOMING_PATH}
RewriteRule .* /product/${sku_to_path:%1} [R=301,L]

I have a solution to this problem, but I'm wondering whether there is a
simpler way.  Here is my solution:

I created a rewrite map program - it takes a string with two substrings
separated by ":".  If the left is the same as the right, it returns 0,
if different it returns 1

#!/usr/bin/perl
# /etc/httpd/different.pl
$| = 1;
while (<STDIN>) {
    chomp;
    ($first, $second) = split (/:/);
    if ( $first eq $second) { print "0\n";}
    else { print "1\n"; }
}

My working mod_rewrite config is

RewriteMap sku_to_path      txt:/etc/httpd/conf/sku_to_path.txt
RewriteMap different prg:/etc/httpd/different.pl

RewriteCond %{REQUEST_URI}  ^/product(.*)
RewriteRule ^ - [E=INCOMING_PATH:%1]

RewriteCond %{QUERY_STRING} sku=([0-9A-Z]+)
RewriteRule ^ - [E=CORRECT_PATH:/${sku_to_path:%1}]

RewriteCond ${different:%{ENV:CORRECT_PATH}:%{ENV:INCOMING_PATH}} 1
RewriteRule .* /product%{ENV:CORRECT_PATH} [R=301,L]

Is there a simpler way?

-David Bylsma



---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@xxxxxxxxxxxxxxxx
   "   from the digest: users-digest-unsubscribe@xxxxxxxxxxxxxxxx
For additional commands, e-mail: users-help@xxxxxxxxxxxxxxxx


[Index of Archives]     [Open SSH Users]     [Linux ACPI]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Squid]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux