@Override public Http2RemoteFlowController flowController() { return delegate.flowController(); }
@Override public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency, short weight, boolean exclusive) throws Http2Exception { encoder.flowController().updateDependencyTree(streamId, streamDependency, weight, exclusive); listener.onPriorityRead(ctx, streamId, streamDependency, weight, exclusive); }
private void _writeData(Http2Stream stream, ByteBuf chunk, boolean end, ChannelPromise promise) { encoder().writeData(chctx, stream.id(), chunk, 0, end, promise); Http2RemoteFlowController controller = encoder().flowController(); if (!controller.isWritable(stream) || end) { try { encoder().flowController().writePendingBytes(); } catch (Http2Exception e) { onError(chctx, true, e); } } chctx.channel().flush(); }
@Override public void flush(ChannelHandlerContext ctx) { try { // Trigger pending writes in the remote flow controller. encoder.flowController().writePendingBytes(); ctx.flush(); } catch (Http2Exception e) { onError(ctx, true, e); } catch (Throwable cause) { onError(ctx, true, connectionError(INTERNAL_ERROR, cause, "Error flushing")); } }
@Override public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { // Writability is expected to change while we are writing. We cannot allow this event to trigger reentering // the allocation and write loop. Reentering the event loop will lead to over or illegal allocation. try { if (ctx.channel().isWritable()) { flush(ctx); } encoder.flowController().channelWritabilityChanged(); } finally { super.channelWritabilityChanged(ctx); } }
private Http2ClientStream createStream(Http2Stream stream) { boolean writable = handler.encoder().flowController().isWritable(stream); Http2ClientStream clientStream = new Http2ClientStream(this, stream, writable); streams.put(clientStream.stream.id(), clientStream); return clientStream; }
@Override public void handle(AsyncResult<Integer> ar) { if (ar.succeeded()) { synchronized (Http2ServerConnection.this) { int promisedStreamId = ar.result(); String contentEncoding = HttpUtils.determineContentEncoding(headers_); Http2Stream promisedStream = handler.connection().stream(promisedStreamId); boolean writable = handler.encoder().flowController().isWritable(promisedStream); Push push = new Push(promisedStream, contentEncoding, method, path, writable, completionHandler); push.priority(streamPriority); streams.put(promisedStreamId, push); if (maxConcurrentStreams == null || concurrentStreams < maxConcurrentStreams) { concurrentStreams++; context.executeFromIO(v -> push.complete()); } else { pendingPushes.add(push); } } } else { context.executeFromIO(v -> { completionHandler.handle(Future.failedFuture(ar.cause())); }); } } });
public VertxHttp2ConnectionHandler( Function<VertxHttp2ConnectionHandler<C>, C> connectionFactory, boolean useDecompressor, Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder, Http2Settings initialSettings) { super(decoder, encoder, initialSettings); this.connectionFactory = connectionFactory; this.useDecompressor = useDecompressor; encoder().flowController().listener(s -> { if (connection != null) { connection.onStreamWritabilityChanged(s); } }); connection().addListener(this); }
private Http2ServerRequestImpl createRequest(int streamId, Http2Headers headers, boolean streamEnded) { Http2Stream stream = handler.connection().stream(streamId); String contentEncoding = options.isCompressionSupported() ? HttpUtils.determineContentEncoding(headers) : null; boolean writable = handler.encoder().flowController().isWritable(stream); return new Http2ServerRequestImpl(this, stream, metrics, serverOrigin, headers, contentEncoding, writable, streamEnded); }
@Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { // Initialize the encoder, decoder, flow controllers, and internal state. encoder.lifecycleManager(this); decoder.lifecycleManager(this); encoder.flowController().channelHandlerContext(ctx); decoder.flowController().channelHandlerContext(ctx); byteDecoder = new PrefaceDecoder(ctx); }
@Override public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement) throws Http2Exception { Http2Stream stream = connection.stream(streamId); if (stream == null || stream.state() == CLOSED || streamCreatedAfterGoAwaySent(streamId)) { // Ignore this frame. verifyStreamMayHaveExisted(streamId); return; } // Update the outbound flow control window. encoder.flowController().incrementWindowSize(stream, windowSizeIncrement); listener.onWindowUpdateRead(ctx, streamId, windowSizeIncrement); }
private void writeErrorResponse(ChannelHandlerContext ctx, int streamId, HttpResponseStatus status) throws Http2Exception { final byte[] content = 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, content.length), 0, false, ctx.voidPromise()); writer.writeData(ctx, streamId, Unpooled.wrappedBuffer(content), 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(); } }
encoder.flowController().updateDependencyTree(streamId, streamDependency, weight, exclusive);
private void _writeData(Http2Stream stream, ByteBuf chunk, boolean end, ChannelPromise promise) { encoder().writeData(chctx, stream.id(), chunk, 0, end, promise); Http2RemoteFlowController controller = encoder().flowController(); if (!controller.isWritable(stream) || end) { try { encoder().flowController().writePendingBytes(); } catch (Http2Exception e) { onError(chctx, true, e); } } chctx.channel().flush(); }
private Http2ClientStream createStream(Http2Stream stream) { boolean writable = handler.encoder().flowController().isWritable(stream); Http2ClientStream clientStream = new Http2ClientStream(this, stream, writable); streams.put(clientStream.stream.id(), clientStream); return clientStream; }
@Override public void handle(AsyncResult<Integer> ar) { if (ar.succeeded()) { synchronized (Http2ServerConnection.this) { int promisedStreamId = ar.result(); String contentEncoding = HttpUtils.determineContentEncoding(headers_); Http2Stream promisedStream = handler.connection().stream(promisedStreamId); boolean writable = handler.encoder().flowController().isWritable(promisedStream); Push push = new Push(promisedStream, contentEncoding, method, path, writable, completionHandler); push.priority(streamPriority); streams.put(promisedStreamId, push); if (maxConcurrentStreams == null || concurrentStreams < maxConcurrentStreams) { concurrentStreams++; context.executeFromIO(v -> push.complete()); } else { pendingPushes.add(push); } } } else { context.executeFromIO(v -> { completionHandler.handle(Future.failedFuture(ar.cause())); }); } } });
public VertxHttp2ConnectionHandler( Function<VertxHttp2ConnectionHandler<C>, C> connectionFactory, boolean useDecompressor, Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder, Http2Settings initialSettings) { super(decoder, encoder, initialSettings); this.connectionFactory = connectionFactory; this.useDecompressor = useDecompressor; encoder().flowController().listener(s -> { if (connection != null) { connection.onStreamWritabilityChanged(s); } }); connection().addListener(this); }
private Http2ServerRequestImpl createRequest(int streamId, Http2Headers headers, boolean streamEnded) { Http2Stream stream = handler.connection().stream(streamId); String contentEncoding = options.isCompressionSupported() ? HttpUtils.determineContentEncoding(headers) : null; boolean writable = handler.encoder().flowController().isWritable(stream); return new Http2ServerRequestImpl(this, stream, metrics, serverOrigin, headers, contentEncoding, writable, streamEnded); }
@Override public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency, short weight, boolean exclusive) throws Http2Exception { encoder.flowController().updateDependencyTree(streamId, streamDependency, weight, exclusive); listener.onPriorityRead(ctx, streamId, streamDependency, weight, exclusive); }
@Override public void flush(ChannelHandlerContext ctx) { try { // Trigger pending writes in the remote flow controller. encoder.flowController().writePendingBytes(); ctx.flush(); } catch (Http2Exception e) { onError(ctx, true, e); } catch (Throwable cause) { onError(ctx, true, connectionError(INTERNAL_ERROR, cause, "Error flushing")); } }