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  package io.netty.handler.codec.http2;
17  
18  import io.netty.channel.ChannelHandler;
19  import io.netty.channel.ChannelHandlerAdapter;
20  
21  import static io.netty.util.internal.ObjectUtil.checkNotNull;
22  
23  /**
24   * A builder for {@link Http2MultiplexCodec}.
25   *
26   * @deprecated use {@link Http2FrameCodecBuilder} together with {@link Http2MultiplexHandler}.
27   */
28  @Deprecated
29  public class Http2MultiplexCodecBuilder
30          extends AbstractHttp2ConnectionHandlerBuilder<Http2MultiplexCodec, Http2MultiplexCodecBuilder> {
31      private Http2FrameWriter frameWriter;
32  
33      final ChannelHandler childHandler;
34      private ChannelHandler upgradeStreamHandler;
35  
36      Http2MultiplexCodecBuilder(boolean server, ChannelHandler childHandler) {
37          server(server);
38          this.childHandler = checkSharable(checkNotNull(childHandler, "childHandler"));
39          // For backwards compatibility we should disable to timeout by default at this layer.
40          gracefulShutdownTimeoutMillis(0);
41      }
42  
43      private static ChannelHandler checkSharable(ChannelHandler handler) {
44          if (handler instanceof ChannelHandlerAdapter && !((ChannelHandlerAdapter) handler).isSharable() &&
45                  !handler.getClass().isAnnotationPresent(ChannelHandler.Sharable.class)) {
46              throw new IllegalArgumentException("The handler must be Sharable");
47          }
48          return handler;
49      }
50  
51      // For testing only.
52      Http2MultiplexCodecBuilder frameWriter(Http2FrameWriter frameWriter) {
53          this.frameWriter = checkNotNull(frameWriter, "frameWriter");
54          return this;
55      }
56  
57      /**
58       * Creates a builder for an HTTP/2 client.
59       *
60       * @param childHandler the handler added to channels for remotely-created streams. It must be
61       *     {@link ChannelHandler.Sharable}.
62       */
63      public static Http2MultiplexCodecBuilder forClient(ChannelHandler childHandler) {
64          return new Http2MultiplexCodecBuilder(false, childHandler);
65      }
66  
67      /**
68       * Creates a builder for an HTTP/2 server.
69       *
70       * @param childHandler the handler added to channels for remotely-created streams. It must be
71       *     {@link ChannelHandler.Sharable}.
72       */
73      public static Http2MultiplexCodecBuilder forServer(ChannelHandler childHandler) {
74          return new Http2MultiplexCodecBuilder(true, childHandler);
75      }
76  
77      public Http2MultiplexCodecBuilder withUpgradeStreamHandler(ChannelHandler upgradeStreamHandler) {
78          if (isServer()) {
79              throw new IllegalArgumentException("Server codecs don't use an extra handler for the upgrade stream");
80          }
81          this.upgradeStreamHandler = upgradeStreamHandler;
82          return this;
83      }
84  
85      @Override
86      public Http2Settings initialSettings() {
87          return super.initialSettings();
88      }
89  
90      @Override
91      public Http2MultiplexCodecBuilder initialSettings(Http2Settings settings) {
92          return super.initialSettings(settings);
93      }
94  
95      @Override
96      public long gracefulShutdownTimeoutMillis() {
97          return super.gracefulShutdownTimeoutMillis();
98      }
99  
100     @Override
101     public Http2MultiplexCodecBuilder gracefulShutdownTimeoutMillis(long gracefulShutdownTimeoutMillis) {
102         return super.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis);
103     }
104 
105     @Override
106     public boolean isServer() {
107         return super.isServer();
108     }
109 
110     @Override
111     public int maxReservedStreams() {
112         return super.maxReservedStreams();
113     }
114 
115     @Override
116     public Http2MultiplexCodecBuilder maxReservedStreams(int maxReservedStreams) {
117         return super.maxReservedStreams(maxReservedStreams);
118     }
119 
120     @Override
121     public boolean isValidateHeaders() {
122         return super.isValidateHeaders();
123     }
124 
125     @Override
126     public Http2MultiplexCodecBuilder validateHeaders(boolean validateHeaders) {
127         return super.validateHeaders(validateHeaders);
128     }
129 
130     @Override
131     public Http2FrameLogger frameLogger() {
132         return super.frameLogger();
133     }
134 
135     @Override
136     public Http2MultiplexCodecBuilder frameLogger(Http2FrameLogger frameLogger) {
137         return super.frameLogger(frameLogger);
138     }
139 
140     @Override
141     public boolean encoderEnforceMaxConcurrentStreams() {
142         return super.encoderEnforceMaxConcurrentStreams();
143     }
144 
145     @Override
146     public Http2MultiplexCodecBuilder encoderEnforceMaxConcurrentStreams(boolean encoderEnforceMaxConcurrentStreams) {
147         return super.encoderEnforceMaxConcurrentStreams(encoderEnforceMaxConcurrentStreams);
148     }
149 
150     @Override
151     public int encoderEnforceMaxQueuedControlFrames() {
152         return super.encoderEnforceMaxQueuedControlFrames();
153     }
154 
155     @Override
156     public Http2MultiplexCodecBuilder encoderEnforceMaxQueuedControlFrames(int maxQueuedControlFrames) {
157         return super.encoderEnforceMaxQueuedControlFrames(maxQueuedControlFrames);
158     }
159 
160     @Override
161     public Http2HeadersEncoder.SensitivityDetector headerSensitivityDetector() {
162         return super.headerSensitivityDetector();
163     }
164 
165     @Override
166     public Http2MultiplexCodecBuilder headerSensitivityDetector(
167             Http2HeadersEncoder.SensitivityDetector headerSensitivityDetector) {
168         return super.headerSensitivityDetector(headerSensitivityDetector);
169     }
170 
171     @Override
172     public Http2MultiplexCodecBuilder encoderIgnoreMaxHeaderListSize(boolean ignoreMaxHeaderListSize) {
173         return super.encoderIgnoreMaxHeaderListSize(ignoreMaxHeaderListSize);
174     }
175 
176     @Override
177     @Deprecated
178     public Http2MultiplexCodecBuilder initialHuffmanDecodeCapacity(int initialHuffmanDecodeCapacity) {
179         return super.initialHuffmanDecodeCapacity(initialHuffmanDecodeCapacity);
180     }
181 
182     @Override
183     public Http2MultiplexCodecBuilder autoAckSettingsFrame(boolean autoAckSettings) {
184         return super.autoAckSettingsFrame(autoAckSettings);
185     }
186 
187     @Override
188     public Http2MultiplexCodecBuilder autoAckPingFrame(boolean autoAckPingFrame) {
189         return super.autoAckPingFrame(autoAckPingFrame);
190     }
191 
192     @Override
193     public Http2MultiplexCodecBuilder decoupleCloseAndGoAway(boolean decoupleCloseAndGoAway) {
194         return super.decoupleCloseAndGoAway(decoupleCloseAndGoAway);
195     }
196 
197     @Override
198     public Http2MultiplexCodecBuilder flushPreface(boolean flushPreface) {
199         return super.flushPreface(flushPreface);
200     }
201 
202     @Override
203     public int decoderEnforceMaxConsecutiveEmptyDataFrames() {
204         return super.decoderEnforceMaxConsecutiveEmptyDataFrames();
205     }
206 
207     @Override
208     public Http2MultiplexCodecBuilder decoderEnforceMaxConsecutiveEmptyDataFrames(int maxConsecutiveEmptyFrames) {
209         return super.decoderEnforceMaxConsecutiveEmptyDataFrames(maxConsecutiveEmptyFrames);
210     }
211 
212     @Override
213     public Http2MultiplexCodecBuilder decoderEnforceMaxRstFramesPerWindow(
214             int maxRstFramesPerWindow, int secondsPerWindow) {
215         return super.decoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow);
216     }
217 
218     @Override
219     public Http2MultiplexCodecBuilder encoderEnforceMaxRstFramesPerWindow(
220             int maxRstFramesPerWindow, int secondsPerWindow) {
221         return super.encoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow);
222     }
223 
224     @Override
225     public Http2MultiplexCodec build() {
226         Http2FrameWriter frameWriter = this.frameWriter;
227         if (frameWriter != null) {
228             // This is to support our tests and will never be executed by the user as frameWriter(...)
229             // is package-private.
230             DefaultHttp2Connection connection = new DefaultHttp2Connection(isServer(), maxReservedStreams());
231             Long maxHeaderListSize = initialSettings().maxHeaderListSize();
232             Http2FrameReader frameReader = new DefaultHttp2FrameReader(maxHeaderListSize == null ?
233                     new DefaultHttp2HeadersDecoder(isValidateHeaders()) :
234                     new DefaultHttp2HeadersDecoder(isValidateHeaders(), maxHeaderListSize));
235 
236             if (frameLogger() != null) {
237                 frameWriter = new Http2OutboundFrameLogger(frameWriter, frameLogger());
238                 frameReader = new Http2InboundFrameLogger(frameReader, frameLogger());
239             }
240             Http2ConnectionEncoder encoder = new DefaultHttp2ConnectionEncoder(connection, frameWriter);
241             if (encoderEnforceMaxConcurrentStreams()) {
242                 encoder = new StreamBufferingEncoder(encoder);
243             }
244             Http2ConnectionDecoder decoder = new DefaultHttp2ConnectionDecoder(connection, encoder, frameReader,
245                     promisedRequestVerifier(), isAutoAckSettingsFrame(), isAutoAckPingFrame(), isValidateHeaders());
246             int maxConsecutiveEmptyDataFrames = decoderEnforceMaxConsecutiveEmptyDataFrames();
247             if (maxConsecutiveEmptyDataFrames > 0) {
248                 decoder = new Http2EmptyDataFrameConnectionDecoder(decoder, maxConsecutiveEmptyDataFrames);
249             }
250 
251             return build(decoder, encoder, initialSettings());
252         }
253         return super.build();
254     }
255 
256     @Override
257     protected Http2MultiplexCodec build(
258             Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder, Http2Settings initialSettings) {
259         Http2MultiplexCodec codec = new Http2MultiplexCodec(encoder, decoder, initialSettings, childHandler,
260                 upgradeStreamHandler, decoupleCloseAndGoAway(), flushPreface());
261         codec.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis());
262         return codec;
263     }
264 }