"Expires:" vs. "Cache-control: max-age"

Regarding

  ``When the "max-age" directive is present in a cached response
  message, a caching intermediary must refresh the message if it is
  older than the age value given (in seconds) at the time of a new
  request for that resource.  The behavior should be equivalent to what
  would occur if the request had included the max-age directive.''

Shel writes:

    [If] a response contains cache-control:max-age=n, *subsequent*
    requests for that resource will behave as if they contained
    cache-control:max-age=n.  Thus the "clock begins ticking" on the
    cached resource at the time it is sent by the origin server. In
    other words, after Date: + n seconds, any new requests for the
    resource cause the cache to "refresh" (i.e. validate) that
    resource. If this interpretation is correct, then including
    cache-control:max-age=n in a response is exactly equivalent to
    including Expires: <now + n seconds> in the response.  Since this
    functionality appears to be redundant, I am forced to conclude that
    this interpretation, too, must not be what Roy intended.

I don't think Roy's meaning was unclear, because Roy views
"Cache-control: max-age" as a replacement for "Expires:"
(but we cannot eliminate Expires: from HTTP/1.x, for compatibility
reasons).

Roy managed to confuse me with:
   Max-age needs to override expires simply because we don't want
   servers to have to calculate the HTTP-date in expires if they
   understand max-age.
until I decided that "calculate" means "format" and "understand"
means "able to generate" if "servers" mean "origin servers",
but if "servers" mean "proxy servers" then the translations are
"parse" and "accept".

However, I don't quite buy Roy's rationale.  First of all, I am
almost ready to agree with Koen that giving an origin server the
ability to set different expirations based on the protocol version
of the cache, while kludgey, might be exactly what we need to be
able to work around the existing misconfigured caches.  In other
words, "Cache-control: max-age=X" is a good thing to have, but
for reasons in addition to what Roy has said.

Second, given the number of HTTP/1.0 caches out there, and given
that if these caches do not see Expires:, they pick an expiration
time heuristically (with a relatively large upper bound), I think
HTTP/1.1 servers with significant expiration constraints are going
to have to send explicit Expires: headers.  I.e., in order to
not have things cached for unacceptably long periods by HTTP/1.0
caches, origin servers will be sending Expires: whether or not
they send Cache-control: max-age=N.

I would like to propose this as our consensus:

	(1) Origin servers may send either or both of
		Expires:
	and
		Cache-control: max-age=N
	on responses

	(2) If both are sent, an HTTP/1.1 implementation SHOULD
	obey the Cache-control: max-age=N directive.

	(2b) but HTTP/1.0 implementations will ignore it, so servers
	SHOULD NOT depend on a cache obeying that directive.

I think we also might want to change the last sentence of Roy's
paragraph from
    The behavior should be equivalent to what
    would occur if the request had included the max-age directive.
to
    The behavior should be equivalent to what would occur if this
    response had an Expires: field specifying the same number of
    seconds since its Date: field, but overrides other Expires:
    value.

Disagreements? speak up now!

Separately, I would like to suggest that there is no good reason
(not even tradition, since we don't have one here) to use the
same "max-age" token in both requests and replies.  It just seems
to confuse people.  How about using
	Cache-control: fresh-life=NNN
on responses, and
	Cache-control: max-age=NNN
on requests?

-Jeff

Received on Monday, 19 February 1996 22:29:15 UTC