2017-08-11 07:51:45 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2017 The Netty Project
|
|
|
|
*
|
|
|
|
* The Netty Project licenses this file to you under the Apache License,
|
|
|
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
|
|
* with the License. You may obtain a copy of the License at:
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
|
|
|
*/
|
|
|
|
package io.netty.handler.codec.http2;
|
|
|
|
|
|
|
|
import io.netty.channel.ChannelHandler;
|
|
|
|
import io.netty.channel.ChannelHandlerAdapter;
|
|
|
|
import io.netty.util.internal.UnstableApi;
|
|
|
|
|
|
|
|
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A builder for {@link Http2MultiplexCodec}.
|
2019-06-24 09:17:15 +02:00
|
|
|
*
|
|
|
|
* @deprecated use {@link Http2FrameCodecBuilder} together with {@link Http2MultiplexHandler}.
|
2017-08-11 07:51:45 +02:00
|
|
|
*/
|
2019-06-24 09:17:15 +02:00
|
|
|
@Deprecated
|
2017-08-11 07:51:45 +02:00
|
|
|
@UnstableApi
|
|
|
|
public class Http2MultiplexCodecBuilder
|
|
|
|
extends AbstractHttp2ConnectionHandlerBuilder<Http2MultiplexCodec, Http2MultiplexCodecBuilder> {
|
2018-12-14 11:10:04 +01:00
|
|
|
private Http2FrameWriter frameWriter;
|
2017-08-11 07:51:45 +02:00
|
|
|
|
|
|
|
final ChannelHandler childHandler;
|
2018-06-08 01:01:41 +02:00
|
|
|
private ChannelHandler upgradeStreamHandler;
|
2017-08-11 07:51:45 +02:00
|
|
|
|
|
|
|
Http2MultiplexCodecBuilder(boolean server, ChannelHandler childHandler) {
|
|
|
|
server(server);
|
|
|
|
this.childHandler = checkSharable(checkNotNull(childHandler, "childHandler"));
|
2019-04-29 02:48:04 +02:00
|
|
|
// For backwards compatibility we should disable to timeout by default at this layer.
|
|
|
|
gracefulShutdownTimeoutMillis(0);
|
2017-08-11 07:51:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static ChannelHandler checkSharable(ChannelHandler handler) {
|
2017-11-08 16:29:14 +01:00
|
|
|
if ((handler instanceof ChannelHandlerAdapter && !((ChannelHandlerAdapter) handler).isSharable()) &&
|
2017-08-11 07:51:45 +02:00
|
|
|
!handler.getClass().isAnnotationPresent(ChannelHandler.Sharable.class)) {
|
|
|
|
throw new IllegalArgumentException("The handler must be Sharable");
|
|
|
|
}
|
|
|
|
return handler;
|
|
|
|
}
|
|
|
|
|
2018-12-14 11:10:04 +01:00
|
|
|
// For testing only.
|
|
|
|
Http2MultiplexCodecBuilder frameWriter(Http2FrameWriter frameWriter) {
|
|
|
|
this.frameWriter = checkNotNull(frameWriter, "frameWriter");
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2017-08-11 07:51:45 +02:00
|
|
|
/**
|
|
|
|
* Creates a builder for a HTTP/2 client.
|
|
|
|
*
|
|
|
|
* @param childHandler the handler added to channels for remotely-created streams. It must be
|
|
|
|
* {@link ChannelHandler.Sharable}.
|
|
|
|
*/
|
|
|
|
public static Http2MultiplexCodecBuilder forClient(ChannelHandler childHandler) {
|
|
|
|
return new Http2MultiplexCodecBuilder(false, childHandler);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a builder for a HTTP/2 server.
|
|
|
|
*
|
|
|
|
* @param childHandler the handler added to channels for remotely-created streams. It must be
|
|
|
|
* {@link ChannelHandler.Sharable}.
|
|
|
|
*/
|
|
|
|
public static Http2MultiplexCodecBuilder forServer(ChannelHandler childHandler) {
|
|
|
|
return new Http2MultiplexCodecBuilder(true, childHandler);
|
|
|
|
}
|
|
|
|
|
2019-04-29 02:48:04 +02:00
|
|
|
public Http2MultiplexCodecBuilder withUpgradeStreamHandler(ChannelHandler upgradeStreamHandler) {
|
|
|
|
if (this.isServer()) {
|
|
|
|
throw new IllegalArgumentException("Server codecs don't use an extra handler for the upgrade stream");
|
|
|
|
}
|
|
|
|
this.upgradeStreamHandler = upgradeStreamHandler;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2017-08-11 07:51:45 +02:00
|
|
|
@Override
|
|
|
|
public Http2Settings initialSettings() {
|
|
|
|
return super.initialSettings();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder initialSettings(Http2Settings settings) {
|
|
|
|
return super.initialSettings(settings);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public long gracefulShutdownTimeoutMillis() {
|
|
|
|
return super.gracefulShutdownTimeoutMillis();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder gracefulShutdownTimeoutMillis(long gracefulShutdownTimeoutMillis) {
|
|
|
|
return super.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isServer() {
|
|
|
|
return super.isServer();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int maxReservedStreams() {
|
|
|
|
return super.maxReservedStreams();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder maxReservedStreams(int maxReservedStreams) {
|
|
|
|
return super.maxReservedStreams(maxReservedStreams);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isValidateHeaders() {
|
|
|
|
return super.isValidateHeaders();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder validateHeaders(boolean validateHeaders) {
|
|
|
|
return super.validateHeaders(validateHeaders);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2FrameLogger frameLogger() {
|
|
|
|
return super.frameLogger();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder frameLogger(Http2FrameLogger frameLogger) {
|
|
|
|
return super.frameLogger(frameLogger);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean encoderEnforceMaxConcurrentStreams() {
|
|
|
|
return super.encoderEnforceMaxConcurrentStreams();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder encoderEnforceMaxConcurrentStreams(boolean encoderEnforceMaxConcurrentStreams) {
|
|
|
|
return super.encoderEnforceMaxConcurrentStreams(encoderEnforceMaxConcurrentStreams);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2HeadersEncoder.SensitivityDetector headerSensitivityDetector() {
|
|
|
|
return super.headerSensitivityDetector();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder headerSensitivityDetector(
|
|
|
|
Http2HeadersEncoder.SensitivityDetector headerSensitivityDetector) {
|
|
|
|
return super.headerSensitivityDetector(headerSensitivityDetector);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder encoderIgnoreMaxHeaderListSize(boolean ignoreMaxHeaderListSize) {
|
|
|
|
return super.encoderIgnoreMaxHeaderListSize(ignoreMaxHeaderListSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder initialHuffmanDecodeCapacity(int initialHuffmanDecodeCapacity) {
|
|
|
|
return super.initialHuffmanDecodeCapacity(initialHuffmanDecodeCapacity);
|
|
|
|
}
|
|
|
|
|
2019-04-26 00:52:05 +02:00
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder autoAckSettingsFrame(boolean autoAckSettings) {
|
|
|
|
return super.autoAckSettingsFrame(autoAckSettings);
|
|
|
|
}
|
|
|
|
|
2019-04-29 02:48:04 +02:00
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodecBuilder decoupleCloseAndGoAway(boolean decoupleCloseAndGoAway) {
|
|
|
|
return super.decoupleCloseAndGoAway(decoupleCloseAndGoAway);
|
|
|
|
}
|
|
|
|
|
2017-08-11 07:51:45 +02:00
|
|
|
@Override
|
|
|
|
public Http2MultiplexCodec build() {
|
2018-12-14 11:10:04 +01:00
|
|
|
Http2FrameWriter frameWriter = this.frameWriter;
|
|
|
|
if (frameWriter != null) {
|
|
|
|
// This is to support our tests and will never be executed by the user as frameWriter(...)
|
|
|
|
// is package-private.
|
|
|
|
DefaultHttp2Connection connection = new DefaultHttp2Connection(isServer(), maxReservedStreams());
|
|
|
|
Long maxHeaderListSize = initialSettings().maxHeaderListSize();
|
|
|
|
Http2FrameReader frameReader = new DefaultHttp2FrameReader(maxHeaderListSize == null ?
|
|
|
|
new DefaultHttp2HeadersDecoder(true) :
|
|
|
|
new DefaultHttp2HeadersDecoder(true, maxHeaderListSize));
|
|
|
|
|
|
|
|
if (frameLogger() != null) {
|
|
|
|
frameWriter = new Http2OutboundFrameLogger(frameWriter, frameLogger());
|
|
|
|
frameReader = new Http2InboundFrameLogger(frameReader, frameLogger());
|
|
|
|
}
|
|
|
|
Http2ConnectionEncoder encoder = new DefaultHttp2ConnectionEncoder(connection, frameWriter);
|
|
|
|
if (encoderEnforceMaxConcurrentStreams()) {
|
|
|
|
encoder = new StreamBufferingEncoder(encoder);
|
|
|
|
}
|
2019-04-26 00:52:05 +02:00
|
|
|
Http2ConnectionDecoder decoder = new DefaultHttp2ConnectionDecoder(connection, encoder, frameReader,
|
|
|
|
promisedRequestVerifier(), isAutoAckSettingsFrame());
|
2018-12-14 11:10:04 +01:00
|
|
|
|
|
|
|
return build(decoder, encoder, initialSettings());
|
|
|
|
}
|
2017-08-11 07:51:45 +02:00
|
|
|
return super.build();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Http2MultiplexCodec build(
|
|
|
|
Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder, Http2Settings initialSettings) {
|
2019-04-29 02:48:04 +02:00
|
|
|
Http2MultiplexCodec codec = new Http2MultiplexCodec(encoder, decoder, initialSettings, childHandler,
|
|
|
|
upgradeStreamHandler, decoupleCloseAndGoAway());
|
|
|
|
codec.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis());
|
|
|
|
return codec;
|
2017-08-11 07:51:45 +02:00
|
|
|
}
|
|
|
|
}
|