From: Christopher Faulet Date: Mon, 1 Mar 2021 16:46:32 +0000 (+0100) Subject: BUG/MINOR: mux-h1: Immediately report H1C errors from h1_snd_buf() X-Git-Tag: v2.1.12~24 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=b61e152f6951be7f5b1125e83f07d662fb5b6038;p=haproxy-2.1.git BUG/MINOR: mux-h1: Immediately report H1C errors from h1_snd_buf() In case an H1 stream tries to send while on error occurred on its underlying H1 connection, we must report the error. The way the stream-interface is synchronously notified of the error. It seems to only be a problem on the 2.0. Probably because the scheduling has changed in upper versions. On the 2.0, it prevent the stream to be notified of errors, when for instance, a payload is found in a response to a HEAD request. Not always though. This patch must be backported as far as 2.0 because, on 2.0, it should fix the issue #1101. There is no upstream ID for this commit because on the 2.4, this fix already exists, it is part of non-backportable commit. (cherry picked from commit 4099f99004dbbc8a5c116f1024623bac0d723be4) Signed-off-by: Christopher Faulet (cherry picked from commit 25435eb38e2245bf15d86eb5aae1d6ebb4ea26b8) Signed-off-by: Christopher Faulet --- diff --git a/src/mux_h1.c b/src/mux_h1.c index 3b96ec9..3a6e5a5 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -2712,6 +2712,12 @@ static size_t h1_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t coun return 0; } + if (h1c->flags & H1C_F_CS_ERROR) { + cs->flags |= CS_FL_ERROR; + TRACE_DEVEL("H1 connection is in error, leaving in error", H1_EV_STRM_SEND|H1_EV_H1C_ERR|H1_EV_H1S_ERR|H1_EV_STRM_ERR, h1c->conn, h1s); + return 0; + } + while (count) { size_t ret = 0; @@ -2726,6 +2732,12 @@ static size_t h1_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t coun if ((h1c->wait_event.events & SUB_RETRY_SEND) || !h1_send(h1c)) break; } + + if (h1c->flags & H1C_F_CS_ERROR) { + TRACE_DEVEL("reporting error to the app-layer stream", H1_EV_STRM_SEND|H1_EV_H1S_ERR|H1_EV_STRM_ERR, h1c->conn, h1s); + cs->flags |= CS_FL_ERROR; + } + h1_refresh_timeout(h1c); TRACE_LEAVE(H1_EV_STRM_SEND, h1c->conn, h1s,, (size_t[]){total}); return total;