View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http2.config;
29  
30  import org.apache.hc.core5.annotation.Contract;
31  import org.apache.hc.core5.annotation.ThreadingBehavior;
32  import org.apache.hc.core5.http2.frame.FrameConsts;
33  import org.apache.hc.core5.util.Args;
34  
35  /**
36   * HTTP/2 protocol configuration.
37   *
38   * @since 5.0
39   */
40  @Contract(threading = ThreadingBehavior.IMMUTABLE)
41  public class H2Config {
42  
43      public static final H2Config DEFAULT = custom().build();
44      public static final H2Config INIT = initial().build();
45  
46      private final int headerTableSize;
47      private final boolean pushEnabled;
48      private final int maxConcurrentStreams;
49      private final int initialWindowSize;
50      private final int maxFrameSize;
51      private final int maxHeaderListSize;
52      private final boolean compressionEnabled;
53  
54      H2Config(final int headerTableSize, final boolean pushEnabled, final int maxConcurrentStreams,
55               final int initialWindowSize, final int maxFrameSize, final int maxHeaderListSize,
56               final boolean compressionEnabled) {
57          super();
58          this.headerTableSize = headerTableSize;
59          this.pushEnabled = pushEnabled;
60          this.maxConcurrentStreams = maxConcurrentStreams;
61          this.initialWindowSize = initialWindowSize;
62          this.maxFrameSize = maxFrameSize;
63          this.maxHeaderListSize = maxHeaderListSize;
64          this.compressionEnabled = compressionEnabled;
65      }
66  
67      public int getHeaderTableSize() {
68          return headerTableSize;
69      }
70  
71      public boolean isPushEnabled() {
72          return pushEnabled;
73      }
74  
75      public int getMaxConcurrentStreams() {
76          return maxConcurrentStreams;
77      }
78  
79      public int getInitialWindowSize() {
80          return initialWindowSize;
81      }
82  
83      public int getMaxFrameSize() {
84          return maxFrameSize;
85      }
86  
87      public int getMaxHeaderListSize() {
88          return maxHeaderListSize;
89      }
90  
91      public boolean isCompressionEnabled() {
92          return compressionEnabled;
93      }
94  
95      @Override
96      public String toString() {
97          final StringBuilder builder = new StringBuilder();
98          builder.append("[headerTableSize=").append(this.headerTableSize)
99                  .append(", pushEnabled=").append(this.pushEnabled)
100                 .append(", maxConcurrentStreams=").append(this.maxConcurrentStreams)
101                 .append(", initialWindowSize=").append(this.initialWindowSize)
102                 .append(", maxFrameSize=").append(this.maxFrameSize)
103                 .append(", maxHeaderListSize=").append(this.maxHeaderListSize)
104                 .append(", compressionEnabled=").append(this.compressionEnabled)
105                 .append("]");
106         return builder.toString();
107     }
108 
109     public static H2Config.Builder custom() {
110         return new Builder();
111     }
112 
113     private static final int      INIT_HEADER_TABLE_SIZE   = 4096;
114     private static final boolean  INIT_ENABLE_PUSH         = true;
115     private static final int      INIT_MAX_FRAME_SIZE      = FrameConsts.MIN_FRAME_SIZE;
116     private static final int      INIT_WINDOW_SIZE         = 65535;
117 
118     public static H2Config.Builder initial() {
119         return new Builder()
120                 .setHeaderTableSize(INIT_HEADER_TABLE_SIZE)
121                 .setPushEnabled(INIT_ENABLE_PUSH)
122                 .setMaxConcurrentStreams(Integer.MAX_VALUE) // no limit
123                 .setMaxFrameSize(INIT_MAX_FRAME_SIZE)
124                 .setInitialWindowSize(INIT_WINDOW_SIZE)
125                 .setMaxHeaderListSize(Integer.MAX_VALUE); // unlimited
126     }
127 
128     public static H2Config.Builder copy(final H2Config config) {
129         Args.notNull(config, "Connection config");
130         return new Builder()
131                 .setHeaderTableSize(config.getHeaderTableSize())
132                 .setPushEnabled(config.isPushEnabled())
133                 .setMaxConcurrentStreams(config.getMaxConcurrentStreams())
134                 .setInitialWindowSize(config.getInitialWindowSize())
135                 .setMaxFrameSize(config.getMaxFrameSize())
136                 .setMaxHeaderListSize(config.getMaxHeaderListSize())
137                 .setCompressionEnabled(config.isCompressionEnabled());
138     }
139 
140     public static class Builder {
141 
142         private int headerTableSize;
143         private boolean pushEnabled;
144         private int maxConcurrentStreams;
145         private int initialWindowSize;
146         private int maxFrameSize;
147         private int maxHeaderListSize;
148         private boolean compressionEnabled;
149 
150         Builder() {
151             this.headerTableSize = INIT_HEADER_TABLE_SIZE * 2;
152             this.pushEnabled = INIT_ENABLE_PUSH;
153             this.maxConcurrentStreams = 250;
154             this.initialWindowSize = INIT_WINDOW_SIZE;
155             this.maxFrameSize  = FrameConsts.MIN_FRAME_SIZE * 4;
156             this.maxHeaderListSize = FrameConsts.MAX_FRAME_SIZE;
157             this.compressionEnabled = true;
158         }
159 
160         public Builder setHeaderTableSize(final int headerTableSize) {
161             Args.notNegative(headerTableSize, "Header table size");
162             this.headerTableSize = headerTableSize;
163             return this;
164         }
165 
166         public Builder setPushEnabled(final boolean pushEnabled) {
167             this.pushEnabled = pushEnabled;
168             return this;
169         }
170 
171         public Builder setMaxConcurrentStreams(final int maxConcurrentStreams) {
172             Args.positive(maxConcurrentStreams, "Max concurrent streams");
173             this.maxConcurrentStreams = maxConcurrentStreams;
174             return this;
175         }
176 
177         public Builder setInitialWindowSize(final int initialWindowSize) {
178             Args.positive(initialWindowSize, "Initial window size");
179             this.initialWindowSize = initialWindowSize;
180             return this;
181         }
182 
183         public Builder setMaxFrameSize(final int maxFrameSize) {
184             this.maxFrameSize = Args.checkRange(maxFrameSize, FrameConsts.MIN_FRAME_SIZE, FrameConsts.MAX_FRAME_SIZE,
185                     "Invalid max frame size");
186             return this;
187         }
188 
189         public Builder setMaxHeaderListSize(final int maxHeaderListSize) {
190             Args.positive(maxHeaderListSize, "Max header list size");
191             this.maxHeaderListSize = maxHeaderListSize;
192             return this;
193         }
194 
195         public Builder setCompressionEnabled(final boolean compressionEnabled) {
196             this.compressionEnabled = compressionEnabled;
197             return this;
198         }
199 
200         public H2Config build() {
201             return new H2Config(
202                     headerTableSize,
203                     pushEnabled,
204                     maxConcurrentStreams,
205                     initialWindowSize,
206                     maxFrameSize,
207                     maxHeaderListSize,
208                     compressionEnabled);
209         }
210 
211     }
212 
213 }