Opened 6 years ago

Closed 4 years ago

#746 closed defect (wontfix)

Cached objects wit expires headers in the past served up with proxy_cache_revalidate

Reported by: Justin Ellison Owned by:
Priority: minor Milestone:
Component: nginx-module Version: 1.6.x
Keywords: Cc:
uname -a: Linux base.vagrant.foo.com 2.6.32-504.8.1.el6.x86_64 #1 SMP Wed Jan 28 21:11:36 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.6.2
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)
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=/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-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'

Description

When setting up a nginx reverse proxy that caches objects to the filesystem, you can get into a configuration where objects with Expires headers that expire in the past are served up indefinitely.

Steps to reproduce:

1) Setup a backend to proxy for that sends expires, etags, and last-modified headers
2) Setup nginx to proxy for that backend host. Enable a proxy_cache_path with a large inactive time, such as 24h. Enable proxy_cache_revalidate.
3) Make the first request with curl. The object will be fetched from the backend, and cached on nginx's filesystem. Note that the expires header from the backend and nginx's cached object match.
4) Wait until after the expires header timestamp has passed, and make the same request from curl. Nginx will do the right thing and revalidate the object, but if the object has the same etag on the backend with a new expires header, nginx won't update it's local cached object with the new expires timestamp.

Shouldn't nginx update it's expires header to match the backend on revalidation?

That's the core bug, but there's some other behavior going on that I can't quite figure out. Even though nginx now has an expires header in the past, it doesn't attempt to revalidate on each request after that. I'm not 100% certain, but I think only time it would attempt to revalidate was after the inactive time on the proxy_cache_path had expired.

Disabling proxy_cache_revalidate is a workaround, but not nearly as efficient.

I'm attaching a diff of what I've done to the configuration from a stock install of the CentOS 6 RPM from the nginx yum repo.

Attachments (1)

nginx.patch (6.2 KB ) - added by Justin Ellison 6 years ago.
nginx-config.patch

Download all attachments as: .zip

Change History (2)

by Justin Ellison, 6 years ago

Attachment: nginx.patch added

nginx-config.patch

comment:1 by Maxim Dounin, 4 years ago

Resolution: wontfix
Status: newclosed

The proxy_cache_revalidate is turned off by default, in particular, because nginx doesn't try to merge headers received in 304 responses with original response headers. And there are no plans to change this in foreseeable future.

If you want to use proxy_cache_revalidate, consider using Cache-Control: max-age=... instead of (or in addition to) Expires on your backend, and/or using proxy_hide_header/expires to hide or change the header on nginx side.

Note: See TracTickets for help on using tickets.