From: Amaury Denoyelle Date: Mon, 22 Jun 2026 12:36:16 +0000 (+0200) Subject: BUG/MINOR: hq-interop: support response buffer wrapping X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;p=thirdparty%2Fhaproxy.git BUG/MINOR: hq-interop: support response buffer wrapping When using QUIC on the backend side, transcoding of a large HTTP response may cause the rxbuf to wrap. This patch introduces buffer wrapping support for the HTTP/0.9 transcoder. This is similar to what is already implemented in HTTP/3 layer. This should be backported up to 3.3. --- diff --git a/src/hq_interop.c b/src/hq_interop.c index f1b366e50..3868cb2c4 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -116,9 +116,10 @@ static ssize_t hq_interop_rcv_buf_res(struct qcs *qcs, struct buffer *b, int fin struct htx_sl *sl; struct buffer *htx_buf; const unsigned int flags = HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN; - size_t to_copy = b_data(b); + size_t to_copy = b_contig_data(b, 0); size_t htx_sent = 0; uint32_t htx_space; + char *head; htx_buf = qcc_get_stream_rxbuf(qcs); BUG_ON(!htx_buf); @@ -144,8 +145,8 @@ static ssize_t hq_interop_rcv_buf_res(struct qcs *qcs, struct buffer *b, int fin } } else { - BUG_ON(b_head(b) + to_copy > b_wrap(b)); /* TODO */ - + head = b_head(b); + retry: htx_space = htx_free_data_space(htx); if (!htx_space) { qcs->flags |= QC_SF_DEM_FULL; @@ -157,6 +158,19 @@ static ssize_t hq_interop_rcv_buf_res(struct qcs *qcs, struct buffer *b, int fin fin = 0; } + if (b_head(b) + to_copy > b_wrap(b)) { + size_t contig = b_wrap(b) - head; + htx_sent = htx_add_data(htx, ist2(b_head(b), contig)); + if (htx_sent < contig) { + qcs->flags |= QC_SF_DEM_FULL; + goto out; + } + + to_copy -= contig; + head = b_orig(b); + goto retry; + } + htx_sent = htx_add_data(htx, ist2(b_head(b), to_copy)); if (htx_sent < to_copy) { qcs->flags |= QC_SF_DEM_FULL; @@ -175,9 +189,6 @@ static ssize_t hq_interop_rcv_buf_res(struct qcs *qcs, struct buffer *b, int fin /* Returns the amount of decoded bytes from or a negative error code. */ static ssize_t hq_interop_rcv_buf(struct qcs *qcs, struct buffer *b, int fin) { - /* hq-interop parser does not support buffer wrapping. */ - BUG_ON(b_data(b) != b_contig_data(b, 0)); - return !(qcs->qcc->flags & QC_CF_IS_BACK) ? hq_interop_rcv_buf_req(qcs, b, fin) : hq_interop_rcv_buf_res(qcs, b, fin);