]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: mux-h1: Handle read0 in rcv_pipe() only when data receipt was tried
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 22 Sep 2023 07:18:40 +0000 (09:18 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 4 Oct 2023 13:34:18 +0000 (15:34 +0200)
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.

src/mux_h1.c

index c602b68a38e29d198a4cdabd51a5824762ec380b..f1788de3c901ed522b56b90402098c2a6564297e 100644 (file)
@@ -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;