]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: h3: increment unknown request payload length
authorAndrea Cocito <andrea@cocito.eu>
Tue, 23 Jun 2026 09:44:39 +0000 (11:44 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 24 Jun 2026 06:53:00 +0000 (08:53 +0200)
When an HTTP/3 request carries DATA frames without a Content-Length
header, the H3 mux updates the stream endpoint known input payload
length so the stream layer can pass this information to the output mux.

The current code assigns h3s->data_len to qcs->sd->kip. However,
h3s->data_len is cumulative, while sedesc->kip is an incremental value:
it is moved to the opposite side as kop and then consumed by the output
mux. With multiple DATA frames, the H1 output mux may therefore announce
chunk sizes based on the total body length received so far instead of
the next payload length.

For an H3-to-H1 request without Content-Length, this can produce
malformed chunked encoding on the backend connection. A backend HTTP/1
parser may then reject the request, and HAProxy can return a 500 to the
client.

Fix this by incrementing qcs->sd->kip with the current DATA frame length
instead of assigning the cumulative body length.

This should be backported up to 3.3.

src/h3.c

index f3c18bfe34347200611b09e0c1e966e5d0a33cee..fddc845f91c9cef78e1fde783ad801750c34b3ea 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -1937,7 +1937,7 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
                                }
                                else if (qcs->sd) {
                                        /* content-length not present, update estimated payload length. */
-                                       qcs->sd->kip = h3s->data_len;
+                                       qcs->sd->kip += flen;
                                }
                        }