]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: mux-h2: Use flags of HTX blocks to detect end of message during sending
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 9 Jul 2026 09:40:39 +0000 (11:40 +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, most of the logic remains unchanged. The
only difference is the detection of the end of the message when headers are
sent (back or front). Now, it is be possible to detect the EOM when the
stream is already closed and H2_SF_MORE_HTX_DATA may be removed while it was
untouched before. But it is not a big deal because this flag is only tested
when a shutdown is performed on the stream. So removing it for an already
closed stream is a no-op.

src/mux_h2.c

index f875e3888c8bf05b3ec4fa73a6ba85d6f4707a41..42feb750a9d242f6efaecb5c2e7cf97b6e3ee4ea 100644 (file)
@@ -6881,6 +6881,15 @@ static size_t h2s_snd_fhdrs(struct h2s *h2s, struct htx *htx)
        while (blk) {
                type = htx_get_blk_type(blk);
                ret += htx_get_blksz(blk);
+               if ((blk->flags & HTX_BLK_FL_EOM) && h2s->status >= 200) {
+                       /* EOM: we may need to add END_STREAM except for 1xx
+                        * responses and tunneled response.
+                        */
+                       h2s->flags &= ~H2_SF_MORE_HTX_DATA;
+                       if (!(h2s->flags & H2_SF_BODY_TUNNEL) || h2s->status >= 300)
+                               es_now = 1;
+               }
+
                blk = htx_remove_blk(htx, blk);
                /* The removed block is the EOH */
                if (type == HTX_BLK_EOH)
@@ -6891,14 +6900,6 @@ static size_t h2s_snd_fhdrs(struct h2s *h2s, struct htx *htx)
                /* Response already closed: add END_STREAM */
                es_now = 1;
        }
-       else if ((htx->flags & HTX_FL_HAS_EOM) && htx_is_empty(htx) && h2s->status >= 200) {
-               /* EOM+empty: we may need to add END_STREAM except for 1xx
-                * responses and tunneled response.
-                */
-               h2s->flags &= ~H2_SF_MORE_HTX_DATA;
-               if (!(h2s->flags & H2_SF_BODY_TUNNEL) || h2s->status >= 300)
-                       es_now = 1;
-       }
 
        if (es_now)
                outbuf.area[4] |= H2_F_HEADERS_END_STREAM;
@@ -7322,6 +7323,15 @@ static size_t h2s_snd_bhdrs(struct h2s *h2s, struct htx *htx)
        while (blk) {
                type = htx_get_blk_type(blk);
                ret += htx_get_blksz(blk);
+               if (blk->flags & HTX_BLK_FL_EOM) {
+                       /* EOM+empty: we may need to add END_STREAM (except for CONNECT
+                        * request)
+                        */
+                       h2s->flags &= ~H2_SF_MORE_HTX_DATA;
+                       if (!(h2s->flags & H2_SF_BODY_TUNNEL))
+                               es_now = 1;
+               }
+
                blk = htx_remove_blk(htx, blk);
                /* The removed block is the EOH */
                if (type == HTX_BLK_EOH)
@@ -7332,14 +7342,6 @@ static size_t h2s_snd_bhdrs(struct h2s *h2s, struct htx *htx)
                /* Request already closed: add END_STREAM */
                es_now = 1;
        }
-       if ((htx->flags & HTX_FL_HAS_EOM) && htx_is_empty(htx)) {
-               /* EOM+empty: we may need to add END_STREAM (except for CONNECT
-                * request)
-                */
-               h2s->flags &= ~H2_SF_MORE_HTX_DATA;
-               if (!(h2s->flags & H2_SF_BODY_TUNNEL))
-                       es_now = 1;
-       }
 
        if (es_now)
                outbuf.area[4] |= H2_F_HEADERS_END_STREAM;
@@ -7503,8 +7505,8 @@ static size_t h2s_make_data(struct h2s *h2s, struct buffer *buf, size_t count)
                        goto end;
                }
 
-               if (htx->flags & HTX_FL_HAS_EOM) {
-                       /* EOM+empty: we may need to add END_STREAM (except for tunneled
+               if (blk->flags & HTX_BLK_FL_EOM) {
+                       /* EOM: we may need to add END_STREAM (except for tunneled
                         * message)
                         */
                        h2s->flags &= ~H2_SF_MORE_HTX_DATA;
@@ -7639,8 +7641,7 @@ static size_t h2s_make_data(struct h2s *h2s, struct buffer *buf, size_t count)
        /* consume incoming HTX block */
        total += fsize;
        if (fsize == bsize) {
-               htx_remove_blk(htx, blk);
-               if ((htx->flags & HTX_FL_HAS_EOM) && htx_is_empty(htx)) {
+               if (blk->flags & HTX_BLK_FL_EOM) {
                        /* EOM+empty: we may need to add END_STREAM (except for tunneled
                         * message)
                         */
@@ -7648,6 +7649,7 @@ static size_t h2s_make_data(struct h2s *h2s, struct buffer *buf, size_t count)
                        if (!(h2s->flags & H2_SF_BODY_TUNNEL))
                                es_now = 1;
                }
+               htx_remove_blk(htx, blk);
        }
        else {
                /* we've truncated this block */
@@ -7724,7 +7726,7 @@ static size_t h2s_skip_data(struct h2s *h2s, struct buffer *buf, size_t count)
        if (fsize != bsize)
                goto skip_data;
 
-       if (!(htx->flags & HTX_FL_HAS_EOM) || !htx_is_unique_blk(htx, blk))
+       if (!(blk->flags & HTX_BLK_FL_EOM))
                goto skip_data;
 
        h2s->flags &= ~H2_SF_MORE_HTX_DATA;