Proud member of the sinister Smart Goat keiretsu.

 Permanent link to: Using mod_rewrite for Backward Compatibility Using mod_rewrite for Backward Compatibility

January 14, 2004 02:30 PM

Problem:

You just upgraded your web site to a new back-end system. The old system used URLs like this:

http://www.domain.com/cgi-bin/product.cgi?product=abc123

Your new system, however, creates “friendly” URLs, like so:

http://www.domain.com/product.php/product_model/abc123

Now, for the entire time you used the old system, Google was your friend. Your URLs may have been unfriendly, but they weren’t bad enough to deter Google. All those old links to your products are still out there, and you need some way to point them to their new locations.

Solution:

mod_rewrite

The problem above is exactly what I faced with the redesign of Crafty Goat. It took quite a bit of digging to pull together all the information I needed to solve this, so I thought I should document the answer here.

What I needed was the ability to take the product ID from the old URL, put it into the new URL, and serve a HTTP 301 (permanent redirect) response.

My early attempts looked something like this:

RewriteRule ^cgi-bin/product.cgi?product=(.*) http://www.domain.com/product.php/product_model/$1 [R,L]

This does not work for a variety of reasons. First, RewriteRule does not match against the query string (everything after the question mark). Second, this only serves up a temporary redirect (HTTP 302 response). What I needed was a RewriteCond, which can match against the query string, and a specific redirect response. Like so:

RewriteCond %{QUERY_STRING} ^product=(.*)$
RewriteRule ^cgi-bin/product.cgi http://www.domain.com/product.php/product_model/$1 [R=301,L]

This works, except for one thing. Apache will kindly append the old query string to the end of the new URL, just in case you need it. I do not. Luckily, this is addressed in the documentation: Simply add a question mark to the end of the new URL to eliminate the old query string. Which leaves us with this:

RewriteCond %{QUERY_STRING} ^product=(.*)$
RewriteRule ^cgi-bin/product.cgi http://www.domain.com/product.php/product_model/%1? [R=301,L]

Which solves our problem perfectly. Like I said before, most of what the Apache server does is complete magic to me. Hopefully, I can find time soon to learn more about this stuff.

Smart Goat
Crafty Goat
Central Oklahoma Mensa
Jon's Site
Slashdot
Techbargains
Camworld
WWDN
Arts & Letters Daily
A List Apart
Zeldman
Doc Searls
Dan Gillmor
Engadget
Lawrence Lessig
Technorati Profile
 


January 2005
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
 

 

Valid XHTML 1.0!

Valid CSS!

Movable Type

Browse Happy logo