Trouble with a complex rewrite

Igor Sysoev is at rambler-co.ru
Mon Apr 2 16:25:24 MSD 2007


On Mon, Apr 02, 2007 at 07:41:09AM -0400, Wilson Bilkovich wrote:

> I am migrating an existing Apache 2.2.4 -> Mongrel configuration to Nginx.
> Everything is working fine save for one final piece.
> 
> We have a complicated rule that redirects some traffic to a partner
> site based on the contents of the query string. At the moment, this is
> still a requirement, and I can't do away with it.
> 
> The existing Apache rule is:
> 
> RewriteCond %{QUERY_STRING} message=.*(%\d+|\b)(foo|bar|baz|qux)(%\d+|\b) 
> [NC]
> RewriteRule ^/api/receive
> http://target.example.com/horrible/url/?%{QUERY_STRING} [P,L,NC]
> 
> The nasty piece here is that "%\d+" in the regexp pattern is
> necessary. 'foo' should only match if it is a whole word in the query
> string.
> (%\d+|\b) allows the pattern to handle either normal word boundaries,
> or HTML-encoded entities like %20.
> For example:
> api/receive?message=foo%20hello should match this rule, but:
> api/receive?message=hellofoo should not
> 
> Is it possible to duplicate this in nginx?
> Thus far I have tried:
> 1. Making a location {} entry for api/receive, and using if
> ($query_string ~ pattern)
> 2. Using if($query_string) inside the / location block
> 3. Making a location entry for the regexp on its own
> 4. Testing with simply message=.*foo as the pattern, which makes me
> think the problem is more basic than the regexp pattern
> 
> None of these seem to work.
> I've tried both "~" and "~*" styles, though I haven't actually been
> able to figure out what the difference between them is.

        location /api/receive {
            if ($args ~ "message=.*(%\d+|\b)(foo|bar|baz|qux)(%\d+|\b)") {
                rewrite  ^   http://target.example.com/horrible/url/;
            }
        }


-- 
Igor Sysoev
http://sysoev.ru/en/





More information about the nginx mailing list