Re: Warning: header, need origin

Jeffrey Mogul:
>
>[...]
>
>My understanding was that the proper way for servers to use
>cookies was to send
>
>        Vary: Cookie
>
>in any response whose request depends on the Cookie: header.

No, the situation is a bit more complex.  Suppose we  have a shopping
site which uses
  customer="koen"
cookies to keep track of who the customer is.

First, in all responses with a set-cookie header, the server will send
along

  Cache-control: no-cache="set-cookie"

to ensure that intermediary caches will never send these headers to
other paties because the (rest of the) response is still fresh.

Now, for product pages in the shop, there is no dependence on the name
of the customer, so the server sends no special response headers at
all.  This allows product pages to be cached, which is the main goal
of the whole cookie exercise: these pages cannot be cached with the
current session-id-in-the-url hacks people use.

For the page showing me my customer name), the server does indeed send
  Vary: Cookie
as you thought.

For the page showing me my shopping basket, however, the server sends
  Vary: Cookie
  Cache-control: max-age=0
in order to get (conditional) GET requests _every time the page is
accessed_.  Thus, if I visit my shopping basket page, then put more
stuff in my shopping basket (by following links to CGI scripts in
product pages), and then re-request to my shopping basket page, the
server can send me the updated shopping basket.

So what we don't want is caches which are configured to give stale
responses instead of doing a conditional GETs when the max-age is
exceeded: this leads to the showing of the old basket, which is
unacceptable.

This is why to need to detect if you can indeed rely on caches not
returning stale responses.

Instead of `shopping basket page', by the way, you can also read `page
with a room in a MUD' or `page in a collaborative editing system'.
For such pages, the detecability need is even more urgent: the stale
shopping basket problem could in principle be solved by changing the
cookie every time the basket changes, but for pages that can also
change without the user doing something, this approach cannot be used,
and you must really rely on caches not returning stale responses.

>Note that if we can mandate that user-agent caches send
>        Cache-control: max-stale=NNNN
>then we can certainly mandate that all caches obey the Vary header.

I don't quite follow this logic.  Obeying the Vary header is much more
difficult to implement than the sending max-stale if you are not
transparent.

>One big problem with having clients send max-stale=NNN is that
>a multi-user cache would have to have an extremely odd interpretation
>of this.

I also don't quite follow this logic: I am not requiring another
implementation than the one already agreed on.  But if you think that
sending max-stale is too odd, the detectability requirements would
also be met by requiring that caches send

 Cache-control: nontransparent

if they are not following one or more of the rules for caching. 

>Consider the following sequence (assuming that we were to adopt your
>suggestion):
[...]
>                HTTP/1.1 200 OK
>                Expires: Thu, 02 Dec 1999 16:00:00 GMT
>                (etc.)

In your example, everything works fine without detectability, because
we are not dealing with a page for which the server always wants
conditional GETs.  

An example illustrating my point is:

     - user requests basket page
     - server sends basket page response 5APPLES with
         Vary: Cookie
         Cache-control: max-age=0
       the page says "your basket contains 5 apples".
     - user agent cache stores the 5APPLES response

     - (1 minute later) user adds 3 bananas to basket

     - (2 minutes later) user requests basket page again 
     - user agent cache was configured to `never check' if the
       response it not more than 5 minutes stale.  It thus considers
       the response 5APPLES to be fresh.  Thus, the cache can use the
       second rule the Vary header description (see (*) below) for
       being allowed to send 200 response from cache.  It thus sends
       the old 5APPLES response

     - user prints the 5APPLES basket page and presses `buy basket
       contents'.  Note that the server thinks the user has 5 apples
       and 3 bananas in the basket.

    -  (N hours later) 5 apples and 3 bananas are delivered to the
       user.

    -  User compares with printout, is unhappy, sues store, New York
       Times front page article, etc.


The bottom line is that all shopping baskets implemented without
cache-busting techniques will not work through non-transparent caches.

Therefore, if we don't make non-transparent caches detectable to the
origin server, interactive sites who are in a position to be sued will
keep using the cache busting techniques they use now.

If we _do_ make non-transparent caches detectable, interactive sites
will be able to ask users to make their caches transparent before
entering the store, and the store can be cache-friendly.


(*) Rule for serving fresh responses from varying resources, taken
    from Vary header descriptions:

 | Second, if a cache gets a request on a varying resource, it can
 | return to its client a cached, fresh 200 (OK) response which has
                                  ^^^^^
 | Vary or Alternates headers, provided that
 |
 |     - the Vary and Alternates headers of this fresh response
 |       specify that only request header fields are selecting
 |       parameters,
 |
 |     - the specified selecting request header fields of the current
 |       request match the specified selecting request header fields
 |       of a previous request on the resource relayed towards the
 |       origin server,
 |    
 |     - this previous request got a 200 (OK) or 3xx (Ppp Qqq)
 |       response which had the same cache validator in its CVal header
 |       as the cached, fresh 200 (OK) response.

[...]
>But this means that the origin server doesn't see the signal
>you are expecting to make the world safe for cookie deployment,
>and as far as I understand things, the Wrong Thing happens.

The point at which you check for non-transparency is when you return
the Set-Cookie header which sets the customer="koen" cookie.  Even
non-transparent caches will not send stale responses which include
Set-Cookie headers, because there is a 

  Cache-control: no-cache="set-cookie"

header in all responses with Set-Cookie headers.  This assumes that
the non-transparent cache _does_ look at the Cache-control:
no-cache="set-cookie" header, of course.  So there will be
detectability if you want it, even through caches that are themselves
non-transparent.

>Please explain what is wrong with this reasoning, if you are still
>convinced that the max-stale= mechanism is at all useful as a signal.

I hope the explanation above suffices.  If not, I can pull my text
about the legal and commercial necessity of detectability out of my
mail archive.

On a general philosophical/ethical level, I find that, if two parties
engage in a conversation supposedly according to a protocol, each of
the two has the right to know if the other is not playing by the
protocol rules.  Especially if the conversation according to the
protocol is about the goods delivered in a commercial transaction to
be done between the parties.

Your `Warning' header is for notification that a server is not playing
by the rules, my max-age is for notification that a client is not
playing by the rules.

None of the things I said above are really new.  We have had this same
discussion a few times before.

As I said, if you think a signal with max-stale= is strange, a

 Cache-control: nontransparent

header would also work, and may even be a bit easier to explain in
text.  This header would even be better if we want to allow other
kinds of nontransparancy in addition to a loosening of the freshness
rules.

>-Jeff

Koen.

Received on Saturday, 6 April 1996 23:33:08 UTC