From b24260ec9449fca37d2507820bb11fe0fb25a3de Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 13 May 2026 14:03:56 +0200 Subject: [PATCH] BUG/MEDIUM: http-client: Only consume input buffer when hc one is empty Since http-client applet uses its own buffers, it is possible to have data stuck in the applet input buffer while the http-client response buffer is full, preventing the applet to consume these data. If this happens on the last part of the response payload, the upper stream can decide to shut the applet. In this case, the applet using the http client will not be able to retrieve these last data because they will never be move into the hc response buffer. The main reason for this bug is that, for now, the applets cannot survive the upper stream unlike multiplexers. It could be a good improvement for the 3.5. However, some applets still uses the stream-connector and the upper stream (peer and stat applets for instance). So it is not an easy task. In the mean time, to fix the issue on stable branches, the http-client applet now stops to consume data when the hc response buffer is not empty. This way, the applet shut will be deferred. Data will be consumed when they can be fully moved in the httpclient response buffer. This patch should fix the issue #3366. It must be backported to 3.3. --- src/http_client.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/http_client.c b/src/http_client.c index be876c628..93764472c 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -183,8 +183,10 @@ int httpclient_res_xfer(struct httpclient *hc, struct buffer *dst) /* call the client once we consumed all data */ if (!b_data(&hc->res.buf)) { b_free(&hc->res.buf); - if (ret && hc->appctx) + if (ret && hc->appctx) { + applet_will_consume(hc->appctx); appctx_wakeup(hc->appctx); + } } return ret; } @@ -776,7 +778,6 @@ void httpclient_applet_io_handler(struct appctx *appctx) } else { appctx->st0 = HTTPCLIENT_S_RES_BODY; } - htx_to_buf(htx, inbuf); break; @@ -874,6 +875,10 @@ void httpclient_applet_io_handler(struct appctx *appctx) } out: + if (appctx->st0 != HTTPCLIENT_S_RES_END && !b_is_null(&hc->res.buf)) { + /* Don't accept more data while the httpclient response buffer is not empty */ + applet_wont_consume(appctx); + } return; error: