From: Christopher Faulet Date: Tue, 8 Jul 2025 06:24:45 +0000 (+0200) Subject: BUG/MEDIUM: http-client: Test HTX_FL_EOM flag before commiting the HTX buffer X-Git-Tag: v3.3-dev3~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4bdb2e5a26587120101234c8f73cbc40d1777656;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: http-client: Test HTX_FL_EOM flag before commiting the HTX buffer when htx_to_buf() function is called, if the HTX message is empty, the buffer is reset. So HTX flags must not be tested after because the info may be lost. So now, we take care to test HTX_FL_EOM flag before calling htx_to_buf(). This patch must be backported as far as 2.8. --- diff --git a/src/http_client.c b/src/http_client.c index 7d14ed267..809e437d5 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -659,8 +659,6 @@ void httpclient_applet_io_handler(struct appctx *appctx) if (hc->ops.res_stline) hc->ops.res_stline(hc); - htx_to_buf(htx, &res->buf); - /* if there is no HTX data anymore and the EOM flag is * set, leave (no body) */ if (htx_is_empty(htx) && htx->flags & HTX_FL_EOM) @@ -668,6 +666,7 @@ void httpclient_applet_io_handler(struct appctx *appctx) else appctx->st0 = HTTPCLIENT_S_RES_HDR; + htx_to_buf(htx, &res->buf); break; case HTTPCLIENT_S_RES_HDR: @@ -697,7 +696,6 @@ void httpclient_applet_io_handler(struct appctx *appctx) if (htx->flags & HTX_FL_EOM) hc_htx->flags |= HTX_FL_EOM; - htx_to_buf(htx, &res->buf); htx_to_buf(hc_htx, &hc->res.buf); } else { @@ -730,7 +728,6 @@ void httpclient_applet_io_handler(struct appctx *appctx) } blk = htx_remove_blk(htx, blk); } - htx_to_buf(htx, &res->buf); if (hdr_num) { /* alloc and copy the headers in the httpclient struct */ @@ -752,6 +749,7 @@ void httpclient_applet_io_handler(struct appctx *appctx) appctx->st0 = HTTPCLIENT_S_RES_BODY; } + htx_to_buf(htx, &res->buf); break; case HTTPCLIENT_S_RES_BODY: @@ -841,16 +839,16 @@ void httpclient_applet_io_handler(struct appctx *appctx) } } + /* if not finished, should be called again */ + if ((htx_is_empty(htx) && (htx->flags & HTX_FL_EOM))) + appctx->st0 = HTTPCLIENT_S_RES_END; + htx_to_buf(htx, &res->buf); /* the data must be processed by the caller in the receive phase */ if (hc->ops.res_payload) hc->ops.res_payload(hc); - /* if not finished, should be called again */ - if ((htx_is_empty(htx) && (htx->flags & HTX_FL_EOM))) - appctx->st0 = HTTPCLIENT_S_RES_END; - /* end of message, we should quit */ break; case HTTPCLIENT_S_RES_END: