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 Http2MultiplexCodec build() {
220         Http2FrameWriter frameWriter = this.frameWriter;
221         if (frameWriter != null) {
222             // This is to support our tests and will never be executed by the user as frameWriter(...)
223             // is package-private.
224             DefaultHttp2Connection connection = new DefaultHttp2Connection(isServer(), maxReservedStreams());
225             Long maxHeaderListSize = initialSettings().maxHeaderListSize();
226             Http2FrameReader frameReader = new DefaultHttp2FrameReader(maxHeaderListSize == null ?
227                     new DefaultHttp2HeadersDecoder(isValidateHeaders()) :
228                     new DefaultHttp2HeadersDecoder(isValidateHeaders(), maxHeaderListSize));
229 
230             if (frameLogger() != null) {
231                 frameWriter = new Http2OutboundFrameLogger(frameWriter, frameLogger());
232                 frameReader = new Http2InboundFrameLogger(frameReader, frameLogger());
233             }
234             Http2ConnectionEncoder encoder = new DefaultHttp2ConnectionEncoder(connection, frameWriter);
235             if (encoderEnforceMaxConcurrentStreams()) {
236                 encoder = new StreamBufferingEncoder(encoder);
237             }
238             Http2ConnectionDecoder decoder = new DefaultHttp2ConnectionDecoder(connection, encoder, frameReader,
239                     promisedRequestVerifier(), isAutoAckSettingsFrame(), isAutoAckPingFrame(), isValidateHeaders());
240             int maxConsecutiveEmptyDataFrames = decoderEnforceMaxConsecutiveEmptyDataFrames();
241             if (maxConsecutiveEmptyDataFrames > 0) {
242                 decoder = new Http2EmptyDataFrameConnectionDecoder(decoder, maxConsecutiveEmptyDataFrames);
243             }
244 
245             return build(decoder, encoder, initialSettings());
246         }
247         return super.build();
248     }
249 
250     @Override
251     protected Http2MultiplexCodec build(
252             Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder, Http2Settings initialSettings) {
253         Http2MultiplexCodec codec = new Http2MultiplexCodec(encoder, decoder, initialSettings, childHandler,
254                 upgradeStreamHandler, decoupleCloseAndGoAway(), flushPreface());
255         codec.gracefulShutdownTimeoutMillis(gracefulShutdownTimeoutMillis());
256         return codec;
257     }
258 }