]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: mux-h1: only accept the H2 preface on the first request
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 7 Oct 2026 09:53:15 +0000 (11:53 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 12 Oct 2026 13:46:18 +0000 (15:46 +0200)
The H1 to H2 upgrade via the H2 connection preface is only supported for the
first request of a connection. It is checked by testing the absence of
H1C_F_WAIT_NEXT_REQ, which is set on the H1 connection once a first
transaction is finished. But this flag is moved to the H1 stream
(H1S_F_NOT_FIRST) and removed from the connection as soon as a new H1 stream
is created, which happens when the beginning of the next request is
received. So when the preface of a second request is received in several
parts (e.g. "PRI " then the rest), the first part creates an embryonic H1
stream and clears the flag, and the upgrade is then accepted when the
complete preface is received. The connection is upgraded to H2 in the middle
of its life, while the end of the previous response may still be pending in
the output buffer (it is then lost).

Now the H1 stream's H1S_F_NOT_FIRST flag is also checked.

This was introduced by commit 39c7b6b09 ("MEDIUM: mux-h1: Add ST_READY
state for the H1 connections") in 2.4. It may be backported to all
stable versions.

src/mux_h1.c

index 0538088dd4682503a0a9de4c2323ef7525bdecc2..0b0911450cb23e7b70d1388dda45bd316ad68d0d 100644 (file)
@@ -4228,7 +4228,8 @@ static int h1_process(struct h1c * h1c)
                 */
                if (h1c->state != H1_CS_DRAINING &&
                    b_isteq(&h1c->ibuf, 0, b_data(&h1c->ibuf), ist(H2_CONN_PREFACE)) > 0) {
-                       if (!(h1c->flags & H1C_F_WAIT_NEXT_REQ) &&         /* First request */
+                       if (!(h1c->flags & H1C_F_WAIT_NEXT_REQ) &&         /* First request (the flag is */
+                           !(h1s && (h1s->flags & H1S_F_NOT_FIRST)) &&    /*   moved to the h1s once created) */
                            !(h1c->px->options2 & PR_O2_NO_H2_UPGRADE) &&  /* H2 upgrade supported by the proxy */
                            !(conn->mux->flags & MX_FL_NO_UPG)) {          /* the current mux supports upgrades */
                                h1c->flags |= H1C_F_UPG_H2C;