- From: Roy T. Fielding <fielding@gbiv.com>
- Date: Thu, 2 Sep 2021 10:47:58 -0700
- To: Willy Tarreau <w@1wt.eu>
- Cc: HTTP Working Group <ietf-http-wg@w3.org>, Martin Thomson <mt@lowentropy.net>
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