Http2ConnectionHandler extends ByteToMessageDecoder implements Http2LifecycleManager,
                                                                            ChannelOutboundHandler { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (getEmbeddedHttp2Exception(cause) != null) { onError(ctx, cause); } else { super.exceptionCaught(ctx, cause); } } protected  Http2ConnectionHandler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
                                     Http2Settings initialSettings);   Http2ConnectionHandler(boolean server, Http2FrameWriter frameWriter, Http2FrameLogger frameLogger,
                    Http2Settings initialSettings); long gracefulShutdownTimeoutMillis(); void gracefulShutdownTimeoutMillis(long gracefulShutdownTimeoutMillis); Http2Connection connection(); Http2ConnectionDecoder decoder(); Http2ConnectionEncoder encoder(); void onHttpClientUpgrade(); void onHttpServerUpgrade(Http2Settings settings); @Override void flush(ChannelHandlerContext ctx); @Override void handlerAdded(ChannelHandlerContext ctx); @Override void channelActive(ChannelHandlerContext ctx); @Override void channelInactive(ChannelHandlerContext ctx); @Override void channelWritabilityChanged(ChannelHandlerContext ctx); @Override void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise); @Override void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
                        ChannelPromise promise); @Override void disconnect(ChannelHandlerContext ctx, ChannelPromise promise); @Override void close(ChannelHandlerContext ctx, ChannelPromise promise); @Override void deregister(ChannelHandlerContext ctx, ChannelPromise promise); @Override void read(ChannelHandlerContext ctx); @Override void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise); @Override void channelReadComplete(ChannelHandlerContext ctx); @Override void exceptionCaught(ChannelHandlerContext ctx, Throwable cause); @Override void closeStreamLocal(Http2Stream stream, ChannelFuture future); @Override void closeStreamRemote(Http2Stream stream, ChannelFuture future); @Override void closeStream(final Http2Stream stream, ChannelFuture future); @Override void onError(ChannelHandlerContext ctx, Throwable cause); @Override ChannelFuture resetStream(final ChannelHandlerContext ctx, int streamId, long errorCode,
                                     ChannelPromise promise); @Override ChannelFuture goAway(final ChannelHandlerContext ctx, final int lastStreamId, final long errorCode,
                                final ByteBuf debugData, ChannelPromise promise);  }
@Test public void connectionErrorShouldStartShutdown() throws Exception { handler = newHandler(); Http2Exception e = new Http2Exception(PROTOCOL_ERROR); when(remote.lastStreamCreated()).thenReturn(STREAM_ID); handler.exceptionCaught(ctx, e); ArgumentCaptor<ByteBuf> captor = ArgumentCaptor.forClass(ByteBuf.class); verify(frameWriter).writeGoAway(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()), captor.capture(), eq(promise)); captor.getValue().release(); }
@Test public void serverShouldSend431OnHeaderSizeErrorWhenDecodingInitialHeaders() throws Exception { int padding = 0; handler = newHandler(); Http2Exception e = new Http2Exception.HeaderListSizeException(STREAM_ID, PROTOCOL_ERROR, "Header size exceeded max allowed size 8196", true); when(stream.id()).thenReturn(STREAM_ID); when(connection.isServer()).thenReturn(true); when(stream.isHeadersSent()).thenReturn(false); when(remote.lastStreamCreated()).thenReturn(STREAM_ID); when(frameWriter.writeRstStream(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()), eq(promise))).thenReturn(future); handler.exceptionCaught(ctx, e); ArgumentCaptor<Http2Headers> captor = ArgumentCaptor.forClass(Http2Headers.class); verify(encoder).writeHeaders(eq(ctx), eq(STREAM_ID), captor.capture(), eq(padding), eq(true), eq(promise)); Http2Headers headers = captor.getValue(); assertEquals(HttpResponseStatus.REQUEST_HEADER_FIELDS_TOO_LARGE.codeAsText(), headers.status()); verify(frameWriter).writeRstStream(ctx, STREAM_ID, PROTOCOL_ERROR.code(), promise); }
@Test public void serverShouldNeverSend431HeaderSizeErrorWhenEncoding() throws Exception { int padding = 0; handler = newHandler(); Http2Exception e = new Http2Exception.HeaderListSizeException(STREAM_ID, PROTOCOL_ERROR, "Header size exceeded max allowed size 8196", false); when(stream.id()).thenReturn(STREAM_ID); when(connection.isServer()).thenReturn(true); when(stream.isHeadersSent()).thenReturn(false); when(remote.lastStreamCreated()).thenReturn(STREAM_ID); when(frameWriter.writeRstStream(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()), eq(promise))).thenReturn(future); handler.exceptionCaught(ctx, e); verify(encoder, never()).writeHeaders(eq(ctx), eq(STREAM_ID), any(Http2Headers.class), eq(padding), eq(true), eq(promise)); verify(frameWriter).writeRstStream(ctx, STREAM_ID, PROTOCOL_ERROR.code(), promise); }
@Test public void clientShouldNeverSend431WhenHeadersAreTooLarge() throws Exception { int padding = 0; handler = newHandler(); Http2Exception e = new Http2Exception.HeaderListSizeException(STREAM_ID, PROTOCOL_ERROR, "Header size exceeded max allowed size 8196", true); when(stream.id()).thenReturn(STREAM_ID); when(connection.isServer()).thenReturn(false); when(stream.isHeadersSent()).thenReturn(false); when(remote.lastStreamCreated()).thenReturn(STREAM_ID); when(frameWriter.writeRstStream(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()), eq(promise))).thenReturn(future); handler.exceptionCaught(ctx, e); verify(encoder, never()).writeHeaders(eq(ctx), eq(STREAM_ID), any(Http2Headers.class), eq(padding), eq(true), eq(promise)); verify(frameWriter).writeRstStream(ctx, STREAM_ID, PROTOCOL_ERROR.code(), promise); }
@Test public void serverShouldNeverSend431IfHeadersAlreadySent() throws Exception { int padding = 0; handler = newHandler(); Http2Exception e = new Http2Exception.HeaderListSizeException(STREAM_ID, PROTOCOL_ERROR, "Header size exceeded max allowed size 8196", true); when(stream.id()).thenReturn(STREAM_ID); when(connection.isServer()).thenReturn(true); when(stream.isHeadersSent()).thenReturn(true); when(remote.lastStreamCreated()).thenReturn(STREAM_ID); when(frameWriter.writeRstStream(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()), eq(promise))).thenReturn(future); handler.exceptionCaught(ctx, e); verify(encoder, never()).writeHeaders(eq(ctx), eq(STREAM_ID), any(Http2Headers.class), eq(padding), eq(true), eq(promise)); verify(frameWriter).writeRstStream(ctx, STREAM_ID, PROTOCOL_ERROR.code(), promise); }
@Test public void serverShouldCreateStreamIfNeededBeforeSending431() throws Exception { int padding = 0; handler = newHandler(); Http2Exception e = new Http2Exception.HeaderListSizeException(STREAM_ID, PROTOCOL_ERROR, "Header size exceeded max allowed size 8196", true); when(connection.stream(STREAM_ID)).thenReturn(null); when(remote.createStream(STREAM_ID, true)).thenReturn(stream); when(stream.id()).thenReturn(STREAM_ID); when(connection.isServer()).thenReturn(true); when(stream.isHeadersSent()).thenReturn(false); when(remote.lastStreamCreated()).thenReturn(STREAM_ID); when(frameWriter.writeRstStream(eq(ctx), eq(STREAM_ID), eq(Http2Error.PROTOCOL_ERROR.code()), eq(promise))).thenReturn(future); handler.exceptionCaught(ctx, e); verify(remote).createStream(STREAM_ID, true); verify(encoder).writeHeaders(eq(ctx), eq(STREAM_ID), any(Http2Headers.class), eq(padding), eq(true), eq(promise)); verify(frameWriter).writeRstStream(ctx, STREAM_ID, PROTOCOL_ERROR.code(), promise); }