Comment 5 for bug 2039251

Revision history for this message
Colin Watson (cjwatson) wrote :

I'm not sure why behaviour changed recently, but I think this may be a lazr.restful bug. RFC 2616 says:

10.3.5 304 Not Modified
[...]
   The response MUST include the following header fields:

      - Date, unless [...]

      - ETag and/or Content-Location, if the header would have been sent
        in a 200 response to the same request

      - Expires, Cache-Control, and/or Vary, if the field-value might
        differ from that sent in any previous response for the same
        variant

   If the conditional GET used a strong cache validator (see section
   13.3.3), the response SHOULD NOT include other entity-headers.
   Otherwise (i.e., the conditional GET used a weak validator), the
   response MUST NOT include other entity-headers; this prevents
   inconsistencies between cached entity-bodies and updated headers.

   If a 304 response indicates an entity not currently cached, then the
   cache MUST disregard the response and repeat the request without the
   conditional.

   If a cache uses a received 304 response to update a cache entry, the
   cache MUST update the entry to reflect any new field values given in
   the response.

In this case a strong cache validator is being used, but we're still violating the SHOULD NOT by sending a bunch of other response headers, including "Content-Length: 0".

RFC 7232 says:

4.1. 304 Not Modified
[...]

   The server generating a 304 response MUST generate any of the
   following header fields that would have been sent in a 200 (OK)
   response to the same request: Cache-Control, Content-Location, Date,
   ETag, Expires, and Vary.

   Since the goal of a 304 response is to minimize information transfer
   when the recipient already has one or more cached representations, a
   sender SHOULD NOT generate representation metadata other than the
   above listed fields unless said metadata exists for the purpose of
   guiding cache updates (e.g., Last-Modified might be useful if the
   response does not have an ETag field).

And RFC 7234 says, for the case where a cache receives a 304 response and already has a stored 200 response for the same cache key:

   If a stored response is selected for update, the cache MUST:

   o delete any Warning header fields in the stored response with
      warn-code 1xx (see Section 5.5);

   o retain any Warning header fields in the stored response with
      warn-code 2xx; and,

   o use other header fields provided in the 304 (Not Modified)
      response to replace all instances of the corresponding header
      fields in the stored response.

So it would appear that lazr.restful needs to ensure that any other response headers are removed when it generates a 304 (in `lazr.restful._resource.HTTPResource.handleConditionalGET`).