MEDIUM: mux-h2: make h2_rcv_buf() support HTX transfers
The function needs to be slightly adapted to transfer HTX blocks, since
it may face a full buffer on the receive path, thus it needs to transfer
HTX blocks between the two sides ignoring the <count> argument in this
mode.
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 001d1da..c07cdd9 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -3579,10 +3579,31 @@
{
struct h2s *h2s = cs->ctx;
struct h2c *h2c = h2s->h2c;
+ struct htx *h2s_htx = NULL;
+ struct htx *buf_htx = NULL;
+ struct htx_ret htx_ret;
size_t ret = 0;
/* transfer possibly pending data to the upper layer */
- ret = b_xfer(buf, &h2s->rxbuf, count);
+ if (h2c->proxy->options2 & PR_O2_USE_HTX) {
+ /* in HTX mode we ignore the count argument */
+ h2s_htx = htx_from_buf(&h2s->rxbuf);
+ if (htx_is_empty(h2s_htx))
+ goto end;
+
+ buf_htx = htx_from_buf(buf);
+ count = htx_free_space(buf_htx);
+
+ htx_ret = htx_xfer_blks(buf_htx, h2s_htx, count, (h2s_htx->sl_off != -1) ? HTX_BLK_EOH : HTX_BLK_EOM);
+
+ buf_htx->extra = h2s_htx->extra;
+ if (htx_is_not_empty(buf_htx))
+ b_set_data(buf, b_size(buf));
+ ret = htx_ret.ret;
+ }
+ else {
+ ret = b_xfer(buf, &h2s->rxbuf, count);
+ }
if (b_data(&h2s->rxbuf))
cs->flags |= CS_FL_RCV_MORE;
@@ -3604,7 +3625,7 @@
tasklet_wakeup(h2c->wait_event.task);
}
}
-
+end:
return ret;
}