Opened 4 years ago
#1990 new defect
proxy_cache_min_uses not counted per variant on initial requests
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | documentation | Version: | 1.16.x |
Keywords: | Cc: | ||
uname -a: | Linux 10-0-1-120 4.19.0-0.bpo.6-amd64 #1 SMP Debian 4.19.67-2+deb10u2~bpo9+1 (2019-11-12) x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.16.0
built with OpenSSL 1.1.0k 28 May 2019 (running with OpenSSL 1.1.0l 10 Sep 2019) TLS SNI support enabled configure arguments: --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-pcre --with-debug --with-http_auth_request_module --with-http_sub_module --with-ipv6 --prefix=/usr --user=www-data --group=www-data --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-client-body-temp-path=/var/lib/nginx/body |
Description
When proxy_cache_min_uses
is set to a value greater than 1, and multiple requests arrive which all resolve to a common primary proxy_cache_key
but which are different variants according to the Vary
response header, the requests are not counted on a per-variant basis at first, until at least one variant is cached.
Suppose proxy_cache_min_uses 2
is configured and two requests for the same URL arrive with different Accept-Encoding
headers, and suppose the backend responds to both with Vary: Accept-Encoding
.
The second request will be cached in this case, even though only one "use" has so far been seen for that variant.
After this, future requests will be counted on a per-variant basis, however.
Consider the following sequence of requests for the same URL with proxy_cache_min_uses 2
:
Accept-Encoding: foo MISS (not cached) Accept-Encoding: bar MISS (cached) Accept-Encoding: bar HIT Accept-Encoding: foo MISS (not cached) Accept-Encoding: abc MISS (not cached) Accept-Encoding: foo MISS (cached) Accept-Encoding: abc MISS (cached) Accept-Encoding: foo HIT Accept-Encoding: abc HIT
So the foo
variant ends up not cached until its third request, while the bar
variant is cached on its first request. Only the abc
variant is correctly cached on its second request.
This appears to be due to the way that ngx_http_file_cache_open()
first calls ngx_http_file_cache_exists()
but only proceeds to ngx_http_file_cache_read()
if a "primary" cache file is found, and it's only in ngx_http_file_cache_read()
that the variant is tested and a "secondary" cache file may be opened instead using ngx_http_file_cache_reopen()
(see https://hg.nginx.org/nginx/file/stable-1.16/src/http/ngx_http_file_cache.c#l598).
So "uses" are counted generically against the primary key, regardless of variation, until a first cache file is created for that key.
It would be ideal if, instead, per-variant use counting could be done from the start for each unique cache key.