Part of the fun of writing programs that deal with HTTP is decoding things like RFC 2616 to answer somewhat obscure questions about how various things interact. Today's case is the following question:
When can your web server generate a 304 'content not modified' response if it receives a request with both an
If-None-Matchand anIf-Modified-Sinceheader?
If-None-Match
and
If-Modified-Since
are HTTP request headers used to implement 'conditional GET', a bandwidth saving technique that avoids re-fetching unchanged pages (see here or here for more discussion of this).
(
ETag
headers come into this because the server's
ETag
value is what the client will use as its
If-None-Match
value in the conditional GET request.)
The answer turns out to be in section 13.3.4 of RFC 2616 . It is (de-RFC-ized):
You can only generate a 304 response if both headers match; the
If-None-Matchmatches the response'sETagand theIf-Modified-Sinceheader matches theLast-Modified.
In the case of
If-Modified-Since
and
Last-Modified
, servers may require an exact match instead of merely Last-Modified being no later than If-Modified-Since. As RFC 2616 notes in 14.25 , client authors should really just store the Last-Modified result as a string and hork it up in their If-Modified-Since header.
This came up when I threw debugging code into DWiki to see exactly what various people repeatedly pulling my Atom feed without getting bandwidth-efficient 304 responses were sending. One feed reader was sending both headers but making up their own If-Modified-Since instead of just repeating Last-Modified. ( DWiki requires an exact match for technical reasons.)
(Whether by accident or by reading RFC 2616 carefully when I wrote the code and then forgetting it, DWiki does the right thing when both headers are present.)