io.netty.handler.codec.http2.Http2Stream Java Examples

The following examples show how to use io.netty.handler.codec.http2.Http2Stream. 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: NettyHandlerTestBase.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@Test
public void windowShouldNotExceedMaxWindowSize() throws Exception {
  manualSetUp();
  makeStream();
  AbstractNettyHandler handler = (AbstractNettyHandler) handler();
  handler.setAutoTuneFlowControl(true);
  Http2Stream connectionStream = connection().connectionStream();
  Http2LocalFlowController localFlowController = connection().local().flowController();
  int maxWindow = handler.flowControlPing().maxWindow();

  handler.flowControlPing().setDataSizeAndSincePing(maxWindow);
  long payload = handler.flowControlPing().payload();
  channelRead(pingFrame(true, payload));

  assertEquals(maxWindow, localFlowController.initialWindowSize(connectionStream));
}
 
Example #2
Source File: NettyServerHandler.java    From grpc-nebula-java with Apache License 2.0 6 votes vote down vote up
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 #3
Source File: Http2ServerChannelHandler.java    From sofa-rpc with Apache License 2.0 6 votes vote down vote up
@Override
public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) {
    int processed = data.readableBytes() + padding;

    Http2Stream http2Stream = connection().stream(streamId);
    ByteBuf msg = http2Stream.getProperty(messageKey);
    if (msg == null) {
        msg = ctx.alloc().buffer();
        http2Stream.setProperty(messageKey, msg);
    }
    final int dataReadableBytes = data.readableBytes();
    msg.writeBytes(data, data.readerIndex(), dataReadableBytes);

    if (endOfStream) {
        // read cached http2 header from stream
        Http2Headers headers = http2Stream.getProperty(headerKey);
        handleRequest(ctx, streamId, headers, msg);
    }
    return processed;
}
 
Example #4
Source File: NettyClientHandler.java    From grpc-nebula-java with Apache License 2.0 6 votes vote down vote up
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: NettyClientHandler.java    From grpc-nebula-java with Apache License 2.0 6 votes vote down vote up
/**
 * Handler for a GOAWAY being received. Fails any streams created after the
 * last known stream.
 */
private void goingAway(Status status) {
  lifecycleManager.notifyShutdown(status);
  final Status goAwayStatus = lifecycleManager.getShutdownStatus();
  final int lastKnownStream = connection().local().lastStreamKnownByPeer();
  try {
    connection().forEachActiveStream(new Http2StreamVisitor() {
      @Override
      public boolean visit(Http2Stream stream) throws Http2Exception {
        if (stream.id() > lastKnownStream) {
          NettyClientStream.TransportState clientStream = clientStream(stream);
          if (clientStream != null) {
            clientStream.transportReportStatus(
                goAwayStatus, RpcProgress.REFUSED, false, new Metadata());
          }
          stream.close();
        }
        return true;
      }
    });
  } catch (Http2Exception e) {
    throw new RuntimeException(e);
  }
}
 
Example #6
Source File: NettyHandlerTestBase.java    From grpc-nebula-java with Apache License 2.0 6 votes vote down vote up
@Test
public void windowShouldNotExceedMaxWindowSize() throws Exception {
  manualSetUp();
  makeStream();
  AbstractNettyHandler handler = (AbstractNettyHandler) handler();
  handler.setAutoTuneFlowControl(true);
  Http2Stream connectionStream = connection().connectionStream();
  Http2LocalFlowController localFlowController = connection().local().flowController();
  int maxWindow = handler.flowControlPing().maxWindow();

  handler.flowControlPing().setDataSizeSincePing(maxWindow);
  long payload = handler.flowControlPing().payload();
  channelRead(pingFrame(true, payload));

  assertEquals(maxWindow, localFlowController.initialWindowSize(connectionStream));
}
 
Example #7
Source File: NoPriorityByteDistributionBenchmark.java    From netty-4.1.22 with Apache License 2.0 6 votes vote down vote up
@Override
public void write(Http2Stream stream, int numBytes) {
    if (numBytes > 0) {
        // Add the data to the refresher so that it can be given back to the
        // stream at the end of the iteration.
        DataRefresher refresher = dataRefresher(stream);
        refresher.add(numBytes);

        ++counters.numWrites;
        counters.totalBytes += numBytes;
        if (numBytes < counters.minWriteSize) {
            counters.minWriteSize = numBytes;
        }
        if (numBytes > counters.maxWriteSize) {
            counters.maxWriteSize = numBytes;
        }
    }

    delegate.write(stream, numBytes);
}
 
Example #8
Source File: Http2MultiplexedChannelPool.java    From aws-sdk-java-v2 with Apache License 2.0 6 votes vote down vote up
/**
 * By default, connection window size is a constant value:
 * connectionWindowSize = 65535 + (configureInitialWindowSize - 65535) * 2.
 * See https://github.com/netty/netty/blob/5c458c9a98d4d3d0345e58495e017175156d624f/codec-http2/src/main/java/io/netty
 * /handler/codec/http2/Http2FrameCodec.java#L255
 * We should expand connection window so that the window size proportional to the number of concurrent streams within the
 * connection.
 * Note that when {@code WINDOW_UPDATE} will be sent depends on the processedWindow in DefaultHttp2LocalFlowController.
 */
private void tryExpandConnectionWindow(Channel parentChannel) {
    doInEventLoop(parentChannel.eventLoop(), () -> {
        Http2Connection http2Connection = parentChannel.attr(HTTP2_CONNECTION).get();
        Integer initialWindowSize = parentChannel.attr(HTTP2_INITIAL_WINDOW_SIZE).get();

        Validate.notNull(http2Connection, "http2Connection should not be null on channel " + parentChannel);
        Validate.notNull(http2Connection, "initialWindowSize should not be null on channel " + parentChannel);

        Http2Stream connectionStream = http2Connection.connectionStream();
        log.debug(() -> "Expanding connection window size for " + parentChannel + " by " + initialWindowSize);
        try {
            Http2LocalFlowController localFlowController = http2Connection.local().flowController();
            localFlowController.incrementWindowSize(connectionStream, initialWindowSize);

        } catch (Http2Exception e) {
            log.warn(() -> "Failed to increment windowSize of connection " + parentChannel, e);
        }
    });
}
 
Example #9
Source File: Http2RequestDecoder.java    From armeria with Apache License 2.0 6 votes vote down vote up
private void writeErrorResponse(ChannelHandlerContext ctx, int streamId, HttpResponseStatus status,
                                @Nullable ByteBuf content) throws Http2Exception {
    final ByteBuf data =
            content != null ? content
                            : Unpooled.wrappedBuffer(status.toString().getBytes(StandardCharsets.UTF_8));

    writer.writeHeaders(
            ctx, streamId,
            new DefaultHttp2Headers(false)
                    .status(status.codeAsText())
                    .set(HttpHeaderNames.CONTENT_TYPE, MediaType.PLAIN_TEXT_UTF_8.toString())
                    .setInt(HttpHeaderNames.CONTENT_LENGTH, data.readableBytes()),
            0, false, ctx.voidPromise());

    writer.writeData(ctx, streamId, data, 0, true, ctx.voidPromise());

    final Http2Stream stream = writer.connection().stream(streamId);
    if (stream != null && writer.flowController().hasFlowControlled(stream)) {
        // Ensure to flush the error response if it's flow-controlled so that it is sent
        // before an RST_STREAM frame.
        writer.flowController().writePendingBytes();
    }
}
 
Example #10
Source File: Http2ObjectEncoder.java    From armeria with Apache License 2.0 6 votes vote down vote up
/**
 * Returns {@code true} if the stream with the given {@code streamId} has been created and is writable.
 * Note that this method will return {@code false} for the stream which was not created yet.
 */
protected final boolean isStreamPresentAndWritable(int streamId) {
    final Http2Stream stream = encoder.connection().stream(streamId);
    if (stream == null) {
        return false;
    }

    switch (stream.state()) {
        case RESERVED_LOCAL:
        case OPEN:
        case HALF_CLOSED_REMOTE:
            return true;
        default:
            // The response has been sent already.
            return false;
    }
}
 
Example #11
Source File: NettyServerHandler.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
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 #12
Source File: NettyClientHandler.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
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 #13
Source File: NettyClientHandler.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
/**
 * Handler for a GOAWAY being received. Fails any streams created after the
 * last known stream. May only be called during a read.
 */
private void goingAway(Status status) {
  lifecycleManager.notifyGracefulShutdown(status);
  // Try to allocate as many in-flight streams as possible, to reduce race window of
  // https://github.com/grpc/grpc-java/issues/2562 . To be of any help, the server has to
  // gracefully shut down the connection with two GOAWAYs. gRPC servers generally send a PING
  // after the first GOAWAY, so they can very precisely detect when the GOAWAY has been
  // processed and thus this processing must be in-line before processing additional reads.

  // This can cause reentrancy, but should be minor since it is normal to handle writes in
  // response to a read. Also, the call stack is rather shallow at this point
  clientWriteQueue.drainNow();
  lifecycleManager.notifyShutdown(status);

  final Status goAwayStatus = lifecycleManager.getShutdownStatus();
  final int lastKnownStream = connection().local().lastStreamKnownByPeer();
  try {
    connection().forEachActiveStream(new Http2StreamVisitor() {
      @Override
      public boolean visit(Http2Stream stream) throws Http2Exception {
        if (stream.id() > lastKnownStream) {
          NettyClientStream.TransportState clientStream = clientStream(stream);
          if (clientStream != null) {
            clientStream.transportReportStatus(
                goAwayStatus, RpcProgress.REFUSED, false, new Metadata());
          }
          stream.close();
        }
        return true;
      }
    });
  } catch (Http2Exception e) {
    throw new RuntimeException(e);
  }
}
 
Example #14
Source File: NettyServerHandlerTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Test
public void connectionWindowShouldBeOverridden() throws Exception {
  flowControlWindow = 1048576; // 1MiB
  manualSetUp();

  Http2Stream connectionStream = connection().connectionStream();
  Http2LocalFlowController localFlowController = connection().local().flowController();
  int actualInitialWindowSize = localFlowController.initialWindowSize(connectionStream);
  int actualWindowSize = localFlowController.windowSize(connectionStream);
  assertEquals(flowControlWindow, actualWindowSize);
  assertEquals(flowControlWindow, actualInitialWindowSize);
}
 
Example #15
Source File: NettyClientHandlerTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Override
protected NettyClientHandler newHandler() throws Http2Exception {
  Http2Connection connection = new DefaultHttp2Connection(false);

  // Create and close a stream previous to the nextStreamId.
  Http2Stream stream = connection.local().createStream(streamId - 2, true);
  stream.close();

  final Ticker ticker = new Ticker() {
    @Override
    public long read() {
      return nanoTime;
    }
  };
  Supplier<Stopwatch> stopwatchSupplier = new Supplier<Stopwatch>() {
    @Override
    public Stopwatch get() {
      return Stopwatch.createUnstarted(ticker);
    }
  };
  return NettyClientHandler.newHandler(
      connection,
      frameReader(),
      frameWriter(),
      lifecycleManager,
      mockKeepAliveManager,
      false,
      flowControlWindow,
      maxHeaderListSize,
      stopwatchSupplier,
      tooManyPingsRunnable,
      transportTracer,
      Attributes.EMPTY,
      "someauthority");
}
 
Example #16
Source File: AbstractNettyHandler.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
/**
 * Sends initial connection window to the remote endpoint if necessary.
 */
private void sendInitialConnectionWindow() throws Http2Exception {
  if (!initialWindowSent && ctx.channel().isActive()) {
    Http2Stream connectionStream = connection().connectionStream();
    int currentSize = connection().local().flowController().windowSize(connectionStream);
    int delta = initialConnectionWindow - currentSize;
    decoder().flowController().incrementWindowSize(connectionStream, delta);
    initialWindowSent = true;
    ctx.flush();
  }
}
 
Example #17
Source File: NettyClientHandler.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
private Http2Stream requireHttp2Stream(int streamId) {
  Http2Stream stream = connection().stream(streamId);
  if (stream == null) {
    // This should never happen.
    throw new AssertionError("Stream does not exist: " + streamId);
  }
  return stream;
}
 
Example #18
Source File: NettyClientHandlerTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Test
public void connectionWindowShouldBeOverridden() throws Exception {
  flowControlWindow = 1048576; // 1MiB
  setUp();

  Http2Stream connectionStream = connection().connectionStream();
  Http2LocalFlowController localFlowController = connection().local().flowController();
  int actualInitialWindowSize = localFlowController.initialWindowSize(connectionStream);
  int actualWindowSize = localFlowController.windowSize(connectionStream);
  assertEquals(flowControlWindow, actualWindowSize);
  assertEquals(flowControlWindow, actualInitialWindowSize);
  assertEquals(1048576, actualWindowSize);
}
 
Example #19
Source File: NettyServerStream.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
public TransportState(
    NettyServerHandler handler,
    EventLoop eventLoop,
    Http2Stream http2Stream,
    int maxMessageSize,
    StatsTraceContext statsTraceCtx,
    TransportTracer transportTracer,
    String methodName) {
  super(maxMessageSize, statsTraceCtx, transportTracer);
  this.http2Stream = checkNotNull(http2Stream, "http2Stream");
  this.handler = checkNotNull(handler, "handler");
  this.eventLoop = eventLoop;
  this.tag = PerfMark.createTag(methodName, http2Stream.id());
}
 
Example #20
Source File: NettyClientStream.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
/**
 * Sets the underlying Netty {@link Http2Stream} for this stream. This must be called in the
 * context of the transport thread.
 */
public void setHttp2Stream(Http2Stream http2Stream) {
  checkNotNull(http2Stream, "http2Stream");
  checkState(this.http2Stream == null, "Can only set http2Stream once");
  this.http2Stream = http2Stream;

  // Now that the stream has actually been initialized, call the listener's onReady callback if
  // appropriate.
  onStreamAllocated();
  getTransportTracer().reportLocalStreamStarted();
}
 
Example #21
Source File: NettyFlowControlTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Override
public void onNext(StreamingOutputCallResponse value) {
  GrpcHttp2ConnectionHandler grpcHandler = grpcHandlerRef.get();
  Http2Stream connectionStream = grpcHandler.connection().connectionStream();
  lastWindow = grpcHandler.decoder().flowController().initialWindowSize(connectionStream);
  if (lastWindow >= expectedWindow) {
    onCompleted();
  }
}
 
Example #22
Source File: NettyServerHandler.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
/**
 * Handler for the Channel shutting down.
 */
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  try {
    if (keepAliveManager != null) {
      keepAliveManager.onTransportTermination();
    }
    if (maxConnectionIdleManager != null) {
      maxConnectionIdleManager.onTransportTermination();
    }
    if (maxConnectionAgeMonitor != null) {
      maxConnectionAgeMonitor.cancel(false);
    }
    final Status status =
        Status.UNAVAILABLE.withDescription("connection terminated for unknown reason");
    // Any streams that are still active must be closed
    connection().forEachActiveStream(new Http2StreamVisitor() {
      @Override
      public boolean visit(Http2Stream stream) throws Http2Exception {
        NettyServerStream.TransportState serverStream = serverStream(stream);
        if (serverStream != null) {
          serverStream.transportReportStatus(status);
        }
        return true;
      }
    });
  } finally {
    super.channelInactive(ctx);
  }
}
 
Example #23
Source File: Http2ObjectEncoder.java    From armeria with Apache License 2.0 5 votes vote down vote up
@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 #24
Source File: NettyServerHandler.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the given processed bytes back to inbound flow control.
 */
void returnProcessedBytes(Http2Stream http2Stream, int bytes) {
  try {
    decoder().flowController().consumeBytes(http2Stream, bytes);
  } catch (Http2Exception e) {
    throw new RuntimeException(e);
  }
}
 
Example #25
Source File: Http2RequestDecoder.java    From armeria with Apache License 2.0 5 votes vote down vote up
private static boolean isWritable(Http2Stream stream) {
    switch (stream.state()) {
        case OPEN:
        case HALF_CLOSED_REMOTE:
            return !stream.isHeadersSent();
        default:
            return false;
    }
}
 
Example #26
Source File: Http2RequestDecoder.java    From armeria with Apache License 2.0 5 votes vote down vote up
@Override
public void onStreamClosed(Http2Stream stream) {
    goAwayHandler.onStreamClosed(channel, stream);

    final DecodedHttpRequest req = requests.remove(stream.id());
    if (req != null) {
        // Ignored if the stream has already been closed.
        req.close(ClosedStreamException.get());
    }
}
 
Example #27
Source File: Http2ResponseDecoder.java    From armeria with Apache License 2.0 5 votes vote down vote up
@Override
public void onStreamClosed(Http2Stream stream) {
    goAwayHandler.onStreamClosed(channel(), stream);

    final HttpResponseWrapper res = getResponse(streamIdToId(stream.id()), true);
    if (res == null) {
        return;
    }

    if (!goAwayHandler.receivedGoAway()) {
        res.close(ClosedStreamException.get());
        return;
    }

    final int lastStreamId = conn.local().lastStreamKnownByPeer();
    if (stream.id() > lastStreamId) {
        res.close(UnprocessedRequestException.of(GoAwayReceivedException.get()));
    } else {
        res.close(ClosedStreamException.get());
    }

    // Send a GOAWAY frame if the connection has been scheduled for disconnection and
    // it did not receive or send a GOAWAY frame.
    if (needsToDisconnectNow() && !goAwayHandler.sentGoAway() && !goAwayHandler.receivedGoAway()) {
        channel().close();
    }
}
 
Example #28
Source File: Http2Handler.java    From xrpc with Apache License 2.0 5 votes vote down vote up
/** Removes all requests and handlers for a given stream. */
@Override
public void onStreamRemoved(Http2Stream stream) {
  int id = stream.id();
  requests.remove(id);
  handlers.remove(id);
}
 
Example #29
Source File: NettyClientStream.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
/**
 * Sets the underlying Netty {@link Http2Stream} for this stream. This must be called in the
 * context of the transport thread.
 */
public void setHttp2Stream(Http2Stream http2Stream) {
  checkNotNull(http2Stream, "http2Stream");
  checkState(this.http2Stream == null, "Can only set http2Stream once");
  this.http2Stream = http2Stream;

  // Now that the stream has actually been initialized, call the listener's onReady callback if
  // appropriate.
  onStreamAllocated();
  getTransportTracer().reportLocalStreamStarted();
}
 
Example #30
Source File: NettyServerHandler.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
/**
 * Handler for the Channel shutting down.
 */
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  try {
    if (keepAliveManager != null) {
      keepAliveManager.onTransportTermination();
    }
    if (maxConnectionIdleManager != null) {
      maxConnectionIdleManager.onTransportTermination();
    }
    if (maxConnectionAgeMonitor != null) {
      maxConnectionAgeMonitor.cancel(false);
    }
    final Status status =
        Status.UNAVAILABLE.withDescription("connection terminated for unknown reason");
    // Any streams that are still active must be closed
    connection().forEachActiveStream(new Http2StreamVisitor() {
      @Override
      public boolean visit(Http2Stream stream) throws Http2Exception {
        NettyServerStream.TransportState serverStream = serverStream(stream);
        if (serverStream != null) {
          serverStream.transportReportStatus(status);
        }
        return true;
      }
    });
  } finally {
    super.channelInactive(ctx);
  }
}