From af124360edda54168922d537344f9ee8dc84fa73 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 14 Feb 2023 10:48:02 +0100 Subject: [PATCH] BUG/MEDIUM: http-ana: Detect closed SC on opposite side during body forwarding During the payload forwarding, since the commit f2b02cfd9 ("MAJOR: http-ana: Review error handling during HTTP payload forwarding"), when an error occurred on one side, we don't rely anymore on a specific HTTP message state to detect it on the other side. However, nothing was added to detect the error. Thus, when this happens, a spinning loop may be experienced and an abort because of the watchdog. To fix the bug, we must detect the opposite side is closed by checking the opposite SC state. Concretly, in http_end_request() and http_end_response(), we wait for the other side iff the HTTP message state is lower to HTTP_MSG_DONE (the message is not finished) and the SC state is not SC_ST_CLO (the opposite side is not closed). In these function, we don't care if there was an error on the opposite side. We only take care to detect when we must stop waiting the other side. This patch should fix the issue #2042. No backport needed. --- src/http_ana.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/http_ana.c b/src/http_ana.c index 09c374ff9c..a4092a7abb 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -4229,9 +4229,10 @@ static void http_end_request(struct stream *s) */ chn->flags |= CF_NEVER_WAIT; - if (txn->rsp.msg_state < HTTP_MSG_DONE) { - /* The server has not finished to respond, so we - * don't want to move in order not to upset it. + if (txn->rsp.msg_state < HTTP_MSG_DONE && s->scb->state != SC_ST_CLO) { + /* The server has not finished to respond and the + * backend SC is not closed, so we don't want to move in + * order not to upset it. */ DBG_TRACE_DEVEL("waiting end of the response", STRM_EV_HTTP_ANA, s, txn); return; @@ -4338,7 +4339,7 @@ static void http_end_response(struct stream *s) */ /* channel_dont_read(chn); */ - if (txn->req.msg_state < HTTP_MSG_DONE) { + if (txn->req.msg_state < HTTP_MSG_DONE && s->scf->state != SC_ST_CLO) { /* The client seems to still be sending data, probably * because we got an error response during an upload. * We have the choice of either breaking the connection -- 2.39.5