Re: Working Group Last Call: HTTP/2 revision

On Sep 1, 2021, at 6:05 AM, Willy Tarreau <w@1wt.eu> wrote:
> 
> On Wed, Sep 01, 2021 at 08:35:49AM +0200, Julian Reschke wrote:
>> To call "Host"
>> mandatoy is just confusing. Maybe the whole statement should be
>> simplified somewhat.
> 
> It's possible, nothing comes to my mind right now. The reality is
> that Host has become a second place for authority long ago but is
> weaker than authority... In an ideal world we'd say that an authority
> is mandatory and must be provided as :authority or Host (or both),
> preferably :authority. But with the split inherited from H1 and the
> need to pass H1 semantics to H2 it's not that easy.

Well, it could have been that easy, but that's water under the bridge.

I think the rationale was to be able to send a request across versions

     h1   h2   h1
   A -> B -> C -> D

and have both h1 requests look the same by preserving Host instead
of :authority. Is that right? Maybe the spec should explain it.

Personally, I would have preferred that Host be deleted in passing
and :authority be used consistently to generate Host only when
forwarding to HTTP/1.1.

HTTP/1.1 (sec 3.2.2) requires that a message to a proxy be in absolute
form:

   When making a request to a proxy, other than a CONNECT or server-wide
   OPTIONS request (as detailed below), a client MUST send the target
   URI in _absolute-form_ as the request-target.

and that a received Host be replaced with the :authority

   A client MUST send a Host header field in an HTTP/1.1 request even if
   the request-target is in the absolute-form, since this allows the
   Host information to be forwarded through ancient HTTP/1.0 proxies
   that might not have implemented Host.

   When a proxy receives a request with an absolute-form of request-
   target, the proxy MUST ignore the received Host header field (if any)
   and instead replace it with the host information of the request-
   target.  A proxy that forwards such a request MUST generate a new
   Host field value based on the received request-target rather than
   forward the received Host field value.

   When an origin server receives a request with an absolute-form of
   request-target, the origin server MUST ignore the received Host
   header field (if any) and instead use the host information of the
   request-target.  Note that if the request-target does not have an
   authority component, an empty Host header field will be sent in this
   case.

Note that it does not place those requirements on intermediaries,
in general, because gateways/CDNs are allowed/expected to modify
the request target when it is being forwarded. 

http2bis 8.3.1 says:

   Clients that generate HTTP/2 requests directly SHOULD use the
   :authority pseudo-header field instead of the Host header field.

   An intermediary that forwards a request to HTTP/2 MUST construct
   an :authority pseudo-header field using the authority information
   from the control data in the original request. If control data
   does not contain authority, an intermediary MUST NOT add an
   :authority pseudo-header field. Note that while the Host header
   field can determine a request target, it is not control data
   for this purpose; see Section 7.2 of [HTTP].

Martin, I find that last sentence confusing, as is the requirement
here on "intermediary" (which would include both proxy and gateway).
Why would a gateway be prevented from changing :authority? Or are you
making a distinction here between "forwarding" a request unchanged
versus satisfying a request by accessing an internal resource?

   Request targets for CONNECT or asterisk-form OPTIONS requests
   do not include authority.

   An intermediary that forwards from HTTP/2 can construct a Host
   header field by copying the value of the :authority pseudo-header
   field. This might be necessary if that version requires that Host
   be included in a request, as HTTP/1.1 does for some forms of
   request target (see Section 3.2 of [HTTP11]).

   An intermediary that forwards a request to HTTP/2 MUST retain
   any Host header field, even if an authority is part of control
   data.

   The value of the Host header field MUST be ignored if control
   data contains authority (that is, the :authority pseudo-header
   field is present).

When an HTTP/1.1 request is received in absolute form (i.e.,
with the equivalent of :authority supplied), we require above
that Host be ignored and replaced with the absolute authority.
The last paragraph above requires to ignore (without saying who
is being required), but it doesn't require that Host be replaced
when forwarded by a proxy.

I would have written that as

   A recipient MUST ignore the Host header field in a request
   that contains an :authority pseudo-header field. If an
   intermediary forwards such a request via HTTP/1.1 without
   changing the request target, the intermediary MUST send
   the :authority pseudo-header field value as the Host field
   in the forwarded request (replacing any existing Host field)
   to avoid potential vulnerabilities in HTTP routing.

Is that something we should add now?

....Roy

Received on Thursday, 2 September 2021 17:48:24 UTC