Opened 7 years ago

Last modified 10 months 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 (5)

comment:1 by Maxim Dounin, 7 years ago

Component: otherdocumentation

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 by Maxim Dounin, 6 years ago

See also #1647.

comment:3 by Maxim Dounin, 5 years ago

See also #1836.

comment:4 by Maxim Dounin, 21 months ago

See also #2375.

comment:5 by Maxim Dounin, 10 months ago

See also #2518.

Note: See TracTickets for help on using tickets.