]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: mux-h1: Use flags of HTX blocks to detect end of message during sending
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 9 Jul 2026 12:52:58 +0000 (14:52 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 18 Sep 2026 15:05:18 +0000 (17:05 +0200)
When a message is sent, the end of the message is now detected by testing
flags of each HTX blocs. Otherwise, the logic remains mostly unchanged. A
test in h1_make_eoh() was slightly changed but it should be harmless.
Especially because HTX_BLK_FL_EOM cannot be set on the EOH block if it is
followed by something else than tunneled data, which is unexpected and
invalid in that case. All conditions to establish a tunnel at this stage
were already evaluated. And if any, the error will be detected in
h1_make_trailers() function.

src/mux_h1.c

index 68401dacc6f2253e62553cd6bc2aad3d0859ec79..329f34a852ba94dfdd4778e8ded7615ecfec8bcd 100644 (file)
@@ -2843,7 +2843,7 @@ static size_t h1_make_eoh(struct h1s *h1s, struct h1m *h1m, struct htx *htx, siz
                        TRACE_STATE("force close mode (T-E + HTTP/1.0)", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
                }
                else if ((h1m->flags & H1_MF_CLEN) && h1m->body_len != 0 &&
-                        htx_is_unique_blk(htx, blk) && (htx->flags & HTX_FL_HAS_EOM) &&
+                        (blk->flags & HTX_BLK_FL_EOM) &&
                         (!(h1m->flags & H1_MF_RESP) || !(h1s->flags & H1S_F_BODYLESS_RESP))) {
                        /* C-L but no data for non-bodyless response or for a request: force close */
                        h1s->flags = (h1s->flags & ~H1S_F_WANT_MSK) | H1S_F_WANT_CLO;
@@ -2958,11 +2958,9 @@ static size_t h1_make_eoh(struct h1s *h1s, struct h1m *h1m, struct htx *htx, siz
                h1s->flags &= ~H1S_F_HAVE_O_CONN;
                TRACE_STATE("1xx response xferred", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1c->conn, h1s);
        }
-       else if (htx_is_unique_blk(htx, blk) &&
-                ((htx->flags & HTX_FL_HAS_EOM) || ((h1m->flags & H1_MF_CLEN) && !h1m->curr_len))) {
-               /* EOM flag is set and it is the last block or there is no
-                * payload. It cannot be removed now. We must emit the end of
-                * the message first to be sure the output buffer is not full.
+       else if (blk->flags & HTX_BLK_FL_EOM) {
+               /* EOM flag is set. We must emit the end of the message first to
+                * be sure the output buffer is not full.
                 */
                if ((h1m->flags & H1_MF_CHNK) && (!(h1m->flags & H1_MF_RESP) || !(h1s->flags & H1S_F_BODYLESS_RESP))) {
                        /* Send null-chunk except for bodyless responses */
@@ -2971,7 +2969,7 @@ static size_t h1_make_eoh(struct h1s *h1s, struct h1m *h1m, struct htx *htx, siz
                }
                else if (!chunk_memcat(&outbuf, "\r\n", 2))
                        goto full;
-               h1m->state = ((htx->flags & HTX_FL_HAS_EOM) ? H1_MSG_DONE : H1_MSG_TRAILERS);
+               h1m->state = H1_MSG_DONE;
        }
        else {
                if (!chunk_memcat(&outbuf, "\r\n", 2))
@@ -3041,7 +3039,7 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf,
            htx_get_blk_value(htx, blk).len == count &&
            b_size(&h1c->obuf) == b_size(buf)) {
                void *old_area;
-               int eom = (htx->flags & HTX_FL_HAS_EOM);
+               int eom = (blk->flags & HTX_BLK_FL_EOM);
 
                old_area = h1c->obuf.area;
                h1c->obuf.area = buf->area;
@@ -3156,7 +3154,7 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf,
                                /* Get the maximum amount of data we can xferred */
                                vlen = count;
                        }
-                       else if (htx_is_unique_blk(htx, blk) && (htx->flags & HTX_FL_HAS_EOM)) {
+                       else if (blk->flags & HTX_BLK_FL_EOM) {
                                /* It is the last block of this message. After this one,
                                 * only tunneled data may be forwarded. */
                                TRACE_DEVEL("last message block", H1_EV_TX_DATA|H1_EV_TX_BODY, h1c->conn, h1s);