@Override public final Http2RemoteFlowController flowController() { return connection().remote().flowController(); }
@Override public HttpConnection goAway(long errorCode, int lastStreamId, Buffer debugData) { if (errorCode < 0) { throw new IllegalArgumentException(); } if (lastStreamId < 0) { lastStreamId = handler.connection().remote().lastStreamCreated(); } handler.writeGoAway(errorCode, lastStreamId, debugData != null ? debugData.getByteBuf() : Unpooled.EMPTY_BUFFER); return this; }
final boolean isWritable(DefaultHttp2FrameStream stream) { Http2Stream s = stream.stream; return s != null && connection().remote().flowController().isWritable(s); }
public DefaultHttp2ConnectionEncoder(Http2Connection connection, Http2FrameWriter frameWriter) { this.connection = checkNotNull(connection, "connection"); this.frameWriter = checkNotNull(frameWriter, "frameWriter"); if (connection.remote().flowController() == null) { connection.remote().flowController(new DefaultHttp2RemoteFlowController(connection)); } }
final boolean isWritable(DefaultHttp2FrameStream stream) { Http2Stream s = stream.stream; return s != null && connection().remote().flowController().isWritable(s); }
private static int getStreamId(Http2Connection connection, HttpHeaders httpHeaders) { return httpHeaders.getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text(), connection.remote().incrementAndGetNextStreamId()); }
/** * Helper method for determining whether or not to ignore inbound frames. A stream is considered to be created * after a {@code GOAWAY} is sent if the following conditions hold: * <p/> * <ul> * <li>A {@code GOAWAY} must have been sent by the local endpoint</li> * <li>The {@code streamId} must identify a legitimate stream id for the remote endpoint to be creating</li> * <li>{@code streamId} is greater than the Last Known Stream ID which was sent by the local endpoint * in the last {@code GOAWAY} frame</li> * </ul> * <p/> */ private boolean streamCreatedAfterGoAwaySent(int streamId) { Endpoint<?> remote = connection.remote(); return connection.goAwaySent() && remote.isValidStreamId(streamId) && streamId > remote.lastStreamKnownByPeer(); }
@Override public void writabilityChanged(Http2Stream stream) { Http2FrameStream frameStream = stream.getProperty(streamKey); if (frameStream == null) { return; } onHttp2StreamWritabilityChanged( ctx, frameStream, connection().remote().flowController().isWritable(stream)); } }
private void writeGoAwayFrame(ChannelHandlerContext ctx, Http2GoAwayFrame frame, ChannelPromise promise) { if (frame.lastStreamId() > -1) { frame.release(); throw new IllegalArgumentException("Last stream id must not be set on GOAWAY frame"); } int lastStreamCreated = connection().remote().lastStreamCreated(); long lastStreamId = lastStreamCreated + ((long) frame.extraStreamIds()) * 2; // Check if the computation overflowed. if (lastStreamId > Integer.MAX_VALUE) { lastStreamId = Integer.MAX_VALUE; } goAway(ctx, (int) lastStreamId, frame.errorCode(), frame.content(), promise); }
@Override public void writabilityChanged(Http2Stream stream) { Http2FrameStream frameStream = stream.getProperty(streamKey); if (frameStream == null) { return; } onHttp2StreamWritabilityChanged( ctx, frameStream, connection().remote().flowController().isWritable(stream)); } }
final boolean isWritable(DefaultHttp2FrameStream stream) { Http2Stream s = stream.stream; return s != null && connection().remote().flowController().isWritable(s); }
private void writeGoAwayFrame(ChannelHandlerContext ctx, Http2GoAwayFrame frame, ChannelPromise promise) { if (frame.lastStreamId() > -1) { frame.release(); throw new IllegalArgumentException("Last stream id must not be set on GOAWAY frame"); } int lastStreamCreated = connection().remote().lastStreamCreated(); long lastStreamId = lastStreamCreated + ((long) frame.extraStreamIds()) * 2; // Check if the computation overflowed. if (lastStreamId > Integer.MAX_VALUE) { lastStreamId = Integer.MAX_VALUE; } goAway(ctx, (int) lastStreamId, frame.errorCode(), frame.content(), promise); }
/** * Close the remote endpoint with with a {@code GO_AWAY} frame. Does <strong>not</strong> flush * immediately, this is the responsibility of the caller. */ private ChannelFuture goAway(ChannelHandlerContext ctx, Http2Exception cause) { long errorCode = cause != null ? cause.error().code() : NO_ERROR.code(); int lastKnownStream = connection().remote().lastStreamCreated(); return goAway(ctx, lastKnownStream, errorCode, Http2CodecUtil.toByteBuf(ctx, cause), ctx.newPromise()); }
@Override public void writabilityChanged(Http2Stream stream) { Http2FrameStream frameStream = stream.getProperty(streamKey); if (frameStream == null) { return; } onHttp2StreamWritabilityChanged( ctx, frameStream, connection().remote().flowController().isWritable(stream)); } }
private void writeGoAwayFrame(ChannelHandlerContext ctx, Http2GoAwayFrame frame, ChannelPromise promise) { if (frame.lastStreamId() > -1) { frame.release(); throw new IllegalArgumentException("Last stream id must not be set on GOAWAY frame"); } int lastStreamCreated = connection().remote().lastStreamCreated(); long lastStreamId = lastStreamCreated + ((long) frame.extraStreamIds()) * 2; // Check if the computation overflowed. if (lastStreamId > Integer.MAX_VALUE) { lastStreamId = Integer.MAX_VALUE; } goAway(ctx, (int) lastStreamId, frame.errorCode(), frame.content(), promise); }
Http2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings) { super(decoder, encoder, initialSettings); decoder.frameListener(new FrameListener()); connection().addListener(new ConnectionListener()); connection().remote().flowController().listener(new Http2RemoteFlowControllerListener()); streamKey = connection().newKey(); upgradeKey = connection().newKey(); initialFlowControlWindowSize = initialSettings.initialWindowSize(); }
/** * Handles the server-side (cleartext) upgrade from HTTP to HTTP/2. * @param settings the settings for the remote endpoint. */ public void onHttpServerUpgrade(Http2Settings settings) throws Http2Exception { if (!connection().isServer()) { throw connectionError(PROTOCOL_ERROR, "Server-side HTTP upgrade requested for a client"); } if (!prefaceSent()) { // If the preface was not sent yet it most likely means the handler was not added to the pipeline before // calling this method. throw connectionError(INTERNAL_ERROR, "HTTP upgrade must occur after preface was sent"); } if (decoder.prefaceReceived()) { throw connectionError(PROTOCOL_ERROR, "HTTP upgrade must occur before HTTP/2 preface is received"); } // Apply the settings but no ACK is necessary. encoder.remoteSettings(settings); // Create a stream in the half-closed state. connection().remote().createStream(HTTP_UPGRADE_STREAM_ID, true); }
Http2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings) { super(decoder, encoder, initialSettings); decoder.frameListener(new FrameListener()); connection().addListener(new ConnectionListener()); connection().remote().flowController().listener(new Http2RemoteFlowControllerListener()); streamKey = connection().newKey(); upgradeKey = connection().newKey(); initialFlowControlWindowSize = initialSettings.initialWindowSize(); }
@Override public Http2Settings localSettings() { Http2Settings settings = new Http2Settings(); Http2FrameReader.Configuration config = frameReader.configuration(); Http2HeadersDecoder.Configuration headersConfig = config.headersConfiguration(); Http2FrameSizePolicy frameSizePolicy = config.frameSizePolicy(); settings.initialWindowSize(flowController().initialWindowSize()); settings.maxConcurrentStreams(connection.remote().maxActiveStreams()); settings.headerTableSize(headersConfig.maxHeaderTableSize()); settings.maxFrameSize(frameSizePolicy.maxFrameSize()); settings.maxHeaderListSize(headersConfig.maxHeaderListSize()); if (!connection.isServer()) { // Only set the pushEnabled flag if this is a client endpoint. settings.pushEnabled(connection.local().allowPushTo()); } return settings; }
Http2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings) { super(decoder, encoder, initialSettings); decoder.frameListener(new FrameListener()); connection().addListener(new ConnectionListener()); connection().remote().flowController().listener(new Http2RemoteFlowControllerListener()); streamKey = connection().newKey(); upgradeKey = connection().newKey(); initialFlowControlWindowSize = initialSettings.initialWindowSize(); }