Opened 18 months ago

Last modified 6 weeks ago

#1285 new defect

map regexp positional captures interfere with location regexp positional captures

Reported by: dimaslv@… Owned by:
Priority: minor Milestone:
Component: documentation Version: 1.10.x
Keywords: map location Cc:
uname -a: Linux srv 3.10.0-327.36.3.el7.x86_64 #1 SMP Mon Oct 24 16:09:20 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.10.3 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) built with OpenSSL 1.1.0c 10 Nov 2016 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-file-aio --with-threads --with-ipv6 --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-stream --with-stream_ssl_module --add-module=/opt/nginx-sla --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -I /opt/openssl110/include' --with-ld-opt='-L /opt/openssl110/lib'

Description

I have map configuration like this:

map $uri $rewrite_scheme {

default "http";
~*test "https";

}

And location configuration like this:

location ~ /proxy_host/(host1|host2)/(.*)$ {

proxy_pass $rewrite_scheme://$1/$2$is_args$args;

}

Before I have added map configuration location was working as expected, but after adding map all positional captures inside location became empty. Probably it is due to map initialization on variable call (which occurs after location).
If it is by design, then it would be nice to document this behavior as it is too hard to investigate.

As a solution named captures could be used like this:

location ~ /proxy_host/(?<rewrite_host>host1|host2)/(?<rewrite_path>.*)$ {

proxy_pass $rewrite_scheme://$rewrite_host/$rewrite_path$is_args$args;

}

Change History (2)

comment:1 Changed 18 months ago by mdounin

  • Component changed from other to documentation

Positional captures as available via $1 .. $9 variables are from the last executed regular expression. As map in your configuration contains a regular expression, it is executed during the map value lookup, and captures refer to the result of this regular expression execution. That's more or less why positional captures are not generally recommended for use, especially in location and server_name directives: they are easily overwritten by any regular expression, and there are lots of cases when a different regular expression can be executed, including non-intuitive ones. Improving the documentation to make this more clear might make sense.

(See also #564, which discusses similar problems with positional captures in rewrite when used with map with regular expressions. This one is a bit different though, and $1 .. $9 variables in rewrite replacement string probably should be changed to always refer captures from rewrite's own regular expression.)

comment:2 Changed 6 weeks ago by mdounin

See also #1647.

Note: See TracTickets for help on using tickets.