Re: Vary VS URI with an eye towards caching

> The short version: We want to add a Vary: header.

Okay, so what's the syntax?

> The long version:  (Anyone who reads this deserves a virtual cookie.  God
> this is long.)
> 
> 1) Background
> The latest draft of HTTP 1.1 added a new improved URI header that allowed
> server to list the variants of a particular resource it had available on
> it's system.  This new URI header also included some meta-information about
> each variant: just enough for those who see the response to duplicate the
> content negotiation process at a later date, and come up with the same
> result the server would on any request.  Let's call this "transparent
> negotiation" because all the information needed by the proxy to negotiate is
> transparent/known, both data and algorithm.

Ah, good wording.

> 2) Benefit
> By giving the power to a proxy to do it's own content negotiation, the proxy
> can avoid contacting the server on every request to have that server do the
> content negotiation for the request.  The proxy has all the information it
> needs: the variant picking algorithm (from the spec), the Accept: headers to
> represent the UAs desires, and the server's list of variants w/
> meta-information and qs values.  It can compute variants from cache and
> serve them up (or send the request through if it doesn't have the variant,
> and then the proxy can add the  variant to it's servable/cachable pool).

Ummm, I think you are missing something here.  The URI header's principal
purpose is to inform *the user* about the availability of those variants.
In fact, the user agent could present it as a menu item, or one of the
multiple choices to be selected when saving to a hotlist, or to perform
instant reactive negotiation if the user agent already knows that the user
some other format or language.  It's use for negotiation is actually a
secondary purpose, and thus a free benefit.

> 3) Problem
> Larry Manister pointed out that many servers would not want to list all
> possible variants.  A WWW image server might be able to convert to 200
> different file formats on the fly.  In this case the URI: picking scheme
> wouldn't work for proxies ability because of lack of data.  Other WWW
> servers might want to send different variants based on User Agent: headers,
> or Cookie: headers, or whatever.  In this case the URI: picking scheme
> wouldn't work for proxies ability because of lack of the right algorithm.  A
> proxy has to know about either one of these cases to be aware that it must
> contact the server on every subsequent request (to let that server do the
> negotiation).

Yes, it is not sufficient.

> 4) Soution
> Add back in the Vary: header. 

Ummm, you mean just add it -- before it was just a poorly defined parameter
of the URI header field.

> This is the server's way of saying to the
> proxy either 1) "I'm not telling you all the data, it's too much of a burden
> to me" or "I have my own variant-picking algorithm."  When the server sends
> a Vary: it is also effectively saying "You must contact me on each request
> to let me choose the variant."  Let's call negotiating via a Vary: scheme
> "opaque negotiation" because the proxy doesn't know everything.  Contacting
> the origin server when faced with lack of data or algorithm is unavoidable,
> but what would be worse would be if the proxy could not even cache responses
> because it had no way of verifying it's cached item was the right variant
> response.

That's not exactly true.  The cache may have chosen to save the request
header fields which are (hopefully) named by the Vary field, and thus can
indeed reuse the response if the subsequent request has the same values
for those fields.  For the reasons you stated earlier, this should only
be an option.

> 4) [okay]
> 
> 5) Other proposals:
> Koen Holtman introduced a "Send-No-Body-For:" header for the purpose of
> negotiation on URI headers, but he was under the influence of User-Agent
> negotiation which I contend can't be easily done under the
> transparent-proxy-has-all-data-and- algorithms-URI scheme.  It should be
> done under the Vary: scheme.  As he intended it to work under some URI
> scheme, he sought "Send-No-Body-For: URL".  Under my thoughts on transparent
> negotiation, one would never make a request with "Send-No-Body-For: URL".
> It would be redundant, if the proxy had that variant, it would be serving
> it.  Under transparent negotiation, the proxy knows that variant is
> servable, it doesn't need approval from the origin server.

Speaking theoretically....

   If all negotiated resources were required to have a Content-ID which
   is unique for each possible entity, then it would still be useful to
   be able to say "send me a 304 response if any of the following IDs
   would be returned in response to this request".  This would require
   the ability to say:

      Unless-ID: <id1@home>, <id2@home>

   which is yet another variation on preconditions.  To generalize:

      Condition: 304 if {or {eq {Content-ID "<id1@home>"}
                                {Content-ID "<id2@home>"}}}

   The 304 response would include the Content-ID for what would have
   been sent if it were a 200 response, and thus the cache can determine
   which one should be delivered to the user agent.

This would still have the potential to save bandwidth and transfer time,
even with the Vary header field.

   BTW, in case you were wondering, Jeff's cache-validator is equivalent to
   the above on a normal GET-IMS if Content-ID is the validator, and
   equivalent to

      Condition: 200 if {ne {Content-ID "<id1@home>"}}

   for a partial GET (i.e., with the Range header field).

   Likewise, Ari's proposed Unless-Modified-Since header field is equivalent to

      Condition: 200 if {or {ne {Last-Modified "Fri, 05 Jan 1996 20:44:01 GMT"}
                            {ne {Content-Length 3600}}}

   Could someone please explain to me why implementing three different
   and non-extensible precondition syntaxes is preferable to implementing
   a single, extensible syntax?

Oh, in answer to an earlier musing by Dan, the reason I switched to
a Lisp-like syntax is because it is impossible to provide a list of
values for a single parameter under the ;parameter="" syntax of MIME
media types.  Personally, I hate Lisp myself, but that doesn't prevent
me from seeing what it is good at doing.

.....Roy

Received on Wednesday, 10 January 1996 14:57:23 UTC