Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#1142 closed defect (duplicate)

Location vars fails when use map variable in try_files

Reported by: Edu Herraiz Owned by:
Priority: major Milestone:
Component: other Version: 1.11.x
Keywords: try_files map Cc:
uname -a: Linux fae1582a4c7a 4.4.1-040401-generic #201601311534 SMP Sun Jan 31 20:36:43 UTC 2016 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.11.5
built by gcc 4.9.2 (Debian 4.9.2-10)
built with OpenSSL 1.0.1t 3 May 2016
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/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-compat --with-file-aio --with-threads --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-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed'

Description

Trying to use a map variable inside a try_files this way:

map $http_accept $webp_prefix { 
    default   "";
    "~*webp*"  "/webp";
}    

...
    
location ~* "^/(..)(..)(.+)?$" {
  root        /data/result_storage/v2;
  expires     1M;
  try_files $webp_prefix/$1/$2$uri =404;
}

We found the vars $1 and $2 are not correctly recollected:

nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http map started
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http script var: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http map: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" "/webp"
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http script var: "/webp"
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http script copy: "/"
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http script capture: ""
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http script copy: "/"
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http script capture: ""
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 http script var: "/HV5vyg-_H07z7o-g2DaGj5nrkeA=/700x200/www.apsl.net/static/apslweb/img/apsl.png"
nginx_1    | 2016/11/23 17:14:20 [debug] 12#12: *1 trying to use file: "/webp///HV5vyg-_H07z7o-g2DaGj5nrkeA=/700x200/www.apsl.net/static/apslweb/img/apsl.png" "/data/result_storage/v2/webp///HV5vyg-_H07z7o-g2DaGj5nrkeA=/700x200/www.apsl.net/static/apslweb/img/apsl.png"

In the case we not use the map in the try_files:

map $http_accept $webp_prefix { 
    default   "";
    "~*webp*"  "/webp";
}    

...
    
location ~* "^/(..)(..)(.+)?$" {
  root        /data/result_storage/v2;
  expires     1M;
  try_files /webp/$1/$2$uri =404;
}

Works properly:

nginx_1    | 2016/11/23 17:18:21 [debug] 11#11: *1 http script copy: "/webp/"
nginx_1    | 2016/11/23 17:18:21 [debug] 11#11: *1 http script capture: "HV"
nginx_1    | 2016/11/23 17:18:21 [debug] 11#11: *1 http script copy: "/"
nginx_1    | 2016/11/23 17:18:21 [debug] 11#11: *1 http script capture: "5v"
nginx_1    | 2016/11/23 17:18:21 [debug] 11#11: *1 http script var: "/HV5vyg-_H07z7o-g2DaGj5nrkeA=/700x200/www.apsl.net/static/apslweb/img/apsl.png"
nginx_1    | 2016/11/23 17:18:21 [debug] 11#11: *1 trying to use file: "/webp/HV/5v/HV5vyg-_H07z7o-g2DaGj5nrkeA=/700x200/www.apsl.net/static/apslweb/img/apsl.png"

Note the URI we are trying to GET is:
/HV5vyg-_H07z7o-g2DaGj5nrkeA=/700x200/www.apsl.net/static/apslweb/img/apsl.png

We found a old examples using this configuration, but we can make this to work.
Are we missing something?

Change History (2)

comment:1 by Maxim Dounin, 4 years ago

Resolution: duplicate
Status: newclosed

You are using $1 and $2 variables which are from last regular expression matched. And since map in your configuration executes a regular expression, $1 and $2 variables are from this match. Quoting map documentation:

A regular expression can contain named and positional captures that can later be used in other directives along with the resulting variable.

It may make sense to just disable positional captures in map, as it seems to cause many unintentional configuration errors.

Closing this as duplicate of #564, which is about very similar problem with map and rewrite.

comment:2 by Edu Herraiz, 4 years ago

Thank you very much for your comments, very helpful.

For the record, we solved our particular problem naming the variables in the location:

map $http_accept $webp_prefix {
    default   "";
    "~*webp*"  "/webp";
}

server {
    
    location ~* "^/(?<path>..)(?<path2>..)(.+)?$" {
        root        /data/result_storage/v2;
        expires     1M;
        try_files $webp_prefix/$path/$path2$uri =404;
        add_header Vary Accept;
        error_page  404 = @fetch;
    }
}
Note: See TracTickets for help on using tickets.