Subject: does no-store request invalidate?

From: Alex Rousskov <[email-masked]>
Date: Tue, 26 Jul 2005 10:53:03 -0600

Hello,

	Responses to HTTP requests with "Cache-control: no-store" are not
cachable. Recently, we came across a cache that does not cache responses
to no-store requests but also does not invalidate an older cached entity
with the same URL. When future requests stop using no-store, the old
cached entity is served.

For example, the following happens in our test case:

  1. Client requests an entity A without using no-store.
  2. Cache proxies the transaction and caches the response (entity A).

  3. Client requests the same entity A using "Cache-control: no-store".
  4. Cache proxies the transaction and does NOT cache the response.

  5. Client requests the same entity A again, without using no-store.
  6. Cache serves the "old" entity A cached in step #2 above.

Does the cache violate the intent of RFC 2616 in step #6? If yes, should
that intent be made explicit (I cannot find any explicit rules
prohibiting the above behavior)? 

If no, should the cache check that response in step #4 does not indicate
that cached entity A is stale? I cannot find explicit rules requiring
that, but we do have similar rules about 304 and HEAD responses
invalidating older cached entities.

Thank you,

Alex.

---

From: Robert Olofsson <[email-masked]>
Date: Tue, 26 Jul 2005 20:52:05 +0200

>prohibiting the above behavior)? 
I would say that it violates the rfc:
"If sent in a request, a cache MUST NOT store any part of either this
 request or any response to it"

Every request passing through a proxy have a few different possible
responses:
1) No response at all (proxy crashes), hopefully this does not happen.
2) Use a cached response.
3) Get response from real server/chained proxy.

Depending on Cache-Control headers responses from 2 might
be filtered (returning 304) and/or not used (when no-cache).

My interpretation of a no-store header is that I have to remove
alternative 2. Remove meaning delete the response from the
cache in this case.

Of course my interpretation of "any" might be wrong.
Especially if one consider the case of a server generated no-store:
"If sent in a response, a cache MUST NOT store any part of either this
 response or the request that elicited it."

Which seems to say that it is ok for a cache to keep any old response...

Test case:

1: Client requests an entity A 
2: Proxy caches response and serves it
3: Client request the same entity A with "Cache-control: no-cache"
4: Server responds with "Cache-Control: no-store"
5: Client requests the same entity A again
6: Proxy serves the old cache entity from step #2.  

Hmm, interesting. I would sure like to hear from someone that knows
how it ought to be.

/robo

---

From: Alex Rousskov <[email-masked]>
Date: Tue, 26 Jul 2005 14:15:04 -0600

>  request or any response to it"

The "any response TO IT" clause does not include responses to previous
or future requests. It seems to apply to a response received during the
no-store transaction in question.

> alternative 2. Remove meaning delete the response from the

I agree that alternative 2 (use cached response) is not allowed.
Unfortunately, I cannot see any requirement that implies that not using
a cached response means deleting that response from the cache.

> Which seems to say that it is ok for a cache to keep any old response...

Yes, this is a similar case, but here we can at least argue that the two
responses are different (one has no-store and the other one does not)
and so the old one has to be deleted to match the server info (even
though there seem to be no explicit requirement about that). In my
original case, the server responses may be identical (but do not have to
be).

Regards,

Alex.

---

From: Mark Nottingham <[email-masked]>
Date: Wed, 27 Jul 2005 12:56:02 -0700

My reading is that a no-store request header applies to that request  
only; i.e., it's control information specific to that client, at the  
time it made that request. Otherwise, a malicious client could  
effectively invalidate any cache entry it chose to.

Cheers,

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

---

From: Alex Rousskov <[email-masked]>
Date: Wed, 27 Jul 2005 14:13:35 -0600

On Wed, 2005-07-27 at 12:56 -0700, Mark Nottingham wrote:
> time it made that request. 

That is my reading as well, but I wonder whether that was the intent. It
seems odd that the protocol talks at length about validating cached
entries using fresh 304 and HEAD responses but does not mention similar
validation using no-store responses.

> Otherwise, a malicious client could  

... which it can often do without no-store (using a DELETE method, for
example):

   "If the [DELETE] request passes through a cache and the Request-URI
identifies one or more currently cached entities, those entries SHOULD
be treated as stale."

Alex.

---

From: Jeffrey Mogul <[email-masked]>
Date: Wed, 27 Jul 2005 14:38:47 -0700

I guess I share a big part of the responsibility for not getting
this issue clear in RFC2616.  To be honest, it's an unusual case;
all of the other cache-control directives are there to allow the
clients and servers to manipulate the externally-visible behavior
of a cache, and so it should be possible to work out the desired
behavior from the basic principles in section 13, especially these:

   Requirements for performance, availability, and disconnected
   operation require us to be able to relax the goal of semantic
   transparency. The HTTP/1.1 protocol allows origin servers, caches,
   and clients to explicitly reduce transparency when necessary.
   However, because non-transparent operation may confuse non-expert
   users, and might be incompatible with certain server applications
   (such as those for ordering merchandise), the protocol requires that
   transparency be relaxed

      - only by an explicit protocol-level request when relaxed by
        client or origin server

      - only with an explicit warning to the end user when relaxed by
        cache or client

However, no-store really has nothing to do with externally-visible
behavior, since there are other ways to get exactly the same
behavior (e.g., "cache-control: must-revalidate" in a response,
or "cache-control: no-cache" in a request).  The only reason
no-store was added to the protocol was to avoid "accidental
releases of information via unanticipated accesses to cache
data structures".  So it is really hard to figure out what it
is supposed to do for externally-visible behavior, since the
"intent" was that it would not be used to influence behavior!

Note that 13.1.1 (Cache Correctness) says

   A correct cache MUST respond to a request with the most up-to-date
   response held by the cache that is appropriate to the request (see
   sections 13.2.5, 13.2.6, and 13.12) which meets one of the following
   conditions:    

I think the "principle of least astonishment" (as Dave Mills would
say) is that step #6 in Alex's example does not match an obvious
interpretation of "most up-to-date response ... that is appropriate
to the request", but on the other hand, I don't see anything in
RFC2616 that specifically prohibits step #6.

Overall, I would say that anyone who relies on externally-visible
behavior that is a specific side-effect of using no-store in
a request is making a mistake.   A client or server implementor
should use other cache-control directives to fully define the
visible behavior of caches.

This leaves open the denial-of-caching issue that Mark Nottingham
raised (i.e. an issue for implementors of shared proxy caches).
I think one has to make a judgement call here about whether there
is a significant risk of clients removing cache entries for each
other, and balance that against the possibility that a client
could end up with an out-of-date cached response (which seems
to me to be more likely to result in serious consequences).

One should note that the "editorial group" that ultimately was
responsible for the text of RFC2616 made an explicit decision
not to try to anticipate and define behavior for every possible
combination of HTTP request and response elements.  In the case
that Alex raises, we probably lacked any "intent" at all.

-Jeff