Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to set up a couple of simple rules that rewrite URLs from an old version of a site based on bits of the path and the query string.

First whack at it looked like this:

RewriteEngine on

RewriteMap freeitems txt:/www/www.example.com/etc/freeitems_map.txt
RewriteMap items txt:/www/www.example.com/etc/items_map.txt

RewriteCond %{QUERY_STRING} ^sku=(\d+)$
RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}?
RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}?

That seemed to work great for the /free_item.php URLs, properly subsituting in the result from the RewriteMap, but /item.php URLs returned just the first part of the redirected URL, leaving out the results from the RewriteMap lookup. If I reversed the order of the rules, the failed/working URLs reversed. As I have always understood RewriteRule syntax, if the URL path doesn't match the pattern, the rule is skipped and processing moves on to the next one. In this case, the

I finally managed to get it working by breaking it out into two blocks:

RewriteEngine on

RewriteMap freeitems txt:/www/www.example.com/etc/freeitems_map.txt
RewriteMap items txt:/www/www.example.com/etc/items_map.txt

RewriteCond %{QUERY_STRING} ^sku=(\d+)$
RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}?

RewriteCond %{QUERY_STRING} ^sku=(\d+)$
RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}?

Can anyone enlighten me as to why the first technique failed?

EDIT: As a test, I added an additional path element to the redirected URL for the second RewriteRule. When I requested a URL that should match the second rule and not the first, that path element appears as expected. Just not the result of the RewriteMap lookup.

Thanks!

-Ben

share|improve this question

1 Answer 1

up vote 1 down vote accepted

The reason the first technique failed, is because the RewriteCond %1 back reference on the 2nd RewriteRule does not exist. Each RewriteRule has its own set of RewriteCond and does not share RewriteCond with other RewriteRule blocks.

See: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#InternalRuleset

I'd also suggest adding the [L] flag, as it would appear that each rule stands on its own. eg:

RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}? [L]

RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}? [L]

Good luck :)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.