Search code examples
.htaccessmod-rewritehttp-status-code-301

Possible infinite loop in mod_rewrite?


I am working on overhauling the URL structure of review pages, which can be filtered by city, county, # of stars and technician. I want to make the pages look like they are static HTML pages as well as replace pluses with hyphens. My goal: -Apply the new style URL's without modifying the reviews page, just the htaccess file -Set up 301 redirects from the old style URLs to new style URLs -Convert pluses to hyphens

Currently the review URLs look like this:

domain.com/reviews/?city=City+Name

domain.com/reviews/?city=City+Name&page=2

domain.com/reviews/?county=County+Name

domain.com/reviews/?county=County+Name&page=2

domain.com/reviews/?stars=4

domain.com/reviews/?stars=4&page=2

domain.com/reviews/?tech=Tech+Name

domain.com/reviews/?tech=Tech+Name&page=2

My goal is to make them look like this (and 301 the old style URLs to the new style URLs):

domain.com/reviews/city/City-Name.html

domain.com/reviews/city/City-Name/page/2.html

domain.com/reviews/county/County-Name.html

domain.com/reviews/county/County-Name/page/2.html

domain.com/reviews/stars/4.html

domain.com/reviews/stars/4/page/2.html

domain.com/reviews/tech/Tech-Name.html

domain.com/reviews/tech/Tech-Name/page/2.html

City, county and tech names don't always contain pluses (ie Boston vs New+York) and some have more than one plus. Currently this is what I have to mask the old style URLs with new style URLs (and this works fine btw):

##FIRST PAGE REVIEWS (ie. reviews/city/city-name.html)
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\-(.*)\-(.*)\.html "/reviews/?$1=$2+$3+$4+$5+$6" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\-(.*)\.html "/reviews/?$1=$2+$3+$4+$5" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\.html "/reviews/?$1=$2+$3+$4" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\.html "/reviews/?$1=$2+$3" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\.html "/reviews/?$1=$2" [NC,L]

##PAGINATED REVIEWS (ie. reviews/city/city-name/page/2.html)
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\-(.*)\-(.*)/page/(.*)\.html "/reviews/?$1=$2+$3+$4+$5+$6&page=$7" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\-(.*)/page/(.*)\.html "/reviews/?$1=$2+$3+$4+$5&page=$6" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)/page/(.*)\.html "/reviews/?$1=$2+$3+$4&page=$5" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)/page/(.*)\.html "/reviews/?$1=$2+$3&page=$4" [NC,L]
RewriteRule ^reviews/(.*)/(.*)/page/(.*)\.html "/reviews/?$1=$2&page=$3" [NC,L]

The part that I am having trouble with is 301-ing the OLD style URLs to the NEW style URLs. This is what I have so far:

RewriteCond %{QUERY_STRING} (.*)=(.*) [NC]
RewriteRule ^reviews/(.*) /reviews/%1/%2.html? [NS,R=301,NC]

RewriteCond %{QUERY_STRING} (.*)=(.*)&page=(.*) [NC]
RewriteRule ^reviews/(.*) /reviews/%1/%2/page/%3.html? [NS,R=301,NC]

When I try this FireFox gives me the "The page isn't redirecting properly" error. Any ideas?


Solution

  • Yes, this is probably an infinite loop. Use THE_REQUEST instead to inspect the request line:

    RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^?\ ]*\?([^=]+)=([^\ ]*)&page=([^\ ]*) [NC]
    RewriteRule ^reviews/ /reviews/%1/%2/page/%3.html? [NS,R=301,NC]
    RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^?\ ]*\?([^=]+)=([^\ ]*)
    RewriteRule ^reviews/ /reviews/%1/%2.html? [NS,R=301,NC]
    

    Note that this will fail if the number or order of parameters is different than this.