From: Christopher Faulet Date: Wed, 14 Oct 2026 19:27:24 +0000 (+0200) Subject: BUG/MEDIUM: mux-h1: Don't close the connection on a payload parsing error X-Git-Tag: v3.5-dev10~161 X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=30ca6e013e13895a05ca227f16379385e4e0dc5f;p=haproxy.git BUG/MEDIUM: mux-h1: Don't close the connection on a payload parsing error When a parsing error is reported by the H1 mux on the payload of a message (chunked encoding, content-length, ...), after the stream was created, the SE_FL_ERROR flag was set on the stream endpoint. This flag reports a fatal error and the stream closes the client connection before the HTTP analyzers can build and send the 400 response from HTX_FL_PARSING_ERROR. In the end, no error is sent to the client and it only sees a connection close. Before the commit 4ccca7e ("BUG/MINOR: mux-h1: Only report a SE error on demux error"), SE_FL_EOI/SE_FL_EOS were reported and the analyzers had a chance to send the error response before the connection closure. But, at that time, the error was not reported to the termination events. Now, the error is reported as EOI when the stream connector is still attached, and the error itself is reported by the mux via the termination events and consumed by the analyzers via the htx flags. SE_FL_ERROR is only reported when there is no stream connector attached to the h1s, because it means the mux owns the error and will handle it itself. No configuration is impacted because the connection is always closed after such an error. This should be backported as far as 3.2. --- diff --git a/src/mux_h1.c b/src/mux_h1.c index 0b0911450..7e6cf2bf2 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -2456,8 +2456,16 @@ static size_t h1_process_demux(struct h1c *h1c, struct buffer *buf, size_t count err: htx_to_buf(htx, buf); - se_fl_set(h1s->sd, SE_FL_ERROR); - TRACE_DEVEL("leaving on error", H1_EV_RX_DATA|H1_EV_STRM_ERR, h1c->conn, h1s); + if (h1c->state < H1_CS_RUNNING) { + /* The mux owns the error: report it to release the SE. */ + se_fl_set(h1s->sd, SE_FL_ERROR); + TRACE_DEVEL("leaving on error, SE released", H1_EV_RX_DATA|H1_EV_STRM_ERR, h1c->conn, h1s); + } + else { + /* The app layer owns the error via htx flags: only report EOI. */ + se_fl_set(h1s->sd, SE_FL_EOI); + TRACE_DEVEL("leaving on error, EOI reported to the SE", H1_EV_RX_DATA|H1_EV_STRM_ERR, h1c->conn, h1s); + } return 0; }