Since af1e4f5167 ("MEDIUM: h2: perform a graceful shutdown on "Connection:
close"") we send GOAWAY with last stream identifier set to 2^31-1, as per
the RFC suggestion [1]. However that is only part of what the RFC suggests
if we want to close the connection gracefully; after at least 1 RTT we
would have to send another GOAWAY with a proper and valid last stream ID.
Just the "2^31-1" GOAWAY is not enough.In fact this confuses Chrome and leads to a hung connection that clears only by "timeout client" or "timeout server" (whatever strikes first). When all 3 connections slots to the HTTP2 server are filled, Chrome is unable to communicate with the server at all. Trivial fix (to be discussed) is to not set the last stream id to 2^31-1. [1] https://tools.ietf.org/html/rfc7540#section-6.8 --- RFC patch: needs discussion and careful review; I just got my feet wet with HTTP2 ... Reproducer: - use a frontend with no backend (503 error from haproxy) - raise "timeout server" and "timeout client" to 30 seconds - in Chrome refresh the error site 4-5 times This is not limited to people refreshing error sites 5 times; I am hitting this issue often when using HTTP Basic Auth ("401 Unauthorized" triggers a close). For another day, we may verify whether all those errors really need to close the connection. --- src/mux_h2.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index eb8dd0e..87e7401 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -2737,8 +2737,6 @@ static int h2s_frt_make_resp_headers(struct h2s *h2s, struct buffer *buf) if (isteq(list[hdr].n, ist("connection"))) { if (!(h2c->flags & (H2_CF_GOAWAY_SENT|H2_CF_GOAWAY_FAILED)) && word_match(list[hdr].v.ptr, list[hdr].v.len, "close", 5)) { - if (h2c->last_sid < 0) - h2c->last_sid = (1U << 31) - 1; if (h2c_send_goaway_error(h2c, h2s) <= 0) { ret = 0; goto end; -- 2.7.4

