Opened 12 days ago

Last modified 8 days ago

#2057 new enhancement

$slice_range variable does not work in set directive.

Reported by: ptcong@… Owned by:
Priority: minor Milestone: nginx-1.19
Component: nginx-module Version: 1.19.x
Keywords: slice_range Cc:
uname -a: Linux abc 3.10.0-1062.18.1.el7.x86_64 #1 SMP Tue Mar 17 23:49:17 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: configure arguments: --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/home/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-threads --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_gzip_static_module --with-http_slice_module --with-http_random_index_module --with-http_secure_link_module --with-pcre=../pcre-8.43 --with-pcre-jit --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,--as-needed,-rpath,/usr/local/luajit/lj2/lib' --add-module=../ngx_devel_kit-0.3.1rc1 --add-module=../lua-nginx-module-0.10.14 --add-module=../headers-more-nginx-module-0.33 --with-openssl=../openssl-OpenSSL_1_0_2o --add-module=../nginx-module-vts-0.1.18

Description

Hello,

I want to set proxy_cache_key dynamically with $cache_key variable.
It works fine with another variables, but with $slice_range this config does not work and give incorrect range from upstream.

set $cache_key "$another_var $blahblah $slice_range";
if ($something) {
set $cache_key "$cache_key new";
}

slice                   1m;
proxy_set_header        Range $slice_range;
proxy_cache_key $cache_key;

$slice_range only works when it's placed directly to proxy_cache_key as this:

slice                   1m;
proxy_set_header        Range $slice_range;
proxy_cache_key $old_cache_key$slice_range;

Is this a bug ?

Change History (1)

comment:1 by Roman Arutyunyan, 8 days ago

It is true $slice_range does not work with the rewrite module directives such as if and set. To fetch a slice, nginx creates a subrequest and sets the value of $slice_range accordingly. This subrequest does not go through normal request phases, but skips to the content phase. This means that if and set are ignored and your cache key remains the same for all slices.

You can still modify the cache key, but you need to escape using rewrite module directives. As an alternative, use volatile maps:

http://nginx.org/en/docs/http/ngx_http_map_module.html#map

Example:

map $something $cache_key {                                                      
    volatile;                                                                
    1       'foo$uri$slice_range';                                           
    default 'bar$uri$slice_range';                                           
}
Note: See TracTickets for help on using tickets.