From 082f559d36e0fc04de328e89092d24a1587b170e Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 25 Nov 2018 08:03:32 +0100 Subject: [PATCH] BUG/MEDIUM: h2: restart demuxing after releasing buffer space Since the connection changes in 1.9, some breakage happened to the H2 mux whose initial design was heavily relying on the fact that connection-level functions were woken up after data were transferred to the stream layer. We need to wake the demux up after receiving such data if the demux is blocked. This at least allows to receive POSTs again. One issue remains, it looks like the end of the uploaded data is silently discarded if the server responds before the end of the transfer (H2 in half-closed(local) state), which doesn't happen with 1.8.14 and nghttp as the client. No backport is needed. --- src/mux_h2.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mux_h2.c b/src/mux_h2.c index f059e3b97b..0407e3808b 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3582,6 +3582,7 @@ static int h2_unsubscribe(struct conn_stream *cs, int event_type, void *param) static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags) { struct h2s *h2s = cs->ctx; + struct h2c *h2c = h2s->h2c; size_t ret = 0; /* transfer possibly pending data to the upper layer */ @@ -3599,6 +3600,15 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun } } + if (ret && h2c->dsi == h2s->id) { + /* demux is blocking on this stream's buffer */ + h2c->flags &= ~H2_CF_DEM_SFULL; + if (!(h2c->wait_event.wait_reason & SUB_CAN_RECV)) { + if (h2_recv_allowed(h2c)) + tasklet_wakeup(h2c->wait_event.task); + } + } + return ret; }