@Override public final Http2LocalFlowController flowController() { return connection.local().flowController(); }
@Override public void createStream(Handler<AsyncResult<HttpClientStream>> completionHandler) { Future<HttpClientStream> fut; synchronized (this) { Http2Connection conn = handler.connection(); try { int id = conn.local().lastStreamCreated() == 0 ? 1 : conn.local().lastStreamCreated() + 2; Http2ClientStream stream = createStream(conn.local().createStream(id, false)); fut = Future.succeededFuture(stream); } catch (Exception e) { fut = Future.failedFuture(e); } } completionHandler.handle(fut); }
/** * Determines whether or not we're allowed to create a new stream right now. */ private boolean canCreateStream() { return connection().local().numActiveStreams() < maxConcurrentStreams; }
private static void incrementLocalWindowSize(ChannelPipeline pipeline, int delta) { try { final Http2Connection connection = pipeline.get(Http2ClientConnectionHandler.class).connection(); connection.local().flowController().incrementWindowSize(connection.connectionStream(), delta); } catch (Http2Exception e) { logger.warn("Failed to increment local flowController window size: {}", delta, e); } }
void writePushPromise(int streamId, Http2Headers headers, Handler<AsyncResult<Integer>> completionHandler) { int promisedStreamId = connection().local().incrementAndGetNextStreamId(); ChannelPromise promise = chctx.newPromise(); promise.addListener(fut -> { if (fut.isSuccess()) { completionHandler.handle(Future.succeededFuture(promisedStreamId)); } else { completionHandler.handle(Future.failedFuture(fut.cause())); } }); EventExecutor executor = chctx.executor(); if (executor.inEventLoop()) { _writePushPromise(streamId, promisedStreamId, headers, promise); } else { executor.execute(() -> { _writePushPromise(streamId, promisedStreamId, headers, promise); }); } }
private void tryExpandConnectionFlowControlWindow(Http2Connection connection) throws Http2Exception { if (initialFlowControlWindowSize != null) { // The window size in the settings explicitly excludes the connection window. So we manually manipulate the // connection window to accommodate more concurrent data per connection. Http2Stream connectionStream = connection.connectionStream(); Http2LocalFlowController localFlowController = connection.local().flowController(); final int delta = initialFlowControlWindowSize - localFlowController.initialWindowSize(connectionStream); // Only increase the connection window, don't decrease it. if (delta > 0) { // Double the delta just so a single stream can't exhaust the connection window. localFlowController.incrementWindowSize(connectionStream, Math.max(delta << 1, delta)); flush(ctx); } } }
final boolean consumeBytes(int streamId, int bytes) throws Http2Exception { Http2Stream stream = connection().stream(streamId); // Upgraded requests are ineligible for stream control. We add the null check // in case the stream has been deregistered. if (stream != null && streamId == Http2CodecUtil.HTTP_UPGRADE_STREAM_ID) { Boolean upgraded = stream.getProperty(upgradeKey); if (Boolean.TRUE.equals(upgraded)) { return false; } } return connection().local().flowController().consumeBytes(stream, bytes); }
public DefaultHttp2ConnectionDecoder(Http2Connection connection, Http2ConnectionEncoder encoder, Http2FrameReader frameReader, Http2PromisedRequestVerifier requestVerifier) { this.connection = checkNotNull(connection, "connection"); this.frameReader = checkNotNull(frameReader, "frameReader"); this.encoder = checkNotNull(encoder, "encoder"); this.requestVerifier = checkNotNull(requestVerifier, "requestVerifier"); if (connection.local().flowController() == null) { connection.local().flowController(new DefaultHttp2LocalFlowController(connection)); } connection.local().flowController().frameWriter(encoder.frameWriter()); }
/** * Get the next stream id either from the {@link HttpHeaders} object or HTTP/2 codec * * @param httpHeaders The HTTP/1.x headers object to look for the stream id * @return The stream id to use with this {@link HttpHeaders} object * @throws Exception If the {@code httpHeaders} object specifies an invalid stream id */ private int getStreamId(HttpHeaders httpHeaders) throws Exception { return httpHeaders.getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text(), connection().local().incrementAndGetNextStreamId()); }
private void increaseInitialConnectionWindow(int deltaBytes) throws Http2Exception { // The LocalFlowController is responsible for detecting over/under flow. connection().local().flowController().incrementWindowSize(connection().connectionStream(), deltaBytes); }
@Override public void remoteSettings(Http2Settings settings) throws Http2Exception { // Need to let the delegate decoder handle the settings first, so that it sees the // new setting before we attempt to create any new streams. super.remoteSettings(settings); // Get the updated value for SETTINGS_MAX_CONCURRENT_STREAMS. maxConcurrentStreams = connection().local().maxActiveStreams(); // Try to create new streams up to the new threshold. tryCreatePendingStreams(); }
final boolean consumeBytes(int streamId, int bytes) throws Http2Exception { Http2Stream stream = connection().stream(streamId); // Upgraded requests are ineligible for stream control. We add the null check // in case the stream has been deregistered. if (stream != null && streamId == Http2CodecUtil.HTTP_UPGRADE_STREAM_ID) { Boolean upgraded = stream.getProperty(upgradeKey); if (Boolean.TRUE.equals(upgraded)) { return false; } } return connection().local().flowController().consumeBytes(stream, bytes); }
private void onStreamActive0(Http2Stream stream) { if (connection().local().isValidStreamId(stream.id())) { return; } DefaultHttp2FrameStream stream2 = newStream().setStreamAndProperty(streamKey, stream); onHttp2StreamStateChanged(ctx, stream2); }
public Http2ConnectionBase(ContextInternal context, VertxHttp2ConnectionHandler handler) { super(context.owner(), handler.context(), context); this.handler = handler; this.handlerContext = chctx; this.windowSize = handler.connection().local().flowController().windowSize(handler.connection().connectionStream()); this.maxConcurrentStreams = io.vertx.core.http.Http2Settings.DEFAULT_MAX_CONCURRENT_STREAMS; }
private void onStreamActive0(Http2Stream stream) { if (connection().local().isValidStreamId(stream.id())) { return; } DefaultHttp2FrameStream stream2 = newStream().setStreamAndProperty(streamKey, stream); onHttp2StreamStateChanged(ctx, stream2); }
@Override public boolean visit(Http2FrameStream stream) { final int streamId = stream.id(); final DefaultHttp2StreamChannel childChannel = ((Http2MultiplexCodecStream) stream).channel; if (streamId > goAwayFrame.lastStreamId() && connection().local().isValidStreamId(streamId)) { childChannel.pipeline().fireUserEventTriggered(goAwayFrame.retainedDuplicate()); } return true; } });
private void tryExpandConnectionFlowControlWindow(Http2Connection connection) throws Http2Exception { if (initialFlowControlWindowSize != null) { // The window size in the settings explicitly excludes the connection window. So we manually manipulate the // connection window to accommodate more concurrent data per connection. Http2Stream connectionStream = connection.connectionStream(); Http2LocalFlowController localFlowController = connection.local().flowController(); final int delta = initialFlowControlWindowSize - localFlowController.initialWindowSize(connectionStream); // Only increase the connection window, don't decrease it. if (delta > 0) { // Double the delta just so a single stream can't exhaust the connection window. localFlowController.incrementWindowSize(connectionStream, Math.max(delta << 1, delta)); flush(ctx); } } }
final boolean consumeBytes(int streamId, int bytes) throws Http2Exception { Http2Stream stream = connection().stream(streamId); // Upgraded requests are ineligible for stream control. We add the null check // in case the stream has been deregistered. if (stream != null && streamId == Http2CodecUtil.HTTP_UPGRADE_STREAM_ID) { Boolean upgraded = stream.getProperty(upgradeKey); if (Boolean.TRUE.equals(upgraded)) { return false; } } return connection().local().flowController().consumeBytes(stream, bytes); }
private void increaseInitialConnectionWindow(int deltaBytes) throws Http2Exception { // The LocalFlowController is responsible for detecting over/under flow. connection().local().flowController().incrementWindowSize(connection().connectionStream(), deltaBytes); }
private void onStreamActive0(Http2Stream stream) { if (connection().local().isValidStreamId(stream.id())) { return; } DefaultHttp2FrameStream stream2 = newStream().setStreamAndProperty(streamKey, stream); onHttp2StreamStateChanged(ctx, stream2); }