]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: h3: properly realloc buffer after interim response encoding
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 15 Jul 2025 08:59:07 +0000 (10:59 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 15 Jul 2025 16:39:23 +0000 (18:39 +0200)
Previous commit fixes encoding of several following HTTP response
message when interim status codes are first reported. However,
h3_resp_headers_send() still was unable to interrupt encoding if output
buffer room was not sufficient. This case may be likely because small
buffers are used for headers encoding.

This commit fixes this situation. If output buffer is not empty prior to
response encoding, this means that a previous interim response message
was already encoded before. In this case, and if remaining space is not
sufficient, use buffer release mechanism : this allows to restart
response encoding by using a newer buffer. This process has already been
used for DATA and trailers encoding.

This must be backported up to 2.6. However, note that buffer release
mechanism is not present for version 2.8 and lower. In this case, qcs
flag QC_SF_BLK_MROOM should be enough as a replacement.

src/h3.c

index aca564fbf1e114a41a2b968c5ec87bdc90ea1a10..53679b91de05b4f8a6679651377ca08e332d9865 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -2294,6 +2294,20 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
        return ret;
 
  err_full:
+       if (b_data(res)) {
+               /* Output buffer already contains data : this may happens after
+                * HTTP interim response encoding. Try to release buffer to be
+                * able to encode newer interim or final response.
+                */
+               if (qcc_release_stream_txbuf(qcs)) {
+                       TRACE_DEVEL("cannot release buf", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
+                       return 0;
+               }
+
+               TRACE_DEVEL("retry after buf release", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
+               goto retry;
+       }
+
        if (smallbuf) {
                TRACE_DEVEL("retry with a full buffer", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
                smallbuf = 0;