netty5/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandlerBuilder.java
Scott Mitchell b4e3c12b8e
Http2ConnectionHandler to allow decoupling close(..) from GOAWAY graceful close (#9094)
Motivation:
Http2ConnectionHandler#close(..) always runs the GOAWAY and graceful close
logic. This coupling means that a user would have to override
Http2ConnectionHandler#close(..) to modify the behavior, and the
Http2FrameCodec and Http2MultiplexCodec are not extendable so you cannot
override at this layer. Ideally we can totally decouple the close(..) of the
transport and the GOAWAY graceful closure process completely, but to preserve
backwards compatibility we can add an opt-out option to decouple where the
application is responsible for sending a GOAWAY with error code equal to
NO_ERROR as described in https://tools.ietf.org/html/rfc7540#section-6.8 in
order to initiate graceful close.

Modifications:
- Http2ConnectionHandler supports an additional boolean constructor argument to
opt out of close(..) going through the graceful close path.
- Http2FrameCodecBuilder and Http2MultiplexCodec expose
 gracefulShutdownTimeoutMillis but do not hook them up properly. Since these
are already exposed we should hook them up and make sure the timeout is applied
properly.
- Http2ConnectionHandler's goAway(..) method from Http2LifecycleManager should
initiate the graceful closure process after writing a GOAWAY frame if the error
code is NO_ERROR. This means that writing a Http2GoAwayFrame from
Http2FrameCodec will initiate graceful close.

Result:
Http2ConnectionHandler#close(..) can now be decoupled from the graceful close
process, and immediately close the underlying transport if desired.
2019-04-28 17:48:04 -07:00

111 lines
3.9 KiB
Java

/*
* Copyright 2015 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.handler.codec.http2.Http2HeadersEncoder.SensitivityDetector;
import io.netty.util.internal.UnstableApi;
/**
* Builder which builds {@link Http2ConnectionHandler} objects.
*/
@UnstableApi
public final class Http2ConnectionHandlerBuilder
extends AbstractHttp2ConnectionHandlerBuilder<Http2ConnectionHandler, Http2ConnectionHandlerBuilder> {
@Override
public Http2ConnectionHandlerBuilder validateHeaders(boolean validateHeaders) {
return super.validateHeaders(validateHeaders);
}
@Override
public Http2ConnectionHandlerBuilder initialSettings(Http2Settings settings) {
return super.initialSettings(settings);
}
@Override
public Http2ConnectionHandlerBuilder frameListener(Http2FrameListener frameListener) {
return super.frameListener(frameListener);
}
@Override
public Http2ConnectionHandlerBuilder gracefulShutdownTimeoutMillis(long gracefulShutdownTimeoutMillis) {
return super.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis);
}
@Override
public Http2ConnectionHandlerBuilder server(boolean isServer) {
return super.server(isServer);
}
@Override
public Http2ConnectionHandlerBuilder connection(Http2Connection connection) {
return super.connection(connection);
}
@Override
public Http2ConnectionHandlerBuilder maxReservedStreams(int maxReservedStreams) {
return super.maxReservedStreams(maxReservedStreams);
}
@Override
public Http2ConnectionHandlerBuilder codec(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder) {
return super.codec(decoder, encoder);
}
@Override
public Http2ConnectionHandlerBuilder frameLogger(Http2FrameLogger frameLogger) {
return super.frameLogger(frameLogger);
}
@Override
public Http2ConnectionHandlerBuilder encoderEnforceMaxConcurrentStreams(
boolean encoderEnforceMaxConcurrentStreams) {
return super.encoderEnforceMaxConcurrentStreams(encoderEnforceMaxConcurrentStreams);
}
@Override
public Http2ConnectionHandlerBuilder encoderIgnoreMaxHeaderListSize(boolean encoderIgnoreMaxHeaderListSize) {
return super.encoderIgnoreMaxHeaderListSize(encoderIgnoreMaxHeaderListSize);
}
@Override
public Http2ConnectionHandlerBuilder headerSensitivityDetector(SensitivityDetector headerSensitivityDetector) {
return super.headerSensitivityDetector(headerSensitivityDetector);
}
@Override
public Http2ConnectionHandlerBuilder initialHuffmanDecodeCapacity(int initialHuffmanDecodeCapacity) {
return super.initialHuffmanDecodeCapacity(initialHuffmanDecodeCapacity);
}
@Override
public Http2ConnectionHandlerBuilder decoupleCloseAndGoAway(boolean decoupleCloseAndGoAway) {
return super.decoupleCloseAndGoAway(decoupleCloseAndGoAway);
}
@Override
public Http2ConnectionHandler build() {
return super.build();
}
@Override
protected Http2ConnectionHandler build(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings) {
return new Http2ConnectionHandler(decoder, encoder, initialSettings, decoupleCloseAndGoAway());
}
}