Nginx unexpectedly returning 304 for content cached from proxy
nginx-forum at nginx.us
Tue Oct 27 04:49:10 MSK 2009
I believe I have now located cause of this problem. It appears that "If-None-Match" is being passed back to the Apache backend. (For reference: If-None-Match http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26)
Unfortunately, the 0.8.1 fix doesn't apply to this header:
*) Bugfix: the "If-Modified-Since", "If-Range", etc. client request
header lines were passed to backend while caching if no
"proxy_set_header" directive was used with any parameters.
As a result, the Apache backend can still return a 304, which nginx happily caches. This is obviously not correct behavior for HTTP/1.1 (RFC2616):
If a 304 response indicates an entity not currently cached, then the cache MUST disregard the response and repeat the request without the conditional.
As a workaround, I'm removing this header for proxying:
proxy_set_header If-None-Match "";
However, this causes requests using only If-None-Match to return 200 OK:
> GET /css/rich.css HTTP/1.1
> User-Agent: curl/7.16.3 (i686-pc-cygwin) libcurl/7.16.3 OpenSSL/0.9.8k zlib/1.2.3 libssh2/0.15-CVS
> Host: prod-login.uqconnect.net:444
> Accept: */*
> If-None-Match: "48892-1dfa-47682392e3c00"
< HTTP/1.1 200 OK
< Server: nginx/0.8.17
< Date: Tue, 27 Oct 2009 01:28:41 GMT
< Content-Type: text/css
< Connection: keep-alive
< Last-Modified: Thu, 22 Oct 2009 08:53:04 GMT
< ETag: "48892-1dfa-47682392e3c00"
< Accept-Ranges: bytes
< Content-Length: 7674
< Cache-Control: max-age=5
< Expires: Tue, 27 Oct 2009 01:28:46 GMT
This is fine for now, though not ideal. RFC2616 only states that a server SHOULD return a 304, not that it must. ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26 ).
I don't think the work-around should be required though. While the proxy module is limited to HTTP/1.0 (and RFC1945 doesn't include "If-None-Match"), nginx should still comply with RFC2616 for its own replies without extra configuration. This bug is particularly nasty because the current stripping of "If-Modified-Since" means that 304 will be returned in cases where the original preconditions would have generated a 200 OK.
Any chance of a bug fix?
Posted at Nginx Forum: http://forum.nginx.org/read.php?2,2703,17110#msg-17110
More information about the nginx