BUG/MEDIUM: mux-h1: Force close mode for bodyless message announcing a C-L

When dealing with EOH block, we must be sure to force the close mode for
message with no payload but annoncing a non-null content-length.

It is mainly an issue on the server side but it could be encountered on
client side too. Without this fix, a request can be switched to the DONE
state while the server is still expecting the payload. In an ideal world,
this case should not happen. But in conjunction with other bugs, it may lead
to a desynchro between haproxy and the server.

Now, when a non-null content-length is announced but we know we reached the
end of the message, we force the close mode. The only exception is for
bodyless responses (204s, 304s and responses to head requests).

Thanks to Martino Spagnuolo (r3verii) for his detailed report on this issue.

This patch must be backported to all stable version.
This commit is contained in:
Christopher Faulet 2026-04-22 16:55:00 +02:00
parent d12edebe4a
commit 7c4eda5b57

View File

@ -2864,6 +2864,13 @@ static size_t h1_make_eoh(struct h1s *h1s, struct h1m *h1m, struct htx *htx, siz
h1s->flags = (h1s->flags & ~H1S_F_WANT_MSK) | H1S_F_WANT_CLO;
TRACE_STATE("force close mode (T-E + HTTP/1.0)", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
}
else if ((h1m->flags & H1_MF_CLEN) && h1m->body_len != 0 &&
htx_is_unique_blk(htx, blk) && (htx->flags & HTX_FL_EOM) &&
(!(h1m->flags & H1_MF_RESP) || !(h1s->flags & H1S_F_BODYLESS_RESP))) {
/* C-L but no data for non-bodyless response or for a request: force close */
h1s->flags = (h1s->flags & ~H1S_F_WANT_MSK) | H1S_F_WANT_CLO;
TRACE_STATE("force close mode (C-L without data)", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
}
/* the conn_mode must be processed. So do it */
n = ist("connection");