diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java index 957f2c8b8e..7c2a62bb5c 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java @@ -886,7 +886,10 @@ public class DefaultHttp2Connection implements Http2Connection { streamId, nextStreamIdToCreate); } if (nextStreamIdToCreate <= 0) { - throw connectionError(REFUSED_STREAM, "Stream IDs are exhausted for this endpoint."); + // We exhausted the stream id space that we can use. Let's signal this back but also signal that + // we still may want to process active streams. + throw new Http2Exception(REFUSED_STREAM, "Stream IDs are exhausted for this endpoint.", + Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN); } boolean isReserved = state == RESERVED_LOCAL || state == RESERVED_REMOTE; if (!isReserved && !canOpenStream() || isReserved && numStreams >= maxStreams) { diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java index 9cc072e199..777bea5957 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java @@ -351,6 +351,18 @@ public class DefaultHttp2ConnectionTest { incrementAndGetStreamShouldRespectOverflow(client.local(), MAX_VALUE); } + @Test + public void clientLocalCreateStreamExhaustedSpace() throws Http2Exception { + client.local().createStream(MAX_VALUE, true); + try { + client.local().createStream(MAX_VALUE, true); + fail(); + } catch (Http2Exception expected) { + assertEquals(Http2Error.REFUSED_STREAM, expected.error()); + assertEquals(Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN, expected.shutdownHint()); + } + } + @Test(expected = Http2Exception.class) public void newStreamBehindExpectedShouldThrow() throws Http2Exception { server.local().createStream(0, true);