Nginx map does not use my regex arguments

I am trying to use nginx map but the results are not what I expect.

This is what I have:

map $uri $new {
  default                                 "";
  ~*/cc/(?P<suffix>.*)$                   test.php?suffix=$suffix;
}

location ~     [a-zA-Z0-9/_]+$ {
        proxy_pass http://www.domain.com:81/$new;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

      

When I go to www.domain.com/cc/abc I see this in the logs

2012/03/29 17:27:53 [warn] 3382#0: *33 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/5/00/0000000005 while reading upstream, client: 1.2.3.4, server: www.domain.com, request: "GET /cc/abc HTTP/1.1", upstream: "http://1270.0.0.1:81/test.php?suffix=$suffix", host: "www.domain.com"

      

The $ suffix is ​​not replaced.

But when I do this:

map $uri $new {
  default                                 "";
  ~*/cc/(?P<suffix>.*)$                   $suffix;
}

location ~     [a-zA-Z0-9/_]+$ {
        proxy_pass http://www.domain.com:81/$new;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

      

And now when I go to www.domain.com/cc/abc, the logs show me this:

2012/03/29 17:29:39 [warn] 5916#0: *26 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/2/00/0000000002 while reading upstream, client: 1.2.3.4, server: www.domain.com, request: "GET /cc/abc HTTP/1.1", upstream: "http://1270.0.01:81/abc", host: "www.domain.com"

      

So, when a rewrite contains a string that includes a variable, it is not replaced. But if it only contains a variable, it will work.

What am I doing wrong?

+3


source to share


1 answer


As you found out, map replacement can only be a static string or a single variable. So how is test.php? Suffix = $ suffix does not start with $, nginx assumes it is just a static string. Instead of using a map, you need to use two rewrites to accomplish what you want:

location ~ [a-zA-Z0-9/_]+$ {
  rewrite ^/cc/(.*) /test.php?suffix=$1 break;
  rewrite ^ / break;

  proxy_pass http://www.domain.com:81;
  proxy_set_header X-Real-IP  $remote_addr;
  proxy_set_header Host $host;
  proxy_set_header X-Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

      



The first rewrite will strip any initial / cc / from url and add the rest as url arg as your map tried. The break flag tells nginx to stop processing rewrite rules. If the first overwrite does not match, then the second will always match and it will set the url to /.

EDIT: as of 1.11.0 the map values ​​can be complex values, so the original config will work

+8


source







All Articles