b4e3c12b8e
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.
104 lines
3.7 KiB
Java
104 lines
3.7 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 HttpToHttp2ConnectionHandler} objects.
|
|
*/
|
|
@UnstableApi
|
|
public final class HttpToHttp2ConnectionHandlerBuilder extends
|
|
AbstractHttp2ConnectionHandlerBuilder<HttpToHttp2ConnectionHandler, HttpToHttp2ConnectionHandlerBuilder> {
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder validateHeaders(boolean validateHeaders) {
|
|
return super.validateHeaders(validateHeaders);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder initialSettings(Http2Settings settings) {
|
|
return super.initialSettings(settings);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder frameListener(Http2FrameListener frameListener) {
|
|
return super.frameListener(frameListener);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder gracefulShutdownTimeoutMillis(long gracefulShutdownTimeoutMillis) {
|
|
return super.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder server(boolean isServer) {
|
|
return super.server(isServer);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder connection(Http2Connection connection) {
|
|
return super.connection(connection);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder codec(Http2ConnectionDecoder decoder,
|
|
Http2ConnectionEncoder encoder) {
|
|
return super.codec(decoder, encoder);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder frameLogger(Http2FrameLogger frameLogger) {
|
|
return super.frameLogger(frameLogger);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder encoderEnforceMaxConcurrentStreams(
|
|
boolean encoderEnforceMaxConcurrentStreams) {
|
|
return super.encoderEnforceMaxConcurrentStreams(encoderEnforceMaxConcurrentStreams);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder headerSensitivityDetector(
|
|
SensitivityDetector headerSensitivityDetector) {
|
|
return super.headerSensitivityDetector(headerSensitivityDetector);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder initialHuffmanDecodeCapacity(int initialHuffmanDecodeCapacity) {
|
|
return super.initialHuffmanDecodeCapacity(initialHuffmanDecodeCapacity);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandlerBuilder decoupleCloseAndGoAway(boolean decoupleCloseAndGoAway) {
|
|
return super.decoupleCloseAndGoAway(decoupleCloseAndGoAway);
|
|
}
|
|
|
|
@Override
|
|
public HttpToHttp2ConnectionHandler build() {
|
|
return super.build();
|
|
}
|
|
|
|
@Override
|
|
protected HttpToHttp2ConnectionHandler build(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
|
|
Http2Settings initialSettings) {
|
|
return new HttpToHttp2ConnectionHandler(decoder, encoder, initialSettings, isValidateHeaders(),
|
|
decoupleCloseAndGoAway());
|
|
}
|
|
}
|