Opened 7 years ago
Closed 7 years ago
#1498 closed defect (duplicate)
Named and capture variables cannot be used together
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-module | Version: | 1.12.x |
Keywords: | if set rewrite variable | Cc: | |
uname -a: | Linux servername 4.9.0-5-amd64 #1 SMP Debian 4.9.65-3+deb9u2 (2018-01-04) x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.12.1
built by gcc 4.9.2 (Debian 4.9.2-10) built with OpenSSL 1.0.2j 26 Sep 2016 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --http-client-body-temp-path=/run/shm/body_temp --http-proxy-temp-path=/run/shm/proxy_temp --http-fastcgi-temp-path=/run/shm/fastcgi_temp --http-uwsgi-temp-path=/run/shm/uwsgi_temp --http-scgi-temp-path=/run/shm/scgi_temp --with-http_ssl_module --with-http_realip_module --with-http_sub_module --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --with-mail --with-http_v2_module --with-http_geoip_module --with-select_module --with-http_auth_request_module --with-poll_module --with-debug |
Description
Say I want to rewrite URI differently depending on something like client cookie. So I create a map (remembering that if is evil):
map $cookie_foo $my_var { 1 bar; default baz; }
And later I try to do the obvious rewrite:
location / { rewrite ^/(.*) /$my_var/$1 break; proxy_pass http://backend; }
... and it's tricky. In my case, if map returns default value (baz
), everything works as planned. But if map returns non-default value (bar
), $1
in rewrite expands to empty string no matter what URI really is.
More over, this magic happens not only in rewrite
, but in set
too, for example, I tried the following:
if ( $uri ~ ^/(.*) ) { set $rewrite_path $my_var/$1; rewrite /.* /$rewrite_path break; }
That doesn't work either. But the next piece of code finally works fine for me:
if ( $uri ~ ^/(.*) ) { set $tmp_var $1; rewrite /.* /$my_var/$tmp_var break; }
But it's ugly AF.
Can you please fix it so that the original version (rewrite ^/(.*) /$my_var/$1 break;
) works? Or please tell me what part of the documentation describes why this is impossible (but nevertheless works in some cases).
Debug log for both cases:
1) when map returns default value:
2018/03/02 19:25:09 [debug] 23380#0: *495 http map: "0" "baz" 2018/03/02 19:25:09 [debug] 23380#0: *495 http script copy: "/" 2018/03/02 19:25:09 [debug] 23380#0: *495 http script var: "baz" 2018/03/02 19:25:09 [debug] 23380#0: *495 http script copy: "/" 2018/03/02 19:25:09 [debug] 23380#0: *495 http script capture: "mstatic/build/main.bundle.js" 2018/03/02 19:25:09 [debug] 23380#0: *495 http script regex end 2018/03/02 19:25:09 [notice] 23380#0: *495 rewritten data: "/baz/mstatic/build/main.bundle.js"
URI is captured and capture variable is expanded all right - works as expected
2) when map returns non-default value:
2018/03/02 19:23:20 [debug] 23371#0: *74 http map: "1" "bar" 2018/03/02 19:23:20 [debug] 23371#0: *74 http script copy: "/" 2018/03/02 19:23:20 [debug] 23371#0: *74 http script var: "bar" 2018/03/02 19:23:20 [debug] 23371#0: *74 http script copy: "/" 2018/03/02 19:23:20 [debug] 23371#0: *74 http script capture: "" 2018/03/02 19:23:20 [debug] 23371#0: *74 http script regex end 2018/03/02 19:23:20 [notice] 23371#0: *74 rewritten data: "/bar/"
URI was the same, but it says that capture is empty, so somebody is lying here.
Change History (3)
comment:1 by , 7 years ago
comment:3 by , 7 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Thanks for confirming. Closing this as duplicate of #564.
In the particular configuration with the
map
listed there should be no problem. The problem you are describing is likely to happen when using regular expressions inmap
, see #564.