Opened 5 years ago
Closed 5 years ago
#1862 closed defect (duplicate)
Cache-Control:no-store should remove entry from cache (with proxy_cache_background_update+proxy_cache_use_stale)
Reported by: | Ondřej Nový | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | other | Version: | 1.16.x |
Keywords: | Cc: | ||
uname -a: | Linux mustafar 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.16.1
built with OpenSSL 1.1.1c 28 May 2019 TLS SNI support enabled configure arguments: --with-debug --with-cc-opt='-g -O2 -fdebug-prefix-map=/builds/nginx/szn-nginx=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2 -I /builds/nginx/szn-nginx/openssl/.openssl/include -pthread -DNGX_HAVE_CLOCK_MONOTONIC=0' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -fPIC -L /builds/nginx/szn-nginx/openssl/.openssl/lib -pthread' --prefix=/www/nginx --conf-path=/www/nginx/doc/nginx.conf --http-log-path=/www/nginx/log/access.log --error-log-path=/www/nginx/log/error.log --lock-path=/www/nginx/lock/nginx.lock --pid-path=/var/run/nginx.pid --modules-path=/www/nginx/modules --http-client-body-temp-path=/www/nginx/var/lib/body --http-fastcgi-temp-path=/www/nginx/var/lib/fastcgi --http-proxy-temp-path=/www/nginx/var/lib/proxy --http-scgi-temp-path=/www/nginx/var/lib/scgi --http-uwsgi-temp-path=/www/nginx/var/lib/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_flv_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_secure_link_module --with-http_sub_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_geoip_module=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module |
Description
We are using proxy_cache_background_update+proxy_cache_use_stale.
We have backend which sometimes sets Cache-Control to max-age>10, but for same request sometimes to no-cache/no-store. When we cache entry with max-age=10, that entry keeps in cache forever, even if we set no-cache/no-store in late request.
Example nginx conf to simulate same situation:
events { use epoll; } http { proxy_cache_path /home/debian/test-cache/cache levels=1:2 keys_zone=cache:10m inactive=10m max_size=256m; server { listen 8080; location /in/cache { return 200; add_header "Cache-Control" "max-age=10" always; } location /in/no-cache { return 200; add_header "Cache-Control" "no-store" always; } location / { add_header "X-Cache-Status" $upstream_cache_status always; proxy_cache cache; proxy_cache_key "same"; proxy_cache_lock on; proxy_cache_background_update on; proxy_cache_use_stale updating error timeout; proxy_cache_valid any 10s; proxy_pass http://localhost:8080/in/; } } }
proxy_cache_key is intentionally same in this example config for all location, because i want to test same cache entry.
Add entry into cache:
root@mustafar:/home/debian/test-cache# wget -S localhost:8080/cache -O /dev/null 2>&1 | grep X-Cache-Status X-Cache-Status: MISS root@mustafar:/home/debian/test-cache# wget -S localhost:8080/cache -O /dev/null 2>&1 | grep X-Cache-Status X-Cache-Status: HIT root@mustafar:/home/debian/test-cache# wget -S localhost:8080/no-cache -O /dev/null 2>&1 | grep X-Cache-Status X-Cache-Status: HIT
After >10s, entry is not valid, it's STALEd:
root@mustafar:/home/debian/test-cache# wget -S localhost:8080/no-cache -O /dev/null 2>&1 | grep X-Cache-Status X-Cache-Status: STALE
which is correct. Background task to refresh cache has been started now, because proxy_cache_background_update is on. /in/no-cache location returns Cache-Control: no-store, which should refresh cache entry (in this situation: remove it). But cache entry remains here for ever (until inactive=10m is hit).
Removing a cache entry if an update request returns a non-cacheable response isn't always a good idea: notably, the response might be an uncacheable error, and throwing away cached item in such a case is a bad idea. A readily available solution would be to use 'Cache-Control: stale-while-revalidate=<timeout>" instead of "proxy_cache_use_stale updating" - this allows to specify a timeout to stop using cached response if we weren't able to update it.
Closing this as a duplicate of #853, which is about the same problem and also links to the relevant thread in the nginx-devel@ mailing list.