View Javadoc
1   /*
2    * Copyright 2017 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  
17  package io.netty.handler.codec.http2;
18  
19  import static io.netty.util.internal.ObjectUtil.checkNotNull;
20  
21  /**
22   * Builder for the {@link Http2FrameCodec}.
23   */
24  public class Http2FrameCodecBuilder extends
25          AbstractHttp2ConnectionHandlerBuilder<Http2FrameCodec, Http2FrameCodecBuilder> {
26  
27      private Http2FrameWriter frameWriter;
28  
29      /**
30       * Allows overriding behavior of existing builder.
31       * <p>
32       * Users of this constructor are responsible for invoking {@link #server(boolean)} method or overriding
33       * {@link #isServer()} method to give the builder information if the {@link Http2Connection}(s) it creates are in
34       * server or client mode.
35       *
36       * @see AbstractHttp2ConnectionHandlerBuilder
37       */
38      protected Http2FrameCodecBuilder() {
39      }
40  
41      Http2FrameCodecBuilder(boolean server) {
42          server(server);
43          // For backwards compatibility we should disable to timeout by default at this layer.
44          gracefulShutdownTimeoutMillis(0);
45      }
46  
47      /**
48       * Creates a builder for an HTTP/2 client.
49       */
50      public static Http2FrameCodecBuilder forClient() {
51          return new Http2FrameCodecBuilder(false);
52      }
53  
54      /**
55       * Creates a builder for an HTTP/2 server.
56       */
57      public static Http2FrameCodecBuilder forServer() {
58          return new Http2FrameCodecBuilder(true);
59      }
60  
61      // For testing only.
62      Http2FrameCodecBuilder frameWriter(Http2FrameWriter frameWriter) {
63          this.frameWriter = checkNotNull(frameWriter, "frameWriter");
64          return this;
65      }
66  
67      @Override
68      public Http2Settings initialSettings() {
69          return super.initialSettings();
70      }
71  
72      @Override
73      public Http2FrameCodecBuilder initialSettings(Http2Settings settings) {
74          return super.initialSettings(settings);
75      }
76  
77      @Override
78      public long gracefulShutdownTimeoutMillis() {
79          return super.gracefulShutdownTimeoutMillis();
80      }
81  
82      @Override
83      public Http2FrameCodecBuilder gracefulShutdownTimeoutMillis(long gracefulShutdownTimeoutMillis) {
84          return super.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis);
85      }
86  
87      @Override
88      public boolean isServer() {
89          return super.isServer();
90      }
91  
92      @Override
93      public int maxReservedStreams() {
94          return super.maxReservedStreams();
95      }
96  
97      @Override
98      public Http2FrameCodecBuilder maxReservedStreams(int maxReservedStreams) {
99          return super.maxReservedStreams(maxReservedStreams);
100     }
101 
102     @Override
103     public boolean isValidateHeaders() {
104         return super.isValidateHeaders();
105     }
106 
107     @Override
108     public Http2FrameCodecBuilder validateHeaders(boolean validateHeaders) {
109         return super.validateHeaders(validateHeaders);
110     }
111 
112     @Override
113     public Http2FrameLogger frameLogger() {
114         return super.frameLogger();
115     }
116 
117     @Override
118     public Http2FrameCodecBuilder frameLogger(Http2FrameLogger frameLogger) {
119         return super.frameLogger(frameLogger);
120     }
121 
122     @Override
123     public boolean encoderEnforceMaxConcurrentStreams() {
124         return super.encoderEnforceMaxConcurrentStreams();
125     }
126 
127     @Override
128     public Http2FrameCodecBuilder encoderEnforceMaxConcurrentStreams(boolean encoderEnforceMaxConcurrentStreams) {
129         return super.encoderEnforceMaxConcurrentStreams(encoderEnforceMaxConcurrentStreams);
130     }
131 
132     @Override
133     public int encoderEnforceMaxQueuedControlFrames() {
134         return super.encoderEnforceMaxQueuedControlFrames();
135     }
136 
137     @Override
138     public Http2FrameCodecBuilder encoderEnforceMaxQueuedControlFrames(int maxQueuedControlFrames) {
139         return super.encoderEnforceMaxQueuedControlFrames(maxQueuedControlFrames);
140     }
141 
142     @Override
143     public Http2HeadersEncoder.SensitivityDetector headerSensitivityDetector() {
144         return super.headerSensitivityDetector();
145     }
146 
147     @Override
148     public Http2FrameCodecBuilder headerSensitivityDetector(
149             Http2HeadersEncoder.SensitivityDetector headerSensitivityDetector) {
150         return super.headerSensitivityDetector(headerSensitivityDetector);
151     }
152 
153     @Override
154     public Http2FrameCodecBuilder encoderIgnoreMaxHeaderListSize(boolean ignoreMaxHeaderListSize) {
155         return super.encoderIgnoreMaxHeaderListSize(ignoreMaxHeaderListSize);
156     }
157 
158     @Override
159     @Deprecated
160     public Http2FrameCodecBuilder initialHuffmanDecodeCapacity(int initialHuffmanDecodeCapacity) {
161         return super.initialHuffmanDecodeCapacity(initialHuffmanDecodeCapacity);
162     }
163 
164     @Override
165     public Http2FrameCodecBuilder autoAckSettingsFrame(boolean autoAckSettings) {
166         return super.autoAckSettingsFrame(autoAckSettings);
167     }
168 
169     @Override
170     public Http2FrameCodecBuilder autoAckPingFrame(boolean autoAckPingFrame) {
171         return super.autoAckPingFrame(autoAckPingFrame);
172     }
173 
174     @Override
175     public Http2FrameCodecBuilder decoupleCloseAndGoAway(boolean decoupleCloseAndGoAway) {
176         return super.decoupleCloseAndGoAway(decoupleCloseAndGoAway);
177     }
178 
179     @Override
180     public Http2FrameCodecBuilder flushPreface(boolean flushPreface) {
181         return super.flushPreface(flushPreface);
182     }
183 
184     @Override
185     public int decoderEnforceMaxConsecutiveEmptyDataFrames() {
186         return super.decoderEnforceMaxConsecutiveEmptyDataFrames();
187     }
188 
189     @Override
190     public Http2FrameCodecBuilder decoderEnforceMaxConsecutiveEmptyDataFrames(int maxConsecutiveEmptyFrames) {
191         return super.decoderEnforceMaxConsecutiveEmptyDataFrames(maxConsecutiveEmptyFrames);
192     }
193 
194     @Override
195     public Http2FrameCodecBuilder decoderEnforceMaxRstFramesPerWindow(
196             int maxRstFramesPerWindow, int secondsPerWindow) {
197         return super.decoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow);
198     }
199 
200     /**
201      * Build a {@link Http2FrameCodec} object.
202      */
203     @Override
204     public Http2FrameCodec build() {
205         Http2FrameWriter frameWriter = this.frameWriter;
206         if (frameWriter != null) {
207             // This is to support our tests and will never be executed by the user as frameWriter(...)
208             // is package-private.
209             DefaultHttp2Connection connection = new DefaultHttp2Connection(isServer(), maxReservedStreams());
210             Long maxHeaderListSize = initialSettings().maxHeaderListSize();
211             Http2FrameReader frameReader = new DefaultHttp2FrameReader(maxHeaderListSize == null ?
212                     new DefaultHttp2HeadersDecoder(isValidateHeaders()) :
213                     new DefaultHttp2HeadersDecoder(isValidateHeaders(), maxHeaderListSize));
214 
215             if (frameLogger() != null) {
216                 frameWriter = new Http2OutboundFrameLogger(frameWriter, frameLogger());
217                 frameReader = new Http2InboundFrameLogger(frameReader, frameLogger());
218             }
219             Http2ConnectionEncoder encoder = new DefaultHttp2ConnectionEncoder(connection, frameWriter);
220             if (encoderEnforceMaxConcurrentStreams()) {
221                 encoder = new StreamBufferingEncoder(encoder);
222             }
223             Http2ConnectionDecoder decoder = new DefaultHttp2ConnectionDecoder(connection, encoder, frameReader,
224                     promisedRequestVerifier(), isAutoAckSettingsFrame(), isAutoAckPingFrame(), isValidateHeaders());
225             int maxConsecutiveEmptyDataFrames = decoderEnforceMaxConsecutiveEmptyDataFrames();
226             if (maxConsecutiveEmptyDataFrames > 0) {
227                 decoder = new Http2EmptyDataFrameConnectionDecoder(decoder, maxConsecutiveEmptyDataFrames);
228             }
229             return build(decoder, encoder, initialSettings());
230         }
231         return super.build();
232     }
233 
234     @Override
235     protected Http2FrameCodec build(
236             Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder, Http2Settings initialSettings) {
237         Http2FrameCodec codec = new Http2FrameCodec(encoder, decoder, initialSettings,
238                 decoupleCloseAndGoAway(), flushPreface());
239         codec.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis());
240         return codec;
241     }
242 }