- From: Roy T. Fielding <fielding@gbiv.com>
- Date: Wed, 26 Feb 2025 11:05:48 -0800
- To: last-call@ietf.org
- Cc: IETF-Announce <ietf-announce@ietf.org>, draft-ietf-httpbis-cache-groups@ietf.org, Francesca Palombini <francesca.palombini@ericsson.com>, httpbis-chairs@ietf.org, ietf-http-wg@w3.org, Tommy Pauly <tpauly@apple.com>
- Message-Id: <4282B150-F40F-47B6-B1F3-37DB3F4586D0@gbiv.com>
> On Feb 12, 2025, at 7:35 AM, The IESG <iesg-secretary@ietf.org> wrote: > > > The IESG has received a request from the HTTP WG (httpbis) to consider the > following document: - 'HTTP Cache Groups' > <draft-ietf-httpbis-cache-groups-03.txt> as Proposed Standard While doing a header field review I ran across the below requirements in sections 2 (Cache Groups) and 3 (Cache-Group-Invalidation). Implementations MUST support at least 128 groups in a field value, with up to at least 128 characters in each member. Note that generic limitations on HTTP field lengths may constrain the size of this field value in practice. Why would we want to require implementations to support that many? What is the protocol interoperability problem that this is trying to solve? I mean, literally, require that an implementation receive and process an HTTP header field with a 26 character field name, colon, space, 256 double quotes, 127 comma separators, and 16,384 identifying characters? For cache efficiency? The original motivation seems to be documented at https://github.com/httpwg/http-extensions/issues/2701 as the average of the documentation claims within existing similar implementations that use internal APIs and response bodies to communicate the group names. Except the issue also fails to count the syntax delimiters, so the requirement above actually exceeds all current implementations. To be clear, it's fine if someone does implement that much support. But why should the protocol require it as a minimum MUST? Why not let systems implement the protocol while only allowing 24 groups per message, or identifiers with no more than 64 characters? If a given CDN only allows a dozen identifiers per cache entry, why would a client need to parse more in a received response? If a client sends more than a sensible number of cache groups in a single message, why should the server be required to process them? Likewise, if a server receives a list of internally invalid group names (names aren't opaque to the origin) does it actually have to process them all or can it simply drop the client? IOW, what is the interop purpose of that requirement, and when is it applicable to a given HTTP message? For our CMS (Adobe Experience Manager with Edge Delivery Services), we have implemented this style of cache invalidation on several different CDNs (i.e., each with their own proprietary APIs: using surrogate keys on Fastly, cache tags on Cloudlfare, etc.). It has been a very effective strategy for deploying low-latency sites with push invalidation. I am pretty sure that we have never needed more than six concurrent keys/tags for any given resource. Four is the average. Cache groups are a scoping mechanism that are typically based on how content is generated or when it was released, so they tend to be values for "whole-site", "release-tag"", "back-end", and "this page", with only the latter being resource-specific. This is a controlled namespace, usually allocated by the origin and operated upon only by clients that have authenticated with that same origin. They don't need to support more identifiers than what they have already defined (and not yet invalidated). There is no benefit for legit clients to send more identifiers than are actually in use. Servers can choose to respond with a 431 if the number/size received seems unreasonable. "Implementations" that want to mint an exceptionally large number of groups with very long names can allocate their own resources to do so. Part of the problem here is that the requirement above assumes that "Implementations" means "a CDN"; more specifically, a CDN of global scale that expects to interop with any application built for existing globally-scaled CDNs. But such a requirement simply doesn't make sense for this protocol. We don't need all CDNs to be as large and capable as the very best. We only need them to be large enough for our application's needs. In any case, it should be clear that "Implementation" normally means a client or a server. If this is supposed to be a requirement only on CDNs (as a whole or on specific types), then it should say that. The protocol itself doesn't need a specific number. It only needs to define the syntax and explain how to respond when there are too many identifiers or an identifier that is too long. Let the market for this feature figure out what the minimums should be. In any case, somewhere in the spec should be a very loud statement that long identifiers increase the cost and latency between the origin and downstream caches (which typically strip these header fields before delivery to a user agent). Do CDNs need a common minimum for implementation? Maybe. I would make that a minimum of 32-character names and 16 groups per header field list. It may not sound like much, but that's more than enough to make the protocol useful. I'd recommend support for up to 64-char names (for 512-bit hex hashes), but have seen no need to implement that in practice. Using long names to implement a low-latency system is a spectacular foot-gun. = = = = As a separate issue, Section 3 (Cache-Group-Invalidation) has the requirement The Cache-Group-Invalidation header field MUST be ignored on responses to requests that have a safe method (e.g., GET; see Section 9.2.1 of [HTTP]). and doesn't explain why. My guess is that this requirement is misunderstanding the limitation on side-effects of safe methods. Invalidating a previously cached response is not a side-effect of the request; it's a statement by the origin. It isn't the method that has the side-effect. There might be other reasons to ignore it in responses to GET, but I don't know what they would be and the spec doesn't help. The reason why this is important is because the vast majority of communication between an origin and caches/CDNs currently takes place within cache-control (or CDN-specific fields) in 2xx/304 responses to GET requests. Having this mechanism be arbitrarily limited to POST or DELETE responses is effectively requiring something like an administrative form or API, in which case there should be a response body defining the list of what groups to invalidate, in a format defined by this spec, and we wouldn't need the Cache-Group-Invalidation header field. In practice, what I would want (and expect) is that the header field can be present in GET responses as an advisory note. IOW, tell the downstream that these identified groups of content can be marked as stale and thus can be evicted from resource-constrained caches (prior to evicting fresh content). Furthermore, if a recipient can trust the origin (like a CDN can trust its contract), then the recipient can be configured to invalidate the identified cache groups upon seeing any secured response with that field from the applicable origin, regardless of request method. Cheers, Roy T. Fielding Senior Principal Scientist, Adobe
Received on Wednesday, 26 February 2025 19:06:06 UTC