View Javadoc
1   /*
2    * Copyright 2015 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License, version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * 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 distributed under the License
11   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing permissions and limitations under
13   * the License.
14   */
15  package io.netty5.handler.codec.http2;
16  
17  import io.netty5.handler.codec.TooLongFrameException;
18  import io.netty5.util.internal.UnstableApi;
19  
20  import static java.util.Objects.requireNonNull;
21  
22  /**
23   * A skeletal builder implementation of {@link InboundHttp2ToHttpAdapter} and its subtypes.
24   */
25  @UnstableApi
26  public abstract class AbstractInboundHttp2ToHttpAdapterBuilder<
27          T extends InboundHttp2ToHttpAdapter, B extends AbstractInboundHttp2ToHttpAdapterBuilder<T, B>> {
28  
29      private final Http2Connection connection;
30      private int maxContentLength;
31      private boolean validateHttpHeaders;
32      private boolean propagateSettings;
33  
34      /**
35       * Creates a new {@link InboundHttp2ToHttpAdapter} builder for the specified {@link Http2Connection}.
36       *
37       * @param connection the object which will provide connection notification events
38       *                   for the current connection
39       */
40      protected AbstractInboundHttp2ToHttpAdapterBuilder(Http2Connection connection) {
41          this.connection = requireNonNull(connection, "connection");
42      }
43  
44      @SuppressWarnings("unchecked")
45      protected final B self() {
46          return (B) this;
47      }
48  
49      /**
50       * Returns the {@link Http2Connection}.
51       */
52      protected Http2Connection connection() {
53          return connection;
54      }
55  
56      /**
57       * Returns the maximum length of the message content.
58       */
59      protected int maxContentLength() {
60          return maxContentLength;
61      }
62  
63      /**
64       * Specifies the maximum length of the message content.
65       *
66       * @param maxContentLength the maximum length of the message content. If the length of the message content
67       *        exceeds this value, a {@link TooLongFrameException} will be raised
68       * @return {@link AbstractInboundHttp2ToHttpAdapterBuilder} the builder for the {@link InboundHttp2ToHttpAdapter}
69       */
70      protected B maxContentLength(int maxContentLength) {
71          this.maxContentLength = maxContentLength;
72          return self();
73      }
74  
75      /**
76       * Return {@code true} if HTTP header validation should be performed.
77       */
78      protected boolean isValidateHttpHeaders() {
79          return validateHttpHeaders;
80      }
81  
82      /**
83       * Specifies whether validation of HTTP headers should be performed.
84       *
85       * @param validate
86       * <ul>
87       * <li>{@code true} to validate HTTP headers in the http-codec</li>
88       * <li>{@code false} not to validate HTTP headers in the http-codec</li>
89       * </ul>
90       * @return {@link AbstractInboundHttp2ToHttpAdapterBuilder} the builder for the {@link InboundHttp2ToHttpAdapter}
91       */
92      protected B validateHttpHeaders(boolean validate) {
93          validateHttpHeaders = validate;
94          return self();
95      }
96  
97      /**
98       * Returns {@code true} if a read settings frame should be propagated along the channel pipeline.
99       */
100     protected boolean isPropagateSettings() {
101         return propagateSettings;
102     }
103 
104     /**
105      * Specifies whether a read settings frame should be propagated along the channel pipeline.
106      *
107      * @param propagate if {@code true} read settings will be passed along the pipeline. This can be useful
108      *                     to clients that need hold off sending data until they have received the settings.
109      * @return {@link AbstractInboundHttp2ToHttpAdapterBuilder} the builder for the {@link InboundHttp2ToHttpAdapter}
110      */
111     protected B propagateSettings(boolean propagate) {
112         propagateSettings = propagate;
113         return self();
114     }
115 
116     /**
117      * Builds/creates a new {@link InboundHttp2ToHttpAdapter} instance using this builder's current settings.
118      */
119     protected T build() {
120         final T instance;
121         try {
122             instance = build(connection(), maxContentLength(),
123                                      isValidateHttpHeaders(), isPropagateSettings());
124         } catch (Throwable t) {
125             throw new IllegalStateException("failed to create a new InboundHttp2ToHttpAdapter", t);
126         }
127         connection.addListener(instance);
128         return instance;
129     }
130 
131     /**
132      * Creates a new {@link InboundHttp2ToHttpAdapter} with the specified properties.
133      */
134     protected abstract T build(Http2Connection connection, int maxContentLength,
135                                boolean validateHttpHeaders, boolean propagateSettings) throws Exception;
136 }