Subject: Updating Entity Headers with 304s

From: Mark Nottingham <[email-masked]>
Date: Sat, 10 Feb 2007 16:41:04 +1100

10.3.5 says:

[[[
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.
]]]

That applies to the responses; it doesn't specify the behaviour of  
the cache when it receives such
responses.

it goes on to say

[[[
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.
]]]

and 13.5.3 goes on

[[[
The end-to-end headers stored in the cache entry are used for the  
constructed response, except that
[...]
       - 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.

In other words, the set of end-to-end headers received in the  
incoming response overrides all
corresponding end-to-end headers stored with the cache entry (except  
for stored Warning headers with
warn-code 1xx, which are deleted even if not overridden).
]]]

My strict reading of this is that the intent was to discourage  
updating entity headers with 304 responses, but if it were to happen,  
to make sure that it was done correctly (i.e., all together).

However, an implementer has interpreted the stated intent to mean  
that a cache should not allow entity headers to be updated by 304s.  
See: <http://issues.apache.org/bugzilla/show_bug.cgi?id=39647>.

There's a certain logic to both positions. Does anyone recall what  
the original intent was, and do we need a clarification here?

--
Mark Nottingham     http://www.mnot.net/

---

From: "Roy T. Fielding" <[email-masked]>
Date: Sat, 10 Feb 2007 12:30:09 -0800

> See: <http://issues.apache.org/bugzilla/show_bug.cgi?id=39647>.

The problem report is about the internal handling of a gateway response
that doesn't even use HTTP, so the text in the spec doesn't apply
except in the most abstract sense.

> the original intent was, and do we need a clarification here?

The intent is that the refreshed cache entry matches what would have  
been
sent in a 200 response.  Anything else would be considered an error.

In this case, the back-end has an error that is generating a text/html
response intermittently, and the unset that Ruediger added is just  
making
sure that the cache filter doesn't interpret the response incorrectly.
The right solution is to just fix mod_jk, and I think that was done as
well, since masking a back-end error is a bad idea.  mod_jk does not use
HTTP, so the specification does not apply.

....Roy

---

From: Henrik Nordstrom <[email-masked]>
Date: Sat, 10 Feb 2007 22:14:50 +0100

> See: <http://issues.apache.org/bugzilla/show_bug.cgi?id=39647>.

Well.. that's clearly not what the RFC means, but at the same time
updating some things doesn't make much sense like Content-Length and
maybe Content-Type.

There is one quite relevant paragraph which could apply here. 10.3.5
304, second last paragraph

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

now, content-type doesn't really identify the entity in terms of HTTP,
but a change in content-type is pretty good indication that something
important has changed and that the cached entity probably no longer is
valid..

> the original intent was, and do we need a clarification here?

I don't think clarification is needed unless we want to clarify more in
detail when a 304 should be discarded by the 10.3.5 paragraph above.

We are here in the area of how caches should behave when receiving
non-compliant responses. In this area cache implementers have three
choices

  a) Trust the response and blame the non-compliant origin server if
someone complains about the result.

  b) Discard the response and try again without the conditional as per
10.3.5 paragraph above.

  c) Try to make something which makes sense out of the non-compliant
response.

I think 'b' is what the RFC wants implementers to choose, but I also
think most will select 'c' for efficiency reasons and not sure that's a
bad thing..

Regards
Henrik

---

From: Mark Nottingham <[email-masked]>
Date: Sun, 11 Feb 2007 08:35:52 +1100

Hi Roy,

Ah, I'm not familiar with mod_jk; does it have its own protocol to  
communicate from the front-end to the back-end?

> Here's the configuration:  Frontend reverse caching proxy server  
> running httpd
> 2.2.2, prefork mpm.  The backend web server is httpd 1.3.36 with  
> mod_jk 1.2.15.

Also, this fix was sold in the 2.2.2 notes as a change/fix to  
mod_cache (which is what piqued my interest in the first place);

>   *) mod_cache: Do not overwrite the Content-Type in the cache, for
>      successfully revalidated cached objects. PR 39647.

Are you saying that mod_cache, when used with a HTTP back-end, *will*  
replace the Content-Type if a 304 contains a new one?

On 2007/02/11, at 7:30 AM, Roy T. Fielding wrote:

>> that a cache should not allow entity headers to be updated by  
>> 304s. See: <http://issues.apache.org/bugzilla/show_bug.cgi?id=39647>.
>
> The intent is that the refreshed cache entry matches what would  
> have been

---

From: Mark Nottingham <[email-masked]>
Date: Sun, 11 Feb 2007 08:45:22 +1100

> think most will select 'c' for efficiency reasons and not sure  

+1

The reason I wondered whether a clarification was necessary was  
because if an implementer reads 13.5.3, there's not a lot of wiggle  
room for this; it places a MUST on caches, whereas the requirement  
here (i.e. what to do with non-conformant responses) is only implied.