BUG/MEDIUM: mux-h2: Handle EOM flag when sending a DATA frame with zero-copy

When a DATA frame is sent, we must take care to properly detect the EOM flag
on the HTX message to set ES flag on the frame when necessary, to finish the
stream. But it is only done when data are copied from the HTX message to the
mux buffer and not when the frame are sent via a zero-copy. This patch fixes
this bug.

It is a 2.4-specific bug. No backport is needed.
This commit is contained in:
Christopher Faulet 2021-04-27 22:51:07 +02:00
parent bd878d2c73
commit 925abdfdac
1 changed files with 12 additions and 1 deletions

View File

@ -5703,6 +5703,13 @@ static size_t h2s_make_data(struct h2s *h2s, struct buffer *buf, size_t count)
goto end;
}
if (htx->flags & HTX_FL_EOM) {
/* EOM+empty: we may need to add END_STREAM (except for tunneled
* message)
*/
if (!(h2s->flags & H2_SF_BODY_TUNNEL))
es_now = 1;
}
/* map an H2 frame to the HTX block so that we can put the
* frame header there.
*/
@ -5712,6 +5719,8 @@ static size_t h2s_make_data(struct h2s *h2s, struct buffer *buf, size_t count)
/* prepend an H2 DATA frame header just before the DATA block */
memcpy(outbuf.area, "\x00\x00\x00\x00\x00", 5);
write_n32(outbuf.area + 5, h2s->id); // 4 bytes
if (es_now)
outbuf.area[4] |= H2_F_DATA_END_STREAM;
h2_set_frame_size(outbuf.area, fsize);
/* update windows */
@ -5722,9 +5731,10 @@ static size_t h2s_make_data(struct h2s *h2s, struct buffer *buf, size_t count)
buf->area = old_area;
buf->data = buf->head = 0;
total += fsize;
fsize = 0;
TRACE_PROTO("sent H2 DATA frame (zero-copy)", H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
goto end;
goto out;
}
copy:
@ -5847,6 +5857,7 @@ static size_t h2s_make_data(struct h2s *h2s, struct buffer *buf, size_t count)
/* commit the H2 response */
b_add(mbuf, fsize + 9);
out:
if (es_now) {
if (h2s->st == H2_SS_OPEN)
h2s->st = H2_SS_HLOC;