I have a following servers structure:
content.server contains an Apache instance, which processes one simple
PHP script. On the same node Nginx is set as a caching proxy to that
Apache.
caching.server contains Nginx with proxy_cache directive, with upstream
set to content.server
Php script generates an XML file, that has a lifetime of 30 minutes.
This is achieved by setting headers in PHP code: “Cache-Control:
max-age=1800”, “Date: now()” and “Expires: now()+1800seconds”.
But approximately half of the time caching.server serves the content
where Date header is larger than Expires, and Expires is different from
the one on content.server:
And an additional question: why haven’t nginx requested a new file, when
“Expires” header becomes bigger than current date? Can it be caused by
proxy_cache_valid any 10m; directive?
I’ve captured the debug output of the outlined problem: Expires tag is
less than the date of request processing, but there is no expiration
message like “http file cache expired: 4 1302149578 1302149592”
Debug output:
This doesn’t actually correct: Cache-Control max-age and Expires disagree.
According to max-age, document should expire at 10:20:49, while
expires set to 10:14:25.
Unless configured to ignore some headers (with
proxy_ignore_headers directive) nginx will use first relevant
header it sees to actually expire cached document, Cache-Control
max-age in this case.
Really? That behavior would seem to be at odds with the HTTP 1.1
specification. From RFC 2616 section 14.9.3:
“If a response includes both an Expires header and a max-age
directive, the max-age directive overrides the Expires header, even if
the Expires header is more restrictive”
As almost all origin servers send both Expires and Cache-Control in
their default configurations, with the Expires header coming first,
wouldn’t nginx end up doing the wrong thing most of the time?
This doesn’t actually correct: Cache-Control max-age and Expires
disagree.
According to max-age, document should expire at 10:20:49, while
expires set to 10:14:25.
Unless configured to ignore some headers (with
proxy_ignore_headers directive) nginx will use first relevant
header it sees to actually expire cached document, Cache-Control
max-age in this case.
its own Expires header?
Value of Expires header is preserved from original request, while
Date is current date on the server. Since document isn’t expired
yet (see above), you see Expires in the past.
On Thu, Apr 07, 2011 at 02:54:32PM -0500, Ryan M. wrote:
set to content.server
specification. From RFC 2616 section 14.9.3:
“If a response includes both an Expires header and a max-age
directive, the max-age directive overrides the Expires header, even if
the Expires header is more restrictive”
Yes, I’m aware of the fact that it’s not exactly correct per
RFC2616. The excuse is that nginx is HTTP/1.0 client.
As almost all origin servers send both Expires and Cache-Control in
their default configurations, with the Expires header coming first,
wouldn’t nginx end up doing the wrong thing most of the time?
I believe most servers either don’t sent Expires/Cache-Control at
all, or they agree.
If you do really care - workaround is to use proxy_ignore_headers.