gregjones/httpcache — pull request #29 by sqs (2014-11-06 04:12:17+00:00)
Title: Update cached header fields based on those from incoming 304 response

Removes getHopByHopHeaders and merges all headers from a 304 into the
cache entry (and outgoing response). The new behavior is still not
totally compliant since hop-by-hop headers are stored in the cache
entry, but the previous behavior did so as well. Adds TestUpdateFields
to test this behavior.

This change improves cache performance in the following case. Suppose
the cache has an entry with 'Cache-Control: max-age=60' and a
Date. After it has been stored for 60 seconds, a subsequent request
will attempt to revalidate it. Prior to this commit, if the server
responded with a 304, the old Date header (from the initially cached
response) would remain, and each request after 60 seconds would cause
a revalidation. This commit makes it so that if the server responds
with a 304 and an updated Date (or other header fields), the updated
header fields will be used in future freshness decisions. This can
eliminate unnecessary revalidations.

HTTP 1.1 spec citations follow.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html

Section 13.5.3:

> When a cache makes a validating request to a server, and the server provides a 304 (Not Modified) response or a 206 (Partial Content) response, the cache then constructs a response to send to the requesting client.

> ...

> - any end-to-end headers provided in the 304 or 206 response MUST replace the corresponding headers from the cache entry.

> Unless the cache decides to remove the cache entry, it MUST also replace the end-to-end headers stored with the cache entry with corresponding headers received in the incoming response, except for Warning headers as described immediately above. If a header field- name in the incoming response matches more than one header in the cache entry, all such old headers MUST be replaced.

Section 13.6:

> If the entity-tag of the new response matches that of an existing entry, the new response SHOULD be used to update the header fields of the existing entry, and the result MUST be returned to the client.