io.netty.handler.codec.http2.Http2Error Java Examples
The following examples show how to use
io.netty.handler.codec.http2.Http2Error.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: NettyServerHandlerTest.java From grpc-java with Apache License 2.0 | 6 votes |
@Test public void keepAliveEnforcer_sendingDataResetsCounters() throws Exception { permitKeepAliveWithoutCalls = false; permitKeepAliveTimeInNanos = TimeUnit.HOURS.toNanos(1); manualSetUp(); createStream(); Http2Headers headers = Utils.convertServerHeaders(new Metadata()); ChannelFuture future = enqueue( SendResponseHeadersCommand.createHeaders(stream.transportState(), headers)); future.get(); for (int i = 0; i < 10; i++) { future = enqueue( new SendGrpcFrameCommand(stream.transportState(), content().retainedSlice(), false)); future.get(); channel().releaseOutbound(); channelRead(pingFrame(false /* isAck */, 1L)); } verifyWrite(never()).writeGoAway(eq(ctx()), eq(STREAM_ID), eq(Http2Error.ENHANCE_YOUR_CALM.code()), any(ByteBuf.class), any(ChannelPromise.class)); }
Example #2
Source File: NettyServerHandler.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
/** * Sends out first GOAWAY and ping, and schedules second GOAWAY and close. */ void start(final ChannelHandlerContext ctx) { goAway( ctx, Integer.MAX_VALUE, Http2Error.NO_ERROR.code(), ByteBufUtil.writeAscii(ctx.alloc(), goAwayMessage), ctx.newPromise()); pingFuture = ctx.executor().schedule( new Runnable() { @Override public void run() { secondGoAwayAndClose(ctx); } }, GRACEFUL_SHUTDOWN_PING_TIMEOUT_NANOS, TimeUnit.NANOSECONDS); encoder().writePing(ctx, false /* isAck */, GRACEFUL_SHUTDOWN_PING, ctx.newPromise()); }
Example #3
Source File: NettyClientHandler.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
/** * Handler for an inbound HTTP/2 RST_STREAM frame, terminating a stream. */ private void onRstStreamRead(int streamId, long errorCode) { NettyClientStream.TransportState stream = clientStream(connection().stream(streamId)); if (stream != null) { Status status = GrpcUtil.Http2Error.statusForCode((int) errorCode) .augmentDescription("Received Rst Stream"); stream.transportReportStatus( status, errorCode == Http2Error.REFUSED_STREAM.code() ? RpcProgress.REFUSED : RpcProgress.PROCESSED, false /*stop delivery*/, new Metadata()); if (keepAliveManager != null) { keepAliveManager.onDataReceived(); } } }
Example #4
Source File: NettyClientHandler.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
private void forcefulClose(final ChannelHandlerContext ctx, final ForcefulCloseCommand msg, ChannelPromise promise) throws Exception { // close() already called by NettyClientTransport, so just need to clean up streams connection().forEachActiveStream(new Http2StreamVisitor() { @Override public boolean visit(Http2Stream stream) throws Http2Exception { NettyClientStream.TransportState clientStream = clientStream(stream); if (clientStream != null) { clientStream.transportReportStatus(msg.getStatus(), true, new Metadata()); resetStream(ctx, stream.id(), Http2Error.CANCEL.code(), ctx.newPromise()); } stream.close(); return true; } }); promise.setSuccess(); }
Example #5
Source File: NettyServerHandler.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
@Override public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception { if (keepAliveManager != null) { keepAliveManager.onDataReceived(); } if (!keepAliveEnforcer.pingAcceptable()) { ByteBuf debugData = ByteBufUtil.writeAscii(ctx.alloc(), "too_many_pings"); goAway(ctx, connection().remote().lastStreamCreated(), Http2Error.ENHANCE_YOUR_CALM.code(), debugData, ctx.newPromise()); Status status = Status.RESOURCE_EXHAUSTED.withDescription("Too many pings from client"); try { forcefulClose(ctx, new ForcefulCloseCommand(status), ctx.newPromise()); } catch (Exception ex) { onError(ctx, /* outbound= */ true, ex); } } }
Example #6
Source File: Http2ResponseDecoder.java From armeria with Apache License 2.0 | 6 votes |
private void onWrapperCompleted(HttpResponseWrapper resWrapper, int id, @Nullable Throwable cause) { // Cancel timeout future and abort the request if it exists. resWrapper.onSubscriptionCancelled(cause); if (cause != null) { // We are not closing the connection but just send a RST_STREAM, // so we have to remove the response manually. removeResponse(id); // Reset the stream. final int streamId = idToStreamId(id); final int lastStreamId = conn.local().lastStreamKnownByPeer(); if (lastStreamId < 0 || // Did not receive a GOAWAY yet or streamId <= lastStreamId) { // received a GOAWAY and the request's streamId <= lastStreamId final ChannelHandlerContext ctx = channel().pipeline().lastContext(); if (ctx != null) { encoder.writeRstStream(ctx, streamId, Http2Error.CANCEL.code(), ctx.newPromise()); ctx.flush(); } else { // The pipeline has been cleaned up due to disconnection. } } } }
Example #7
Source File: Http2ResponseDecoder.java From armeria with Apache License 2.0 | 6 votes |
@Override public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception { keepAliveChannelRead(); final HttpResponseWrapper res = removeResponse(streamIdToId(streamId)); if (res == null) { if (conn.streamMayHaveExisted(streamId)) { if (logger.isDebugEnabled()) { logger.debug("{} Received a late RST_STREAM frame for a closed stream: {}", ctx.channel(), streamId); } } else { throw connectionError(PROTOCOL_ERROR, "received a RST_STREAM frame for an unknown stream: %d", streamId); } return; } res.close(new ClosedStreamException("received a RST_STREAM frame: " + Http2Error.valueOf(errorCode))); }
Example #8
Source File: HttpResponseSubscriber.java From armeria with Apache License 2.0 | 6 votes |
private TimeoutTask newTimeoutTask() { return new TimeoutTask() { @Override public boolean canSchedule() { return state != State.DONE; } @Override public void run() { if (state != State.DONE) { final Runnable requestTimeoutHandler = reqCtx.requestTimeoutHandler(); if (requestTimeoutHandler != null) { requestTimeoutHandler.run(); } else { failAndRespond(RequestTimeoutException.get(), serviceUnavailableResponse, Http2Error.INTERNAL_ERROR, true); } } } }; }
Example #9
Source File: ServerHttp2ObjectEncoder.java From armeria with Apache License 2.0 | 6 votes |
@Override public ChannelFuture doWriteHeaders(int id, int streamId, ResponseHeaders headers, boolean endStream, boolean isTrailersEmpty) { if (!isStreamPresentAndWritable(streamId)) { // One of the following cases: // - Stream has been closed already. // - (bug) Server tried to send a response HEADERS frame before receiving a request HEADERS frame. return newFailedFuture(ClosedStreamException.get()); } if (!isGoAwaySent && keepAliveHandler != null && keepAliveHandler.isMaxConnectionAgeExceeded()) { final int lastStreamId = encoder().connection().remote().lastStreamCreated(); encoder().writeGoAway(ctx(), lastStreamId, Http2Error.NO_ERROR.code(), MAX_CONNECTION_AGE_DEBUG.retain(), ctx().newPromise()); isGoAwaySent = true; } final Http2Headers converted = convertHeaders(headers, isTrailersEmpty); onKeepAliveReadOrWrite(); return encoder().writeHeaders(ctx(), streamId, converted, 0, endStream, ctx().newPromise()); }
Example #10
Source File: NettyServerHandler.java From grpc-java with Apache License 2.0 | 6 votes |
private void forcefulClose(final ChannelHandlerContext ctx, final ForcefulCloseCommand msg, ChannelPromise promise) throws Exception { super.close(ctx, promise); connection().forEachActiveStream(new Http2StreamVisitor() { @Override public boolean visit(Http2Stream stream) throws Http2Exception { NettyServerStream.TransportState serverStream = serverStream(stream); if (serverStream != null) { PerfMark.startTask("NettyServerHandler.forcefulClose", serverStream.tag()); PerfMark.linkIn(msg.getLink()); try { serverStream.transportReportStatus(msg.getStatus()); resetStream(ctx, stream.id(), Http2Error.CANCEL.code(), ctx.newPromise()); } finally { PerfMark.stopTask("NettyServerHandler.forcefulClose", serverStream.tag()); } } stream.close(); return true; } }); }
Example #11
Source File: NettyServerHandler.java From grpc-java with Apache License 2.0 | 6 votes |
@Override public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception { if (keepAliveManager != null) { keepAliveManager.onDataReceived(); } if (!keepAliveEnforcer.pingAcceptable()) { ByteBuf debugData = ByteBufUtil.writeAscii(ctx.alloc(), "too_many_pings"); goAway(ctx, connection().remote().lastStreamCreated(), Http2Error.ENHANCE_YOUR_CALM.code(), debugData, ctx.newPromise()); Status status = Status.RESOURCE_EXHAUSTED.withDescription("Too many pings from client"); try { forcefulClose(ctx, new ForcefulCloseCommand(status), ctx.newPromise()); } catch (Exception ex) { onError(ctx, /* outbound= */ true, ex); } } }
Example #12
Source File: NettyClientHandler.java From grpc-java with Apache License 2.0 | 6 votes |
/** * Handler for an inbound HTTP/2 RST_STREAM frame, terminating a stream. */ private void onRstStreamRead(int streamId, long errorCode) { NettyClientStream.TransportState stream = clientStream(connection().stream(streamId)); if (stream != null) { PerfMark.event("NettyClientHandler.onRstStreamRead", stream.tag()); Status status = GrpcUtil.Http2Error.statusForCode((int) errorCode) .augmentDescription("Received Rst Stream"); stream.transportReportStatus( status, errorCode == Http2Error.REFUSED_STREAM.code() ? RpcProgress.REFUSED : RpcProgress.PROCESSED, false /*stop delivery*/, new Metadata()); if (keepAliveManager != null) { keepAliveManager.onDataReceived(); } } }
Example #13
Source File: NettyClientHandler.java From grpc-java with Apache License 2.0 | 6 votes |
private void forcefulClose(final ChannelHandlerContext ctx, final ForcefulCloseCommand msg, ChannelPromise promise) throws Exception { // close() already called by NettyClientTransport, so just need to clean up streams connection().forEachActiveStream(new Http2StreamVisitor() { @Override public boolean visit(Http2Stream stream) throws Http2Exception { NettyClientStream.TransportState clientStream = clientStream(stream); Tag tag = clientStream != null ? clientStream.tag() : PerfMark.createTag(); PerfMark.startTask("NettyClientHandler.forcefulClose", tag); PerfMark.linkIn(msg.getLink()); try { if (clientStream != null) { clientStream.transportReportStatus(msg.getStatus(), true, new Metadata()); resetStream(ctx, stream.id(), Http2Error.CANCEL.code(), ctx.newPromise()); } stream.close(); return true; } finally { PerfMark.stopTask("NettyClientHandler.forcefulClose", tag); } } }); promise.setSuccess(); }
Example #14
Source File: Http2ControlFrameLimitEncoder.java From grpc-java with Apache License 2.0 | 6 votes |
private ChannelPromise handleOutstandingControlFrames(ChannelHandlerContext ctx, ChannelPromise promise) { if (!limitReached) { if (outstandingControlFrames == maxOutstandingControlFrames) { // Let's try to flush once as we may be able to flush some of the control frames. ctx.flush(); } if (outstandingControlFrames == maxOutstandingControlFrames) { limitReached = true; Http2Exception exception = Http2Exception.connectionError(Http2Error.ENHANCE_YOUR_CALM, "Maximum number %d of outstanding control frames reached", maxOutstandingControlFrames); logger.info("Maximum number {} of outstanding control frames reached. Closing channel {}", maxOutstandingControlFrames, ctx.channel(), exception); // First notify the Http2LifecycleManager and then close the connection. lifecycleManager.onError(ctx, true, exception); ctx.close(); } outstandingControlFrames++; // We did not reach the limit yet, add the listener to decrement the number of outstanding control frames // once the promise was completed return promise.unvoid().addListener(outstandingControlFramesListener); } return promise; }
Example #15
Source File: NettyServerHandlerTest.java From grpc-java with Apache License 2.0 | 6 votes |
@Test public void closeShouldGracefullyCloseChannel() throws Exception { manualSetUp(); handler().close(ctx(), newPromise()); verifyWrite().writeGoAway(eq(ctx()), eq(Integer.MAX_VALUE), eq(Http2Error.NO_ERROR.code()), isA(ByteBuf.class), any(ChannelPromise.class)); verifyWrite().writePing( eq(ctx()), eq(false), eq(NettyServerHandler.GRACEFUL_SHUTDOWN_PING), isA(ChannelPromise.class)); channelRead(pingFrame(/*ack=*/ true , NettyServerHandler.GRACEFUL_SHUTDOWN_PING)); verifyWrite().writeGoAway(eq(ctx()), eq(0), eq(Http2Error.NO_ERROR.code()), isA(ByteBuf.class), any(ChannelPromise.class)); // Verify that the channel was closed. assertFalse(channel().isOpen()); }
Example #16
Source File: NettyServerHandler.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
private void forcefulClose(final ChannelHandlerContext ctx, final ForcefulCloseCommand msg, ChannelPromise promise) throws Exception { close(ctx, promise); connection().forEachActiveStream(new Http2StreamVisitor() { @Override public boolean visit(Http2Stream stream) throws Http2Exception { NettyServerStream.TransportState serverStream = serverStream(stream); if (serverStream != null) { serverStream.transportReportStatus(msg.getStatus()); resetStream(ctx, stream.id(), Http2Error.CANCEL.code(), ctx.newPromise()); } stream.close(); return true; } }); }
Example #17
Source File: ExceptionsTest.java From armeria with Apache License 2.0 | 6 votes |
@Test public void testIsExpected() { final boolean expected = !Flags.verboseSocketExceptions(); assertThat(Exceptions.isExpected(new Exception())).isFalse(); assertThat(Exceptions.isExpected(new Exception("broken pipe"))).isFalse(); assertThat(Exceptions.isExpected(new Exception("connection reset by peer"))).isFalse(); assertThat(Exceptions.isExpected(new Exception("stream closed"))).isFalse(); assertThat(Exceptions.isExpected(new Exception("SSLEngine closed already"))).isFalse(); assertThat(Exceptions.isExpected(new ClosedChannelException())).isEqualTo(expected); assertThat(Exceptions.isExpected(ClosedSessionException.get())).isEqualTo(expected); assertThat(Exceptions.isExpected(new IOException("connection reset by peer"))).isEqualTo(expected); assertThat(Exceptions.isExpected(new IOException("invalid argument"))).isEqualTo(false); assertThat(Exceptions.isExpected(new ChannelException("broken pipe"))).isEqualTo(expected); assertThat(Exceptions.isExpected(new ChannelException("invalid argument"))).isEqualTo(false); assertThat(Exceptions.isExpected(new Http2Exception(Http2Error.INTERNAL_ERROR, "stream closed"))) .isEqualTo(expected); assertThat(Exceptions.isExpected(new Http2Exception(Http2Error.INTERNAL_ERROR))).isEqualTo(false); assertThat(Exceptions.isExpected(new SSLException("SSLEngine closed already"))).isEqualTo(expected); assertThat(Exceptions.isExpected(new SSLException("Handshake failed"))).isEqualTo(false); }
Example #18
Source File: HttpObjectEncoder.java From armeria with Apache License 2.0 | 5 votes |
/** * Resets the specified stream. If the session protocol does not support multiplexing or the connection * is in unrecoverable state, the connection will be closed. For example, in an HTTP/1 connection, this * will lead the connection to be closed immediately or after the previous requests that are not reset. */ default ChannelFuture writeReset(int id, int streamId, Http2Error error) { if (isClosed()) { return newClosedSessionFuture(); } return doWriteReset(id, streamId, error); }
Example #19
Source File: NettyClientHandlerTest.java From grpc-java with Apache License 2.0 | 5 votes |
@Test public void cancelShouldSucceed() throws Exception { createStream(); cancelStream(Status.CANCELLED); verifyWrite().writeRstStream(eq(ctx()), eq(3), eq(Http2Error.CANCEL.code()), any(ChannelPromise.class)); verify(mockKeepAliveManager, times(1)).onTransportActive(); // onStreamActive verify(mockKeepAliveManager, times(1)).onTransportIdle(); // onStreamClosed verifyNoMoreInteractions(mockKeepAliveManager); }
Example #20
Source File: NettyServerHandlerTest.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
@Test public void clientCancelShouldForwardToStreamListener() throws Exception { manualSetUp(); createStream(); channelRead(rstStreamFrame(STREAM_ID, (int) Http2Error.CANCEL.code())); ArgumentCaptor<Status> statusCap = ArgumentCaptor.forClass(Status.class); verify(streamListener).closed(statusCap.capture()); assertEquals(Code.CANCELLED, statusCap.getValue().getCode()); Truth.assertThat(statusCap.getValue().getDescription()).contains("RST_STREAM"); verify(streamListener, atLeastOnce()).onReady(); assertNull("no messages expected", streamListenerMessageQueue.poll()); }
Example #21
Source File: Http2RequestDecoder.java From armeria with Apache License 2.0 | 5 votes |
@Override public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception { keepAliveChannelRead(); final DecodedHttpRequest req = requests.get(streamId); if (req == null) { throw connectionError(PROTOCOL_ERROR, "received a RST_STREAM frame for an unknown stream: %d", streamId); } req.abortResponse(new ClosedStreamException( "received a RST_STREAM frame: " + Http2Error.valueOf(errorCode))); }
Example #22
Source File: NettyServerHandlerTest.java From grpc-java with Apache License 2.0 | 5 votes |
@Test public void maxConnectionAgeGrace_channelClosedAfterGracePeriod_withPingTimeout() throws Exception { maxConnectionAgeInNanos = TimeUnit.MILLISECONDS.toNanos(10L); maxConnectionAgeGraceInNanos = TimeUnit.MINUTES.toNanos(30L); // greater than ping timeout manualSetUp(); createStream(); fakeClock().forwardNanos(maxConnectionAgeInNanos); // first GO_AWAY sent verifyWrite().writeGoAway( eq(ctx()), eq(Integer.MAX_VALUE), eq(Http2Error.NO_ERROR.code()), any(ByteBuf.class), any(ChannelPromise.class)); // ping sent verifyWrite().writePing( eq(ctx()), eq(false), eq(0x97ACEF001L), any(ChannelPromise.class)); verifyWrite(never()).writeGoAway( eq(ctx()), eq(STREAM_ID), eq(Http2Error.NO_ERROR.code()), any(ByteBuf.class), any(ChannelPromise.class)); fakeClock().forwardNanos(TimeUnit.SECONDS.toNanos(10)); // second GO_AWAY sent verifyWrite().writeGoAway( eq(ctx()), eq(STREAM_ID), eq(Http2Error.NO_ERROR.code()), any(ByteBuf.class), any(ChannelPromise.class)); fakeClock().forwardNanos(maxConnectionAgeGraceInNanos - 2); assertTrue(channel().isOpen()); fakeClock().forwardTime(2, TimeUnit.MILLISECONDS); // channel closed assertTrue(!channel().isOpen()); }
Example #23
Source File: NettyClientHandlerTest.java From grpc-java with Apache License 2.0 | 5 votes |
@Test public void cancelTwiceDifferentReasons() throws Exception { createStream(); cancelStream(Status.DEADLINE_EXCEEDED); verifyWrite().writeRstStream(eq(ctx()), eq(3), eq(Http2Error.CANCEL.code()), any(ChannelPromise.class)); ChannelFuture future = cancelStream(Status.CANCELLED); assertTrue(future.isSuccess()); }
Example #24
Source File: Http2ObjectEncoder.java From armeria with Apache License 2.0 | 5 votes |
@Override public final ChannelFuture doWriteReset(int id, int streamId, Http2Error error) { final Http2Stream stream = encoder.connection().stream(streamId); // Send a RST_STREAM frame only for an active stream which did not send a RST_STREAM frame already. if (stream != null && !stream.isResetSent()) { return encoder.writeRstStream(ctx, streamId, error.code(), ctx.newPromise()); } return ctx.writeAndFlush(Unpooled.EMPTY_BUFFER); }
Example #25
Source File: HttpResponseSubscriber.java From armeria with Apache License 2.0 | 5 votes |
private void failAndReset(Throwable cause) { final State oldState = setDone(false); final ChannelFuture future = responseEncoder.writeReset(req.id(), req.streamId(), Http2Error.CANCEL); addCallbackAndFlush(cause, oldState, future, true); }
Example #26
Source File: Exceptions.java From armeria with Apache License 2.0 | 5 votes |
/** * Returns {@code true} if the specified exception will cancel the current request or response stream. */ public static boolean isStreamCancelling(Throwable cause) { if (cause instanceof UnprocessedRequestException) { cause = cause.getCause(); } return cause instanceof ClosedStreamException || cause instanceof CancelledSubscriptionException || cause instanceof WriteTimeoutException || cause instanceof AbortedStreamException || (cause instanceof Http2Exception.StreamException && ((Http2Exception.StreamException) cause).error() == Http2Error.CANCEL); }
Example #27
Source File: Http2GoAwayHandlerTest.java From armeria with Apache License 2.0 | 5 votes |
@Test void testIsExpected() { final ByteBuf errorFlushing = Unpooled.copiedBuffer("Error flushing", StandardCharsets.UTF_8); final ByteBuf errorFlushing2 = Unpooled.copiedBuffer("Error flushing stream", StandardCharsets.UTF_8); final ByteBuf other = Unpooled.copiedBuffer("Other reasons", StandardCharsets.UTF_8); assertThat(isExpected(Http2Error.INTERNAL_ERROR.code(), errorFlushing)).isTrue(); assertThat(isExpected(Http2Error.PROTOCOL_ERROR.code(), errorFlushing)).isFalse(); assertThat(isExpected(Http2Error.INTERNAL_ERROR.code(), errorFlushing2)).isTrue(); assertThat(isExpected(Http2Error.INTERNAL_ERROR.code(), other)).isFalse(); }
Example #28
Source File: NettyClientHandler.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
private Status statusFromGoAway(long errorCode, byte[] debugData) { Status status = GrpcUtil.Http2Error.statusForCode((int) errorCode) .augmentDescription("Received Goaway"); if (debugData != null && debugData.length > 0) { // If a debug message was provided, use it. String msg = new String(debugData, UTF_8); status = status.augmentDescription(msg); } return status; }
Example #29
Source File: HttpResponseSubscriber.java From armeria with Apache License 2.0 | 5 votes |
private void failAndRespond(Throwable cause, AggregatedHttpResponse res, Http2Error error, boolean cancel) { final State oldState = setDone(cancel); final int id = req.id(); final int streamId = req.streamId(); final ChannelFuture future; final boolean isReset; if (oldState == State.NEEDS_HEADERS) { // ResponseHeaders is not sent yet, so we can send the response. final ResponseHeaders headers = res.headers(); logBuilder().responseHeaders(headers); final HttpData content = res.content(); // Did not write anything yet; we can send an error response instead of resetting the stream. if (content.isEmpty()) { future = responseEncoder.writeHeaders(id, streamId, headers, true); } else { responseEncoder.writeHeaders(id, streamId, headers, false); logBuilder().increaseResponseLength(content); future = responseEncoder.writeData(id, streamId, content, true); } isReset = false; } else { // Wrote something already; we have to reset/cancel the stream. future = responseEncoder.writeReset(id, streamId, error); isReset = true; } addCallbackAndFlush(cause, oldState, future, isReset); }
Example #30
Source File: NettyServerHandlerTest.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
@Test public void keepAliveEnforcer_enforcesPings() throws Exception { permitKeepAliveWithoutCalls = false; permitKeepAliveTimeInNanos = TimeUnit.HOURS.toNanos(1); manualSetUp(); for (int i = 0; i < KeepAliveEnforcer.MAX_PING_STRIKES + 1; i++) { channelRead(pingFrame(false /* isAck */, 1L)); } verifyWrite().writeGoAway(eq(ctx()), eq(0), eq(Http2Error.ENHANCE_YOUR_CALM.code()), any(ByteBuf.class), any(ChannelPromise.class)); assertFalse(channel().isActive()); }