Subject: Re: [Ietf-message-headers] Requesting provisional registration for AMP-Cache-Transform header

From: Mark Nottingham <[email-masked]>
Date: Tue, 9 Apr 2019 18:16:11 +1000

Hi Devin,

> On 29 Mar 2019, at 5:45 am, Devin Mullins <[email-masked]> wrote:
[snip]
> Apache:
> 	• Has a documented conneg algorithm
> 	• Supports q-values
> 	• It also supports server-side preference among multiple variants when the client expresses indifference. (see "quality-of-source" or "qs" on that page or this one). Potential downsides:
> 		• It appears this makes use of a "type map" format that is specific to Apache.
> 		• This seems incompatible with a mod_proxy setup, and that seems like an important use-case. (As one data point, AMP's canonical implementation of an exchange signer is meant to be used behind a revproxy. We could just suggest that frontends forward all requests to amppkg regardless of Accept, but that vastly limits its utility, as amppkg has not been optimized to serve user-facing traffic. Other implementations may experience similar problems; for instance, they may wish for an edge node to deliver cached content if possible, and may not wish to host AMP transformation on the edge.)
> 			• For instance, it is unclear if backends can return type maps, or they need to be retrieved as files by Apache.
> 			• Also, it would need to pass the negotiated media type on to the backend. For instance, say the client requests `Accept: application/signed-exchange;v=b3;amp="google;v=\"3\"";q=0.8, application/signed-exchange;v=b3;amp="google;v=\"1..2\""`. Then the backend needs to know that version 1..2 is being requested, not 3. It could recompute the negotiated media type, but that risks mismatch with what the frontend computed.

I'm not sure why you think it's incompatible with a mod_proxy setup; AIUI Apache properly generates Vary headers, and so should be cached and served correctly. Why would type maps need to be retrieved?

> nginx:
> 	• Doesn't support conneg natively.
> 	• Example configurations supporting it make use of regexes and scripts that parse Accept only approximately.
> 	• I couldn't find any that support negotiation on qvalues.

Yes. Maybe a more interesting question to ask would be "how many frameworks/languages have good content negotiation facilities"? Since you're requiring the server to process AMP-Cache-Transform, it seems like this could also be addressed by code server-side (especially since much HTML is not static). 

A few quick searches returned:
  * https://github.com/willdurand/Negotiation (PHP)
  * http://pecl.php.net/package/pecl_http (PHP)
  * http://www.ptlis.net/source/php/content-negotiation/ (PHP)
  * https://github.com/jchannon/negotiator (Go)
  * https://pypi.org/project/negotiator/ (Python)
  * https://pythonhosted.org/Flask-arrest/content-negotiation.html (Python)
  * https://api.rubyonrails.org/classes/ActionDispatch/Http/MimeNegotiation.html (Rails)

(Hmm, maybe we need a common test corpus for media range comparisons...)

[snip]

> The modified Accept header will be sent on most Googlebot requests, so in the extreme, it could negatively affect servers that e.g. don't parse Accept properly. (For a contrived example: `Accept: application/signed-exchange;v=b3;amp="ampwebplace;v=\"1\""` may trip the webp detector in this example, even if the server doesn't support AMP or signed exchanges.)
> 
> But excepting that, it's true that the effect is limited to sites wishing to adopt the new format. Still, our goal is to minimize the barrier to entry for web developers wishing to adopt it, within the technical constraints imposed by this space.

Sure, I get that. I'm just concerned that introducing yet another axis of negotiation is going to have unforeseen side effects (especially when its semantics are very similar to an existing one).

> It's also a one-off solution. I'm concerned that if every new format defines such a mechanism, we're going to be overcome by lots of slightly different ways of doing things. From a reverse proxy / CDN standpoint, it's better if we can reuse existing mechanisms that don't require special handling (some do not allow factoring additional request headers into the cache key easily).

Most do with Vary, but yes it's not great.

> I'd be interested for some detail on this. Off-hand, I see that Varnish supports customizing cache key, though that's where my knowledge on this ends. (I'm unable to find recent documentation on Squid's Vary support, after a few minutes' searching.)

FWIW, it seems to support it well:
  https://cache-tests.fyi/#vary

Cheers,

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