]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: h2: restart demuxing after releasing buffer space
authorWilly Tarreau <w@1wt.eu>
Sun, 25 Nov 2018 07:03:32 +0000 (08:03 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 25 Nov 2018 08:06:42 +0000 (09:06 +0100)
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

index f059e3b97b9a3041b5de82e383f2fe239f8bfa45..0407e3808bdd329932f21127ad8b8afb229d8635 100644 (file)
@@ -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;
 }