]> git.kaiwu.me - haproxy.git/commit
BUG/MEDIUM: h1: build a missing Host header from the authority of the URI
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 16 Oct 2026 09:23:19 +0000 (11:23 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 16 Oct 2026 17:10:27 +0000 (19:10 +0200)
commitfcbdb34e38708871c7a1aa2758ad6a1dc34a1d41
tree2962a652c0a1ac323e5a2891a07564e82424f875
parentfb53e904b836f51148e85244878069ef2acc44da
BUG/MEDIUM: h1: build a missing Host header from the authority of the URI

An HTTP/1 request without a Host header could be accepted as-is, while
host-based rules require a host to apply to the real target. This concerns
the two request-target forms that carry an authority:

  - the authority-form, used by CONNECT requests (RFC9112#3.2.3), where the
    authority is the request target and must not contain userinfo, path or
    query;

  - the absolute-form (RFC9112#3.2.2), where the authority of the absolute
    URI is what an H1 server must use as host, and what is sent as
    :authority to H2/H3 servers.

The H1 parser only checked the consistency between the URI's authority and
the Host header when the latter was present. Now, when there is no Host
header, one is added with the authority's value (userinfo removed), so that
host-based rules apply to the real target and H1 servers receive a Host
header matching the request target, as RFC9112#3.2 requires for
HTTP/1.1. For the authority-form, it is only added once the authority was
validated, and for both forms it is not added when the authority contains
chars that are forbidden in the Host header, which is only possible when
unsafe violations are accepted.

A default port is removed from the synthesized value, like it is done when a
Host header with a default port is present, so that the rules see the same
value with and without the Host header: for the authority-form, both ports
80 and 443 are considered default since there is no scheme (CONNECT), and
for the absolute-form the default port depends on the URI's scheme (80 for
http, 443 for https).

The Host header is inserted before the terminating empty header, so that it
is accounted for in the header list.

The reg-tests h1_absolute_uri_no_host and h1_connect_no_host_no_body cover
this.

This is long-standing and should be backported to all supported versions.
reg-tests/http-messaging/h1_absolute_uri_no_host.vtc [new file with mode: 0644]
reg-tests/http-messaging/h1_connect_no_host_no_body.vtc [new file with mode: 0644]
src/h1.c