compare %{REQUEST_URI} with an map value

Discuss practical ways rearrange URLs using mod_rewrite.

compare %{REQUEST_URI} with an map value

Postby bige » Tue Aug 25, 2009 1:01 pm

My overall goal is to grab a value from a map file using a key (%2). Then compare that value to the initial untainted %{REQUEST_URI}. If they exactly match (see line 3) then no redirect is necessary - just serve it. If they don't match (see line 7), then redirect to the official url is done.

The problem is that line 3 and 7 aren't string comparing like I think they are. Any ideas?

RewriteMap lowercase int:tolower
RewriteMap urls txt:/www/docs/www.domain.com/redirects.url

1. RewriteCond %{REQUEST_URI} ^/([a-z0-9]*)-p-([a-z0-9]+)$
2. RewriteCond ${urls:%2} >""
3. RewriteCond %{REQUEST_URI} ${urls:%2}
4. RewriteRule ^([a-z0-9]*)-p-([a-z0-9]+)$ /realpage.html?%1-%2 [NC,L]
5. RewriteCond %{REQUEST_URI} ^/([a-z0-9]*)-p-([a-z0-9]+)$
6. RewriteCond ${urls:%2} >""
7. RewriteCond %{REQUEST_URI} !${urls:%2}
8. RewriteRule ^([a-z0-9]*)-p-([a-z0-9]+)$ ${urls:%2} [R=301,L]

map file format is:
key1 /test-p-key1
key2 /test-p-key2
key3 /test-p-key3

Example url requests:
/test2-p-key1 (invalid url, will redirect one time)
/test-p-key3 (valid url, no redirects)
bige
 
Posts: 5
Joined: Fri Apr 25, 2008 7:35 am

Postby bige » Wed Aug 26, 2009 5:59 am

After much reading, you can't dereference variables to a value on the pattern side (right side) of a RewriteCond like you can with a RewriteRule. It's reserved for perl regex's, fixed strings, and misc. test flags like -f.

To no avail, I even tried tricking it out with stuff like:
RewriteCond %{REQUEST_URI} ^${ENV:${urls:%2}}$

Since I can't test variables, I resorted to test against filename existance. So I implemented a redirects directory loaded up with a slew of 0-byte files with the name of a valid url.

1. RewriteCond %{REQUEST_URI} ^/([a-z0-9]*)-p-([a-z0-9]+)$
2. RewriteCond %{DOCUMENT_ROOT}/redirects/%1-p-%2 -f
3. RewriteRule ^([a-z0-9]*)-p-([a-z0-9]+)$ /realpage.html?%1-%2 [NC,L]
4. RewriteCond %{REQUEST_URI} ^/([a-z0-9]*)-p-([a-z0-9]+)$
5. RewriteCond %{DOCUMENT_ROOT}/redirects/%1-p-%2 !-f
6. RewriteCond ${urls:%2} >""
7. RewriteRule ^([a-z0-9]*)-p-([a-z0-9]+)$ ${urls:%2} [R=301,L]

Any better method than this, please share. Thanks.
bige
 
Posts: 5
Joined: Fri Apr 25, 2008 7:35 am

Postby richardk » Sat Aug 29, 2009 1:59 pm

With some versions of Apache (it depends on the regular expression library version) you can compare with backreferences/variable in the regular expression. Using Backreferences in The Regular Expression.

Try
Code: Select all
Options +FollowSymLinks

RewriteEngine On

RewriteCond ${urls:$2} ^(.+)$
RewriteCond %1?%{REQUEST_URI} !^([^?]+)\?\1$
RewriteRule ^([a-z0-9]+)-p-([a-z0-9]+)$ %1 [R=301,L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

that did it.

Postby bige » Mon Aug 31, 2009 6:44 pm

Neat! With only one map lookup operation and the \1 inline back reference to compare strings, this is a much slicker test. No need for the -f tests.

Thanks richardk - great work.
bige
 
Posts: 5
Joined: Fri Apr 25, 2008 7:35 am


Return to Friendly URLs with Mod_Rewrite

Who is online

Users browsing this forum: No registered users and 27 guests

cron