]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: h3: don't insert more than one Host header
authorWilly Tarreau <w@1wt.eu>
Fri, 16 May 2025 12:51:13 +0000 (14:51 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 16 May 2025 13:13:17 +0000 (15:13 +0200)
Let's make sure we drop extraneous Host headers after having compared
them. That also works when :authority was already present. This way,
like for h1 and h2, we only keep one copy of it, while still making
sure that Host matches :authority. This way, if a request has both
:authority and Host, only one Host header will be produced (from
:authority). Note that due to the different organization of the code
and wording along the evolving RFCs, here we also check that all
duplicates are identical, while h2 ignores them as per RFC7540, but
this will be re-unified later.

This should be backported to stable versions, at least 2.8, though
thanks to the existing checks the impact is probably nul.

src/h3.c

index 680589a6548118479694fc8571b033ccf2aea0fe..d03c963c5e2f6d510481d130a903c8e1ca033d2f 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -861,12 +861,20 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
                }
 
                if (isteq(list[hdr_idx].n, ist("host"))) {
+                       struct ist prev_auth = authority;
+
                        if (h3_set_authority(qcs, &authority, list[hdr_idx].v)) {
                                h3s->err = H3_ERR_MESSAGE_ERROR;
                                qcc_report_glitch(h3c->qcc, 1);
                                len = -1;
                                goto out;
                        }
+
+                       if (isttest(prev_auth)) {
+                               /* skip duplicate Host header */
+                               ++hdr_idx;
+                               continue;
+                       }
                }
                else if (isteq(list[hdr_idx].n, ist("cookie"))) {
                        http_cookie_register(list, hdr_idx, &cookie, &last_cookie);