]> 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, 24 Jul 2026 10:20:47 +0000 (12:20 +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 319bc35b4c8a981e36e73a82e3f1f24f6a645b09..b915667c2871268ac64185bbd35e3cddf11727e9 100644 (file)
@@ -2834,7 +2834,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;
@@ -2949,8 +2949,7 @@ 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))) {
+       else if ((blk->flags & HTX_BLK_FL_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.
@@ -2962,7 +2961,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 = ((blk->flags & HTX_BLK_FL_EOM) ? H1_MSG_DONE : H1_MSG_TRAILERS);
        }
        else {
                if (!chunk_memcat(&outbuf, "\r\n", 2))
@@ -3032,7 +3031,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;
@@ -3147,7 +3146,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);