Java 类io.netty.handler.codec.http2.Http2Error 实例源码

项目:armeria    文件:HttpRequestSubscriber.java   
private void failAndRespond(Throwable cause) {
    fail(cause);

    final Channel ch = ctx.channel();
    final Http2Error error;
    if (response.isOpen()) {
        response.close(cause);
        error = Http2Error.INTERNAL_ERROR;
    } else if (cause instanceof WriteTimeoutException || cause instanceof AbortedStreamException) {
        error = Http2Error.CANCEL;
    } else {
        Exceptions.logIfUnexpected(logger, ch,
                                   HttpSession.get(ch).protocol(),
                                   "a request publisher raised an exception", cause);
        error = Http2Error.INTERNAL_ERROR;
    }

    if (ch.isActive()) {
        encoder.writeReset(ctx, id, streamId(), error);
        ctx.flush();
    }
}
项目:armeria    文件:HttpResponseSubscriber.java   
@Override
public void onComplete() {
    if (!cancelTimeout() && reqCtx.requestTimeoutHandler() == null) {
        // We have already returned a failed response due to a timeout.
        return;
    }

    if (wroteNothing(state)) {
        logger.warn("{} Published nothing (or only informational responses): {}", ctx.channel(), service());
        responseEncoder.writeReset(ctx, req.id(), req.streamId(), Http2Error.INTERNAL_ERROR);
        return;
    }

    if (state != State.DONE) {
        write(HttpData.EMPTY_DATA, true, true);
    }
}
项目:armeria    文件:Http1ObjectEncoder.java   
@Override
protected ChannelFuture doWriteReset(ChannelHandlerContext ctx, int id, int streamId, Http2Error error) {
    // NB: this.minClosedId can be overwritten more than once when 3+ pipelined requests are received
    //     and they are handled by different threads simultaneously.
    //     e.g. when the 3rd request triggers a reset and then the 2nd one triggers another.
    minClosedId = Math.min(minClosedId, id);
    for (int i = minClosedId; i <= maxIdWithPendingWrites; i++) {
        final PendingWrites pendingWrites = pendingWritesMap.remove(i);
        for (;;) {
            final Entry<HttpObject, ChannelPromise> e = pendingWrites.poll();
            if (e == null) {
                break;
            }
            e.getValue().tryFailure(ClosedSessionException.get());
        }
    }

    final ChannelFuture f = ctx.write(Unpooled.EMPTY_BUFFER);
    if (currentId >= minClosedId) {
        f.addListener(ChannelFutureListener.CLOSE);
    }

    return f;
}
项目:grpc-java    文件:NettyServerHandler.java   
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;
    }
  });
}
项目:grpc-java    文件:NettyServerHandler.java   
@Override
public void onPingRead(ChannelHandlerContext ctx, ByteBuf 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, ex);
    }
  }
}
项目:grpc-java    文件:NettyClientHandler.java   
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;
    }
  });
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void keepAliveEnforcer_enforcesPings() throws Exception {
  permitKeepAliveWithoutCalls = false;
  permitKeepAliveTimeInNanos = TimeUnit.HOURS.toNanos(1);
  manualSetUp();

  ByteBuf payload = handler().ctx().alloc().buffer(8);
  payload.writeLong(1);
  for (int i = 0; i < KeepAliveEnforcer.MAX_PING_STRIKES + 1; i++) {
    channelRead(pingFrame(false /* isAck */, payload.slice()));
  }
  payload.release();
  verifyWrite().writeGoAway(eq(ctx()), eq(0), eq(Http2Error.ENHANCE_YOUR_CALM.code()),
      any(ByteBuf.class), any(ChannelPromise.class));
  assertFalse(channel().isActive());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@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();
  ByteBuf payload = handler().ctx().alloc().buffer(8);
  payload.writeLong(1);
  for (int i = 0; i < 10; i++) {
    future = enqueue(
        new SendGrpcFrameCommand(stream.transportState(), content().retainedSlice(), false));
    future.get();
    channel().releaseOutbound();
    channelRead(pingFrame(false /* isAck */, payload.slice()));
  }
  payload.release();
  verifyWrite(never()).writeGoAway(eq(ctx()), eq(STREAM_ID),
      eq(Http2Error.ENHANCE_YOUR_CALM.code()), any(ByteBuf.class), any(ChannelPromise.class));
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void keepAliveEnforcer_initialIdle() throws Exception {
  permitKeepAliveWithoutCalls = false;
  permitKeepAliveTimeInNanos = 0;
  manualSetUp();

  ByteBuf payload = handler().ctx().alloc().buffer(8);
  payload.writeLong(1);
  for (int i = 0; i < KeepAliveEnforcer.MAX_PING_STRIKES + 1; i++) {
    channelRead(pingFrame(false /* isAck */, payload.slice()));
  }
  payload.release();
  verifyWrite().writeGoAway(eq(ctx()), eq(0),
      eq(Http2Error.ENHANCE_YOUR_CALM.code()), any(ByteBuf.class), any(ChannelPromise.class));
  assertFalse(channel().isActive());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void keepAliveEnforcer_noticesActive() throws Exception {
  permitKeepAliveWithoutCalls = false;
  permitKeepAliveTimeInNanos = 0;
  manualSetUp();

  createStream();
  ByteBuf payload = handler().ctx().alloc().buffer(8);
  payload.writeLong(1);
  for (int i = 0; i < 10; i++) {
    channelRead(pingFrame(false /* isAck */, payload.slice()));
  }
  payload.release();
  verifyWrite(never()).writeGoAway(eq(ctx()), eq(STREAM_ID),
      eq(Http2Error.ENHANCE_YOUR_CALM.code()), any(ByteBuf.class), any(ChannelPromise.class));
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void keepAliveEnforcer_noticesInactive() throws Exception {
  permitKeepAliveWithoutCalls = false;
  permitKeepAliveTimeInNanos = 0;
  manualSetUp();

  createStream();
  channelRead(rstStreamFrame(STREAM_ID, (int) Http2Error.CANCEL.code()));
  ByteBuf payload = handler().ctx().alloc().buffer(8);
  payload.writeLong(1);
  for (int i = 0; i < KeepAliveEnforcer.MAX_PING_STRIKES + 1; i++) {
    channelRead(pingFrame(false /* isAck */, payload.slice()));
  }
  payload.release();
  verifyWrite().writeGoAway(eq(ctx()), eq(STREAM_ID),
      eq(Http2Error.ENHANCE_YOUR_CALM.code()), any(ByteBuf.class), any(ChannelPromise.class));
  assertFalse(channel().isActive());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void maxConnectionIdle_goAwaySent() throws Exception {
  maxConnectionIdleInNanos = TimeUnit.MILLISECONDS.toNanos(10L);
  manualSetUp();
  assertTrue(channel().isOpen());

  fakeClock().forwardNanos(maxConnectionIdleInNanos);

  // GO_AWAY sent
  verifyWrite().writeGoAway(
      eq(ctx()), eq(Integer.MAX_VALUE), eq(Http2Error.NO_ERROR.code()), any(ByteBuf.class),
      any(ChannelPromise.class));

  // channel closed
  assertTrue(!channel().isOpen());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void maxConnectionIdle_activeThenRst() throws Exception {
  maxConnectionIdleInNanos = TimeUnit.MILLISECONDS.toNanos(10L);
  manualSetUp();
  createStream();

  fakeClock().forwardNanos(maxConnectionIdleInNanos);

  // GO_AWAY not sent when active
  verifyWrite(never()).writeGoAway(
      any(ChannelHandlerContext.class), any(Integer.class), any(Long.class), any(ByteBuf.class),
      any(ChannelPromise.class));
  assertTrue(channel().isOpen());

  channelRead(rstStreamFrame(STREAM_ID, (int) Http2Error.CANCEL.code()));

  fakeClock().forwardNanos(maxConnectionIdleInNanos);

  // GO_AWAY sent
  verifyWrite().writeGoAway(
      eq(ctx()), eq(Integer.MAX_VALUE), eq(Http2Error.NO_ERROR.code()), any(ByteBuf.class),
      any(ChannelPromise.class));

  // channel closed
  assertTrue(!channel().isOpen());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void maxConnectionAge_goAwaySent() throws Exception {
  maxConnectionAgeInNanos = TimeUnit.MILLISECONDS.toNanos(10L);
  manualSetUp();
  assertTrue(channel().isOpen());

  fakeClock().forwardNanos(maxConnectionAgeInNanos);

  // GO_AWAY sent
  verifyWrite().writeGoAway(
      eq(ctx()), eq(Integer.MAX_VALUE), eq(Http2Error.NO_ERROR.code()), any(ByteBuf.class),
      any(ChannelPromise.class));

  // channel closed
  assertTrue(!channel().isOpen());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void maxConnectionAgeGrace_channelStillOpenDuringGracePeriod() throws Exception {
  maxConnectionAgeInNanos = TimeUnit.MILLISECONDS.toNanos(10L);
  maxConnectionAgeGraceInNanos = TimeUnit.MINUTES.toNanos(30L);
  manualSetUp();
  createStream();

  fakeClock().forwardNanos(maxConnectionAgeInNanos);

  verifyWrite().writeGoAway(
      eq(ctx()), eq(Integer.MAX_VALUE), eq(Http2Error.NO_ERROR.code()), any(ByteBuf.class),
      any(ChannelPromise.class));

  fakeClock().forwardTime(20, TimeUnit.MINUTES);

  // channel not closed yet
  assertTrue(channel().isOpen());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void maxConnectionAgeGrace_channelClosedAfterGracePeriod() throws Exception {
  maxConnectionAgeInNanos = TimeUnit.MILLISECONDS.toNanos(10L);
  maxConnectionAgeGraceInNanos = TimeUnit.MINUTES.toNanos(30L);
  manualSetUp();
  createStream();

  fakeClock().forwardNanos(maxConnectionAgeInNanos);

  verifyWrite().writeGoAway(
      eq(ctx()), eq(Integer.MAX_VALUE), eq(Http2Error.NO_ERROR.code()), any(ByteBuf.class),
      any(ChannelPromise.class));
  assertTrue(channel().isOpen());

  fakeClock().forwardNanos(maxConnectionAgeGraceInNanos);

  // channel closed
  assertTrue(!channel().isOpen());
}
项目:armeria    文件:Http2ResponseDecoder.java   
@Override
HttpResponseWrapper addResponse(
        int id, HttpRequest req, DecodedHttpResponse res, RequestLogBuilder logBuilder,
        long responseTimeoutMillis, long maxContentLength) {

    final HttpResponseWrapper resWrapper =
            super.addResponse(id, req, res, logBuilder, responseTimeoutMillis, maxContentLength);

    resWrapper.completionFuture().whenCompleteAsync((unused, cause) -> {
        if (cause != null) {
            // Ensure that the resWrapper is closed.
            // This is needed in case the response is aborted by the client.
            resWrapper.close(cause);

            // 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);
            if (conn.streamMayHaveExisted(streamId)) {
                final ChannelHandlerContext ctx = channel().pipeline().lastContext();
                encoder.writeRstStream(ctx, streamId, Http2Error.CANCEL.code(), ctx.newPromise());
                ctx.flush();
            }
        } else {
            // Ensure that the resWrapper is closed.
            // This is needed in case the response is aborted by the client.
            resWrapper.close();
        }
    }, channel().eventLoop());
    return resWrapper;
}
项目:armeria    文件:HttpResponseSubscriber.java   
private void onTimeout() {
    if (state != State.DONE) {
        reqCtx.setTimedOut();
        Runnable requestTimeoutHandler = reqCtx.requestTimeoutHandler();
        if (requestTimeoutHandler != null) {
            requestTimeoutHandler.run();
        } else {
            failAndRespond(RequestTimeoutException.get(),
                           SERVICE_UNAVAILABLE_MESSAGE, Http2Error.INTERNAL_ERROR);
        }
    }
}
项目:armeria    文件:HttpResponseSubscriber.java   
@Override
public void onError(Throwable cause) {
    if (cause instanceof HttpResponseException) {
        // Timeout may occur when the aggregation of the error response takes long.
        // If timeout occurs, respond with 503 Service Unavailable.
        ((HttpResponseException) cause).httpResponse()
                                       .aggregate(ctx.executor())
                                       .whenCompleteAsync((message, throwable) -> {
                                           if (throwable != null) {
                                               failAndRespond(throwable,
                                                              INTERNAL_SERVER_ERROR_MESSAGE,
                                                              Http2Error.CANCEL);
                                           } else {
                                               failAndRespond(cause, message, Http2Error.CANCEL);
                                           }
                                       }, ctx.executor());
    } else if (cause instanceof HttpStatusException) {
        failAndRespond(cause,
                       AggregatedHttpMessage.of(((HttpStatusException) cause).httpStatus()),
                       Http2Error.CANCEL);
    } else {
        logger.warn("{} Unexpected exception from a service or a response publisher: {}",
                    ctx.channel(), service(), cause);

        failAndRespond(cause, INTERNAL_SERVER_ERROR_MESSAGE, Http2Error.INTERNAL_ERROR);
    }
}
项目:armeria    文件:HttpResponseSubscriber.java   
private void failAndRespond(Throwable cause, AggregatedHttpMessage message, Http2Error error) {
    final HttpHeaders headers = message.headers();
    final HttpData content = message.content();

    logBuilder().responseHeaders(headers);
    logBuilder().increaseResponseLength(content.length());

    final State state = this.state; // Keep the state before calling fail() because it updates state.
    setDone();
    subscription.cancel();

    final int id = req.id();
    final int streamId = req.streamId();

    final ChannelFuture future;
    if (wroteNothing(state)) {
        // Did not write anything yet; we can send an error response instead of resetting the stream.
        if (content.isEmpty()) {
            future = responseEncoder.writeHeaders(ctx, id, streamId, headers, true);
        } else {
            responseEncoder.writeHeaders(ctx, id, streamId, headers, false);
            future = responseEncoder.writeData(ctx, id, streamId, content, true);
        }
    } else {
        // Wrote something already; we have to reset/cancel the stream.
        future = responseEncoder.writeReset(ctx, id, streamId, error);
    }

    if (state != State.DONE) {
        future.addListener(unused -> {
            // Write an access log always with a cause. Respect the first specified cause.
            if (tryComplete()) {
                logBuilder().endResponse(cause);
                accessLogWriter.accept(reqCtx.log());
            }
        });
    }
    ctx.flush();
}
项目:armeria    文件:Http2RequestDecoder.java   
@Override
public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception {
    final HttpRequestWriter req = requests.get(streamId);
    if (req == null) {
        throw connectionError(PROTOCOL_ERROR,
                              "received a RST_STREAM frame for an unknown stream: %d", streamId);
    }

    req.close(streamError(
            streamId, Http2Error.valueOf(errorCode), "received a RST_STREAM frame"));
}
项目:armeria    文件:Http2GoAwayListener.java   
private void onGoAway(String sentOrReceived, int lastStreamId, long errorCode, ByteBuf debugData) {
    if (errorCode != Http2Error.NO_ERROR.code()) {
        if (logger.isWarnEnabled()) {
            logger.warn("{} {} a GOAWAY frame: lastStreamId={}, errorCode={}, debugData=\"{}\"",
                        ch, sentOrReceived, lastStreamId, errorStr(errorCode),
                        debugData.toString(StandardCharsets.UTF_8));
        }
    } else {
        if (logger.isDebugEnabled()) {
            logger.debug("{} {} a GOAWAY frame: lastStreamId={}, errorCode=NO_ERROR",
                         ch, sentOrReceived, lastStreamId);
        }
    }
}
项目:armeria    文件:HttpObjectEncoder.java   
/**
 * 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.
 */
public final ChannelFuture writeReset(ChannelHandlerContext ctx, int id, int streamId, Http2Error error) {

    if (closed) {
        return newFailedFuture(ctx);
    }

    return doWriteReset(ctx, id, streamId, error);
}
项目:armeria    文件:Http2ObjectEncoder.java   
@Override
protected ChannelFuture doWriteReset(ChannelHandlerContext ctx, int id, int streamId, Http2Error error) {
    final ChannelFuture future = validateStream(ctx, streamId);
    if (future != null) {
        return future;
    }

    return encoder.writeRstStream(ctx, streamId, error.code(), ctx.newPromise());
}
项目:grpc-java    文件:NettyServerHandler.java   
private void cancelStream(ChannelHandlerContext ctx, CancelServerStreamCommand cmd,
    ChannelPromise promise) {
  // Notify the listener if we haven't already.
  cmd.stream().transportReportStatus(cmd.reason());
  // Terminate the stream.
  encoder().writeRstStream(ctx, cmd.stream().id(), Http2Error.CANCEL.code(), promise);
}
项目:grpc-java    文件:NettyClientHandler.java   
/**
 * 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, false /*stop delivery*/, new Metadata());
    if (keepAliveManager != null) {
      keepAliveManager.onDataReceived();
    }
  }
}
项目:grpc-java    文件:NettyClientHandler.java   
/**
 * Cancels this stream.
 */
private void cancelStream(ChannelHandlerContext ctx, CancelClientStreamCommand cmd,
    ChannelPromise promise) {
  NettyClientStream.TransportState stream = cmd.stream();
  stream.transportReportStatus(cmd.reason(), true, new Metadata());
  encoder().writeRstStream(ctx, stream.id(), Http2Error.CANCEL.code(), promise);
}
项目:grpc-java    文件:NettyClientHandler.java   
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;
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@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());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void closeShouldCloseChannel() throws Exception {
  manualSetUp();
  handler().close(ctx(), newPromise());

  verifyWrite().writeGoAway(eq(ctx()), eq(0), eq(Http2Error.NO_ERROR.code()),
      eq(Unpooled.EMPTY_BUFFER), any(ChannelPromise.class));

  // Verify that the channel was closed.
  assertFalse(channel().isOpen());
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void cancelShouldSendRstStream() throws Exception {
  manualSetUp();
  createStream();
  enqueue(new CancelServerStreamCommand(stream.transportState(), Status.DEADLINE_EXCEEDED));
  verifyWrite().writeRstStream(eq(ctx()), eq(stream.transportState().id()),
      eq(Http2Error.CANCEL.code()), any(ChannelPromise.class));
}
项目:grpc-java    文件:NettyServerHandlerTest.java   
@Test
public void keepAliveManagerOnDataReceived_rstStreamRead() throws Exception {
  manualSetUp();
  createStream();
  verify(spyKeepAliveManager).onDataReceived(); // received headers

  channelRead(rstStreamFrame(STREAM_ID, (int) Http2Error.CANCEL.code()));

  verify(spyKeepAliveManager, times(2)).onDataReceived();
  verify(spyKeepAliveManager, never()).onTransportTermination();
}
项目:grpc-java    文件:NettyClientHandlerTest.java   
@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);
}
项目:grpc-java    文件:NettyClientHandlerTest.java   
@Test
public void cancelDeadlineExceededShouldSucceed() throws Exception {
  createStream();
  cancelStream(Status.DEADLINE_EXCEEDED);

  verifyWrite().writeRstStream(eq(ctx()), eq(3), eq(Http2Error.CANCEL.code()),
      any(ChannelPromise.class));
}
项目:grpc-java    文件:NettyClientHandlerTest.java   
/**
 * Although nobody is listening to an exception should it occur during cancel(), we don't want an
 * exception to be thrown because it would negatively impact performance, and we don't want our
 * users working around around such performance issues.
 */
@Test
public void cancelTwiceShouldSucceed() throws Exception {
  createStream();

  cancelStream(Status.CANCELLED);

  verifyWrite().writeRstStream(any(ChannelHandlerContext.class), eq(3),
      eq(Http2Error.CANCEL.code()), any(ChannelPromise.class));

  ChannelFuture future = cancelStream(Status.CANCELLED);
  assertTrue(future.isSuccess());
}
项目:grpc-java    文件:NettyClientHandlerTest.java   
@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());
}
项目:armeria    文件:HttpResponseSubscriber.java   
private IllegalStateException newIllegalStateException(String msg) {
    final IllegalStateException cause = new IllegalStateException(msg);
    failAndRespond(cause, INTERNAL_SERVER_ERROR_MESSAGE, Http2Error.INTERNAL_ERROR);
    return cause;
}
项目:armeria    文件:Http2GoAwayListener.java   
private static String errorStr(long errorCode) {
    final Http2Error error = Http2Error.valueOf(errorCode);
    return error != null ? error.toString() + '(' + errorCode + ')'
                         : "UNKNOWN(" + errorCode + ')';
}
项目:armeria    文件:HttpObjectEncoder.java   
protected abstract ChannelFuture doWriteReset(
ChannelHandlerContext ctx, int id, int streamId, Http2Error error);
项目:armeria    文件:Http2ClientSettingsTest.java   
@Test
public void maxFrameSize() throws Exception {

    try (ServerSocket ss = new ServerSocket(0)) {
        final int port = ss.getLocalPort();

        final ClientFactory clientFactory = new ClientFactoryBuilder()
                .useHttp2Preface(true)
                .http2MaxFrameSize(DEFAULT_MAX_FRAME_SIZE * 2) // == 16384 * 2
                .build();

        final HttpClient client = HttpClient.of(clientFactory, "http://127.0.0.1:" + port);
        final CompletableFuture<AggregatedHttpMessage> future = client.get("/").aggregate();

        try (Socket s = ss.accept()) {
            final InputStream in = s.getInputStream();
            final BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());

            readBytes(in, connectionPrefaceBuf().capacity()); // Read the connection preface and discard it.

            // Read a SETTINGS frame and validate it.
            assertSettingsFrameOfMaxFrameSize(in);

            sendEmptySettingsAndAckFrame(bos);

            readBytes(in, 9); // Read a SETTINGS_ACK frame and discard it.
            readHeadersFrame(in); // Read a HEADERS frame and discard it.

            sendHeaderFrame(bos);

            ////////////////////////////////////////
            // Transmission of data gets started. //
            ////////////////////////////////////////

            // Send a DATA frame that indicates sending data as much as 0x8000 for stream id 03.
            bos.write(new byte[] { 0x00, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 });
            bos.write(EMPTY_DATA);
            bos.write(EMPTY_DATA);
            bos.flush();

            readBytes(in, 13); // Read a WINDOW_UPDATE frame for connection and discard it.
            readBytes(in, 13); // Read a WINDOW_UPDATE frame for stream id 03 and discard it.

            // Send a DATA frame that exceed MAX_FRAME_SIZE by 1.
            bos.write(new byte[] { 0x00, (byte) 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 });
            bos.flush(); // Triggers the client to send a GOAWAY frame for the connection.

            // The client send a GOAWAY frame and the server read it.
            final ByteBuf buffer = readGoAwayFrame(in);
            final DefaultHttp2FrameReader frameReader = new DefaultHttp2FrameReader();

            final CountDownLatch latch = new CountDownLatch(1);
            frameReader.readFrame(null, buffer, new Http2EventAdapter() {
                @Override
                public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long errorCode,
                                         ByteBuf debugData)
                        throws Http2Exception {
                    assertThat(lastStreamId).isZero(); // 0: connection error
                    assertThat(errorCode).isEqualTo(Http2Error.FRAME_SIZE_ERROR.code());
                    latch.countDown();
                }
            });
            latch.await();
            buffer.release();
        }
    }
}