BUG/MEDIUM: mux-h2: Add EOT block when EOM flag is set on an empty HTX message

In the H2 mux, when a empty DATA frame is used to finish a message, just to
set the ES flag, we now only set the EOM flag on the HTX message. However,
if the HTX message is empty, this event will not be properly handled on the
other side because there is no effective data to handle. Thus, it is
interpreted as an abort by the H1 mux.

It is in part caused by the current H1 mux design but also because there is
no way to emit empty HTX block (NOOP HTX block) or to wakeup a mux for send
when there is no data to finish some internal processing.

Thus, for now, to work around this limitation, an EOT HTX block is added by
the H2 mux if a EOM flag is added on an empty HTX message. This case is only
possible when an empty DATA frame with the ES flag is received.

This fix is specific for 2.4. No backport needed.
This commit is contained in:
Christopher Faulet 2021-02-10 09:04:59 +01:00
parent 0a916d2aca
commit 337243235f
1 changed files with 13 additions and 1 deletions

View File

@ -4882,8 +4882,20 @@ static int h2_frt_transfer_data(struct h2s *h2s)
* was aborted. Otherwise (request path + tunnel abrted), the
* EOM was already reported.
*/
if ((h2c->flags & H2_CF_IS_BACK) || !(h2s->flags & H2_SF_TUNNEL_ABRT))
if ((h2c->flags & H2_CF_IS_BACK) || !(h2s->flags & H2_SF_TUNNEL_ABRT)) {
/* If we receive an empty DATA frame with ES flag while the HTX
* message is empty, we must be sure to push a block to be sure
* the HTX EOM flag will be handled on the other side. It is a
* workaround because for now it is not possible to push empty
* HTX DATA block. And without this block, there is no way to
* "commit" the end of the message.
*/
if (htx_is_empty(htx)) {
if (!htx_add_endof(htx, HTX_BLK_EOT))
goto fail;
}
htx->flags |= HTX_FL_EOM;
}
}
h2c->rcvd_c += h2c->dpl;