From: Christopher Faulet Date: Thu, 9 Jul 2026 09:40:39 +0000 (+0200) Subject: MINOR: mux-h2: Use flags of HTX blocks to detect end of message during sending X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=29ced39d9b48632c61e4bad81da3b0ba18587b06;p=haproxy.git MINOR: mux-h2: Use flags of HTX blocks to detect end of message during sending 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. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index b07b97ef7..10384d560 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -6827,6 +6827,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) @@ -6837,14 +6846,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; @@ -7262,6 +7263,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) @@ -7272,14 +7282,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; @@ -7443,8 +7445,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; @@ -7579,8 +7581,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) */ @@ -7588,6 +7589,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 */ @@ -7664,7 +7666,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;