From: Christopher Faulet Date: Mon, 9 Mar 2026 17:10:17 +0000 (+0100) Subject: MEDIUM: stream: Try to use a small buffer for HTTP request on queuing X-Git-Tag: v3.4-dev8~128 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5acdda4eedd0a5adfee2268bdf09b92e92458b80;p=thirdparty%2Fhaproxy.git MEDIUM: stream: Try to use a small buffer for HTTP request on queuing When a HTX stream is queued, if the request is small enough, it is moved into a small buffer. This should save memory on instances intensively using queues. Applet and connection receive function were update to block receive when a small buffer is in use. --- diff --git a/src/stconn.c b/src/stconn.c index 8d5dfeade..1aa136aff 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -1190,7 +1190,7 @@ int sc_conn_recv(struct stconn *sc) * SE_FL_RCV_MORE on the SC if more space is needed. */ max = channel_recv_max(ic); - if ((ic->flags & CF_WROTE_DATA) && b_is_large(sc_ib(sc))) + if (b_is_small(sc_ib(sc)) || ((ic->flags & CF_WROTE_DATA) && b_is_large(sc_ib(sc)))) max = 0; ret = CALL_MUX_WITH_RET(conn->mux, rcv_buf(sc, &ic->buf, max, cur_flags)); @@ -1861,7 +1861,7 @@ int sc_applet_recv(struct stconn *sc) * SE_FL_RCV_MORE on the SC if more space is needed. */ max = channel_recv_max(ic); - if ((ic->flags & CF_WROTE_DATA) && b_is_large(sc_ib(sc))) + if (b_is_small(sc_ib(sc)) || ((ic->flags & CF_WROTE_DATA) && b_is_large(sc_ib(sc)))) max = 0; ret = appctx_rcv_buf(sc, &ic->buf, max, flags); if (sc_ep_test(sc, SE_FL_WANT_ROOM)) { diff --git a/src/stream.c b/src/stream.c index cb26fb68c..28989bd2f 100644 --- a/src/stream.c +++ b/src/stream.c @@ -2511,6 +2511,18 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) srv = objt_server(s->target); if (scb->state == SC_ST_ASS && srv && srv->rdr_len && (s->flags & SF_REDIRECTABLE)) http_perform_server_redirect(s, scb); + + if (unlikely(scb->state == SC_ST_QUE && IS_HTX_STRM(s))) { + struct buffer sbuf = BUF_NULL; + + if (!htx_move_to_small_buffer(&sbuf, &req->buf)) + break; + b_free(&req->buf); + offer_buffers(s, 1); + req->buf = sbuf; + DBG_TRACE_DEVEL("request moved to a small buffer", STRM_EV_STRM_PROC, s); + } + } while (scb->state == SC_ST_ASS); }