From: Christopher Faulet Date: Fri, 22 Sep 2023 07:18:40 +0000 (+0200) Subject: BUG/MINOR: mux-h1: Handle read0 in rcv_pipe() only when data receipt was tried X-Git-Tag: v2.9-dev7~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=331241b084a336b754ac2317f3d8a237953131df;p=thirdparty%2Fhaproxy.git BUG/MINOR: mux-h1: Handle read0 in rcv_pipe() only when data receipt was tried In rcv_pipe() callback we must be careful to not report the end of stream too early because some data may still be present in the input buffer. If we report a EOS here, this will block the subsequent call to rcv_buf() to process remaining input data. This only happens when we try a last rcv_pipe() when the xfer length is unknown and all data was already received in the input buffer. Concretely this happens with a payload larger than a buffer but lower than 2 buffers. This patch must be backported as far as 2.7. --- diff --git a/src/mux_h1.c b/src/mux_h1.c index c602b68a38..f1788de3c9 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -4284,7 +4284,7 @@ static int h1_rcv_pipe(struct stconn *sc, struct pipe *pipe, unsigned int count) se_fl_set(h1s->sd, SE_FL_ERROR); TRACE_ERROR("too much payload, more than announced", H1_EV_RX_DATA|H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s); - goto end; + goto out; } h1m->curr_len -= ret; if (!h1m->curr_len) { @@ -4308,7 +4308,7 @@ static int h1_rcv_pipe(struct stconn *sc, struct pipe *pipe, unsigned int count) HA_ATOMIC_ADD(&h1c->px_counters->spliced_bytes_in, ret); } - end: + out: if (conn_xprt_read0_pending(h1c->conn)) { se_fl_set(h1s->sd, SE_FL_EOS); TRACE_STATE("report EOS to SE", H1_EV_STRM_RECV, h1c->conn, h1s); @@ -4326,6 +4326,7 @@ static int h1_rcv_pipe(struct stconn *sc, struct pipe *pipe, unsigned int count) h1c->flags = (h1c->flags & ~H1C_F_WANT_SPLICE) | H1C_F_EOS; TRACE_STATE("Allow xprt rcv_buf on read0", H1_EV_STRM_RECV, h1c->conn, h1s); } + end: if (h1c->conn->flags & CO_FL_ERROR) { se_fl_set(h1s->sd, SE_FL_ERROR); h1c->flags = (h1c->flags & ~H1C_F_WANT_SPLICE) | H1C_F_ERROR;