1818import io .vertx .core .impl .Arguments ;
1919import io .vertx .core .json .JsonObject ;
2020
21+ import java .util .EnumSet ;
2122import java .util .HashMap ;
2223import java .util .Map ;
24+ import java .util .function .LongConsumer ;
2325
2426/**
2527 * HTTP2 settings, the settings is initialized with the default HTTP/2 values.<p>
3133 */
3234@ DataObject
3335@ JsonGen (publicConverter = false )
34- public class Http2Settings {
36+ public final class Http2Settings extends HttpSettings {
3537
3638 /**
3739 * Default HTTP/2 spec value for {@link #getHeaderTableSize} : {@code 4096}
@@ -68,24 +70,98 @@ public class Http2Settings {
6870 */
6971 public static final Map <Integer , Long > DEFAULT_EXTRA_SETTINGS = null ;
7072
71- private long headerTableSize ;
72- private boolean pushEnabled ;
73- private long maxConcurrentStreams ;
74- private int initialWindowSize ;
75- private int maxFrameSize ;
76- private long maxHeaderListSize ;
73+ /**
74+ * HTTP/2 {@code HEADER_TABLE_SIZE} setting
75+ */
76+ public static final HttpSetting <Long > HEADER_TABLE_SIZE ;
77+
78+ /**
79+ * HTTP/2 {@code HEADER_TABLE_SIZE} setting
80+ */
81+ public static final HttpSetting <Boolean > ENABLE_PUSH ;
82+
83+ /**
84+ * HTTP/2 {@code MAX_CONCURRENT_STREAMS} setting
85+ */
86+ public static final HttpSetting <Long > MAX_CONCURRENT_STREAMS ;
87+
88+ /**
89+ * HTTP/2 {@code INITIAL_WINDOW_SIZE} setting
90+ */
91+ public static final HttpSetting <Integer > INITIAL_WINDOW_SIZE ;
92+
93+ /**
94+ * HTTP/2 {@code MAX_FRAME_SIZE} setting
95+ */
96+ public static final HttpSetting <Integer > MAX_FRAME_SIZE ;
97+
98+ /**
99+ * HTTP/2 {@code MAX_HEADER_LIST_SIZE} setting
100+ */
101+ public static final HttpSetting <Long > MAX_HEADER_LIST_SIZE ;
102+
103+ static {
104+
105+ EnumSet <HttpVersion > baseVersions = EnumSet .of (HttpVersion .HTTP_2 );
106+
107+ LongConsumer headerTableSizeValidator = value -> {
108+ Arguments .require (value >= Http2CodecUtil .MIN_HEADER_TABLE_SIZE ,
109+ "headerTableSize must be >= " + Http2CodecUtil .MIN_HEADER_TABLE_SIZE );
110+ Arguments .require (value <= Http2CodecUtil .MAX_HEADER_TABLE_SIZE ,
111+ "headerTableSize must be <= " + Http2CodecUtil .MAX_HEADER_TABLE_SIZE );
112+ };
113+ HEADER_TABLE_SIZE = new HttpSetting <>(0x01 , "HEADER_TABLE_SIZE" , 4096L ,
114+ val -> val , val -> val , headerTableSizeValidator , baseVersions );
115+
116+ LongConsumer enablePushValidator = value -> {
117+ Arguments .require (value == 0 || value == 1 , "enablePush must be 0 or 1" );
118+ };
119+ ENABLE_PUSH = new HttpSetting <>(0x02 , "ENABLE_PUSH" , true ,
120+ val -> val == null ? 1L : (val ? 1 : 0 ), val -> val == 1L , enablePushValidator , baseVersions );
121+
122+ LongConsumer maxConcurrentStreamsValidator = value -> {
123+ Arguments .require (value >= Http2CodecUtil .MIN_CONCURRENT_STREAMS ,
124+ "value must be >= " + Http2CodecUtil .MIN_CONCURRENT_STREAMS );
125+ Arguments .require (value <= Http2CodecUtil .MAX_CONCURRENT_STREAMS ,
126+ "value must be <= " + Http2CodecUtil .MAX_CONCURRENT_STREAMS );
127+ };
128+ MAX_CONCURRENT_STREAMS = new HttpSetting <>(0x03 , "MAX_CONCURRENT_STREAMS" , 0xFFFFFFFFL ,
129+ val -> val , val -> val , maxConcurrentStreamsValidator , baseVersions );
130+
131+ LongConsumer initialWindowSizeValidator = value -> {
132+ Arguments .require (value >= Http2CodecUtil .MIN_INITIAL_WINDOW_SIZE ,
133+ "value must be >= " + Http2CodecUtil .MIN_INITIAL_WINDOW_SIZE );
134+ Arguments .require (value <= Http2CodecUtil .MAX_INITIAL_WINDOW_SIZE ,
135+ "value must be <= " + Http2CodecUtil .MAX_INITIAL_WINDOW_SIZE );
136+ };
137+ INITIAL_WINDOW_SIZE = new HttpSetting <>(0x04 , "INITIAL_WINDOW_SIZE" , 65535 ,
138+ val -> val , val -> (int )val , initialWindowSizeValidator , baseVersions );
139+
140+ LongConsumer maxFrameSizeValidator = value -> {
141+ Arguments .require (value >= Http2CodecUtil .MAX_FRAME_SIZE_LOWER_BOUND ,
142+ "value must be >= " + Http2CodecUtil .MAX_FRAME_SIZE_LOWER_BOUND );
143+ Arguments .require (value <= Http2CodecUtil .MAX_FRAME_SIZE_UPPER_BOUND ,
144+ "value must be <= " + Http2CodecUtil .MAX_FRAME_SIZE_UPPER_BOUND );
145+ };
146+ MAX_FRAME_SIZE = new HttpSetting <>(0x05 , "MAX_FRAME_SIZE" , 16384 ,
147+ val -> val , val -> (int )val , maxFrameSizeValidator , baseVersions );
148+
149+ LongConsumer maxHeaderListSizeValidator = value -> {
150+ Arguments .require (value >= Http2CodecUtil .MIN_HEADER_LIST_SIZE ,
151+ "maxHeaderListSize must be >= " + Http2CodecUtil .MIN_HEADER_LIST_SIZE );
152+ Arguments .require (value <= Http2CodecUtil .MAX_HEADER_LIST_SIZE , "value must be <= " + Http2CodecUtil .MAX_HEADER_LIST_SIZE );
153+ };
154+ MAX_HEADER_LIST_SIZE = new HttpSetting <>(0x06 , "MAX_HEADER_LIST_SIZE" , 8192L ,
155+ val -> val , val -> val , maxHeaderListSizeValidator , baseVersions );
156+ }
157+
77158 private Map <Integer , Long > extraSettings ;
78159
79160 /**
80161 * Default constructor
81162 */
82163 public Http2Settings () {
83- headerTableSize = DEFAULT_HEADER_TABLE_SIZE ;
84- pushEnabled = DEFAULT_ENABLE_PUSH ;
85- maxConcurrentStreams = DEFAULT_MAX_CONCURRENT_STREAMS ;
86- initialWindowSize = DEFAULT_INITIAL_WINDOW_SIZE ;
87- maxFrameSize = DEFAULT_MAX_FRAME_SIZE ;
88- maxHeaderListSize = DEFAULT_MAX_HEADER_LIST_SIZE ;
164+ super (7 );
89165 extraSettings = DEFAULT_EXTRA_SETTINGS ;
90166 }
91167
@@ -105,20 +181,25 @@ public Http2Settings(JsonObject json) {
105181 * @param other the settings to copy
106182 */
107183 public Http2Settings (Http2Settings other ) {
108- headerTableSize = other .headerTableSize ;
109- pushEnabled = other .pushEnabled ;
110- maxConcurrentStreams = other .maxConcurrentStreams ;
111- initialWindowSize = other .initialWindowSize ;
112- maxFrameSize = other .maxFrameSize ;
113- maxHeaderListSize = other .maxHeaderListSize ;
184+ super (other );
114185 extraSettings = other .extraSettings != null ? new HashMap <>(other .extraSettings ) : null ;
115186 }
116187
188+ @ Override
189+ public Http2Settings copy () {
190+ return new Http2Settings (this );
191+ }
192+
193+ @ Override
194+ HttpVersion version () {
195+ return HttpVersion .HTTP_2 ;
196+ }
197+
117198 /**
118199 * @return the {@literal SETTINGS_HEADER_TABLE_SIZE} HTTP/2 setting
119200 */
120201 public long getHeaderTableSize () {
121- return headerTableSize ;
202+ return getOrDefault ( HEADER_TABLE_SIZE ) ;
122203 }
123204
124205 /**
@@ -128,19 +209,15 @@ public long getHeaderTableSize() {
128209 * @return a reference to this, so the API can be used fluently
129210 */
130211 public Http2Settings setHeaderTableSize (long headerTableSize ) {
131- Arguments .require (headerTableSize >= Http2CodecUtil .MIN_HEADER_TABLE_SIZE ,
132- "headerTableSize must be >= " + Http2CodecUtil .MIN_HEADER_TABLE_SIZE );
133- Arguments .require (headerTableSize <= Http2CodecUtil .MAX_HEADER_TABLE_SIZE ,
134- "headerTableSize must be <= " + Http2CodecUtil .MAX_HEADER_TABLE_SIZE );
135- this .headerTableSize = headerTableSize ;
212+ setLong (HEADER_TABLE_SIZE , headerTableSize );
136213 return this ;
137214 }
138215
139216 /**
140217 * @return the {@literal SETTINGS_ENABLE_PUSH} HTTP/2 setting
141218 */
142219 public boolean isPushEnabled () {
143- return pushEnabled ;
220+ return getOrDefault ( ENABLE_PUSH ) ;
144221 }
145222
146223 /**
@@ -150,15 +227,14 @@ public boolean isPushEnabled() {
150227 * @return a reference to this, so the API can be used fluently
151228 */
152229 public Http2Settings setPushEnabled (boolean pushEnabled ) {
153- this .pushEnabled = pushEnabled ;
154- return this ;
230+ return set (ENABLE_PUSH , pushEnabled );
155231 }
156232
157233 /**
158234 * @return the {@literal SETTINGS_MAX_CONCURRENT_STREAMS} HTTP/2 setting
159235 */
160236 public long getMaxConcurrentStreams () {
161- return maxConcurrentStreams ;
237+ return getOrDefault ( MAX_CONCURRENT_STREAMS ) ;
162238 }
163239
164240 /**
@@ -168,19 +244,14 @@ public long getMaxConcurrentStreams() {
168244 * @return a reference to this, so the API can be used fluently
169245 */
170246 public Http2Settings setMaxConcurrentStreams (long maxConcurrentStreams ) {
171- Arguments .require (maxConcurrentStreams >= Http2CodecUtil .MIN_CONCURRENT_STREAMS ,
172- "maxConcurrentStreams must be >= " + Http2CodecUtil .MIN_CONCURRENT_STREAMS );
173- Arguments .require (maxConcurrentStreams <= Http2CodecUtil .MAX_CONCURRENT_STREAMS ,
174- "maxConcurrentStreams must be < " + Http2CodecUtil .MAX_CONCURRENT_STREAMS );
175- this .maxConcurrentStreams = maxConcurrentStreams ;
176- return this ;
247+ return setLong (MAX_CONCURRENT_STREAMS , maxConcurrentStreams );
177248 }
178249
179250 /**
180251 * @return the {@literal SETTINGS_INITIAL_WINDOW_SIZE} HTTP/2 setting
181252 */
182253 public int getInitialWindowSize () {
183- return initialWindowSize ;
254+ return getOrDefault ( INITIAL_WINDOW_SIZE ) ;
184255 }
185256
186257 /**
@@ -190,17 +261,14 @@ public int getInitialWindowSize() {
190261 * @return a reference to this, so the API can be used fluently
191262 */
192263 public Http2Settings setInitialWindowSize (int initialWindowSize ) {
193- Arguments .require (initialWindowSize >= Http2CodecUtil .MIN_INITIAL_WINDOW_SIZE ,
194- "initialWindowSize must be >= " + Http2CodecUtil .MIN_INITIAL_WINDOW_SIZE );
195- this .initialWindowSize = initialWindowSize ;
196- return this ;
264+ return set (INITIAL_WINDOW_SIZE , initialWindowSize );
197265 }
198266
199267 /**
200268 * @return the {@literal SETTINGS_MAX_FRAME_SIZE} HTTP/2 setting
201269 */
202270 public int getMaxFrameSize () {
203- return maxFrameSize ;
271+ return getOrDefault ( MAX_FRAME_SIZE ) ;
204272 }
205273
206274 /**
@@ -210,19 +278,14 @@ public int getMaxFrameSize() {
210278 * @return a reference to this, so the API can be used fluently
211279 */
212280 public Http2Settings setMaxFrameSize (int maxFrameSize ) {
213- Arguments .require (maxFrameSize >= Http2CodecUtil .MAX_FRAME_SIZE_LOWER_BOUND ,
214- "maxFrameSize must be >= " + Http2CodecUtil .MAX_FRAME_SIZE_LOWER_BOUND );
215- Arguments .require (maxFrameSize <= Http2CodecUtil .MAX_FRAME_SIZE_UPPER_BOUND ,
216- "maxFrameSize must be <= " + Http2CodecUtil .MAX_FRAME_SIZE_UPPER_BOUND );
217- this .maxFrameSize = maxFrameSize ;
218- return this ;
281+ return set (MAX_FRAME_SIZE , maxFrameSize );
219282 }
220283
221284 /**
222285 * @return the {@literal SETTINGS_MAX_HEADER_LIST_SIZE} HTTP/2 setting
223286 */
224287 public long getMaxHeaderListSize () {
225- return maxHeaderListSize ;
288+ return getOrDefault ( MAX_HEADER_LIST_SIZE ) ;
226289 }
227290
228291 /**
@@ -232,11 +295,7 @@ public long getMaxHeaderListSize() {
232295 * @return a reference to this, so the API can be used fluently
233296 */
234297 public Http2Settings setMaxHeaderListSize (long maxHeaderListSize ) {
235- Arguments .require (maxHeaderListSize >= 0 , "maxHeaderListSize must be >= 0" );
236- Arguments .require (maxHeaderListSize >= Http2CodecUtil .MIN_HEADER_LIST_SIZE ,
237- "maxHeaderListSize must be >= " + Http2CodecUtil .MIN_HEADER_LIST_SIZE );
238- this .maxHeaderListSize = maxHeaderListSize ;
239- return this ;
298+ return set (MAX_HEADER_LIST_SIZE , maxHeaderListSize );
240299 }
241300
242301 /**
@@ -266,19 +325,20 @@ public Http2Settings setExtraSettings(Map<Integer, Long> settings) {
266325 * @return the setting value
267326 */
268327 public Long get (int id ) {
328+ // Use static array
269329 switch (id ) {
270330 case 1 :
271- return headerTableSize ;
331+ return getLongOrDefault ( HEADER_TABLE_SIZE ) ;
272332 case 2 :
273- return pushEnabled ? 1L : 0L ;
333+ return getLongOrDefault ( ENABLE_PUSH ) ;
274334 case 3 :
275- return maxConcurrentStreams ;
335+ return getLongOrDefault ( MAX_CONCURRENT_STREAMS ) ;
276336 case 4 :
277- return ( long ) initialWindowSize ;
337+ return getLongOrDefault ( INITIAL_WINDOW_SIZE ) ;
278338 case 5 :
279- return ( long ) maxFrameSize ;
339+ return getLongOrDefault ( MAX_FRAME_SIZE ) ;
280340 case 6 :
281- return ( long ) maxHeaderListSize ;
341+ return getLongOrDefault ( MAX_HEADER_LIST_SIZE ) ;
282342 default :
283343 return extraSettings != null ? extraSettings .get (id ) : null ;
284344 }
@@ -296,24 +356,22 @@ public Http2Settings set(int id, long value) {
296356 Arguments .require (value >= 0L && value <= 0xFFFFFFFFL , "Setting value must me an unsigned 32-bit value" );
297357 switch (id ) {
298358 case 1 :
299- setHeaderTableSize ( value );
359+ setLong ( HEADER_TABLE_SIZE , value );
300360 break ;
301361 case 2 :
302- Arguments .require (value == 0 || value == 1 , "enablePush must be 0 or 1" );
303- setPushEnabled (value == 1 );
362+ setLong (ENABLE_PUSH , value );
304363 break ;
305364 case 3 :
306- setMaxConcurrentStreams ( value );
365+ setLong ( MAX_CONCURRENT_STREAMS , value );
307366 break ;
308367 case 4 :
309- setInitialWindowSize (( int ) value );
368+ setLong ( INITIAL_WINDOW_SIZE , value );
310369 break ;
311370 case 5 :
312- setMaxFrameSize (( int ) value );
371+ setLong ( MAX_FRAME_SIZE , value );
313372 break ;
314373 case 6 :
315- Arguments .require (value <= Integer .MAX_VALUE , "maxHeaderListSize must be <= " + Integer .MAX_VALUE );
316- setMaxHeaderListSize ((int ) value );
374+ setLong (MAX_HEADER_LIST_SIZE , value );
317375 break ;
318376 default :
319377 if (extraSettings == null ) {
@@ -324,30 +382,44 @@ public Http2Settings set(int id, long value) {
324382 return this ;
325383 }
326384
385+ @ Override
386+ public <T > Http2Settings set (HttpSetting <T > setting , T value ) {
387+ return (Http2Settings )super .set (setting , value );
388+ }
389+
390+ @ Override
391+ public Http2Settings setLong (HttpSetting <?> setting , long value ) {
392+ return (Http2Settings )super .setLong (setting , value );
393+ }
394+
327395 @ Override
328396 public boolean equals (Object o ) {
397+
398+ // Reimplement in super class
399+
329400 if (this == o ) return true ;
330401 if (o == null || getClass () != o .getClass ()) return false ;
331402
332403 Http2Settings that = (Http2Settings ) o ;
333404
334- if (headerTableSize != that .headerTableSize ) return false ;
335- if (pushEnabled != that .pushEnabled ) return false ;
336- if (maxConcurrentStreams != that .maxConcurrentStreams ) return false ;
337- if (initialWindowSize != that .initialWindowSize ) return false ;
338- if (maxFrameSize != that .maxFrameSize ) return false ;
339- if (maxHeaderListSize != that .maxHeaderListSize ) return false ;
405+ if (getHeaderTableSize () != that .getHeaderTableSize () ) return false ;
406+ if (isPushEnabled () != that .isPushEnabled () ) return false ;
407+ if (getMaxConcurrentStreams () != that .getMaxConcurrentStreams () ) return false ;
408+ if (getInitialWindowSize () != that .getInitialWindowSize () ) return false ;
409+ if (getMaxFrameSize () != that .getMaxFrameSize () ) return false ;
410+ if (getMaxHeaderListSize () != that .getMaxHeaderListSize () ) return false ;
340411 return true ;
341412 }
342413
343414 @ Override
344415 public int hashCode () {
416+ long headerTableSize = getHeaderTableSize ();
345417 int result = (int ) (headerTableSize ^ (headerTableSize >>> 32 ));
346- result = 31 * result + (pushEnabled ? 1 : 0 );
347- result = 31 * result + (int ) (maxConcurrentStreams ^ (maxConcurrentStreams >>> 32 ));
348- result = 31 * result + initialWindowSize ;
349- result = 31 * result + maxFrameSize ;
350- result = 31 * result + (int ) (maxHeaderListSize ^ (maxHeaderListSize >>> 32 ));
418+ result = 31 * result + (isPushEnabled () ? 1 : 0 );
419+ result = 31 * result + (int ) (getMaxConcurrentStreams () ^ (getMaxConcurrentStreams () >>> 32 ));
420+ result = 31 * result + getInitialWindowSize () ;
421+ result = 31 * result + getMaxFrameSize () ;
422+ result = 31 * result + (int ) (getMaxHeaderListSize () ^ (getMaxHeaderListSize () >>> 32 ));
351423 return result ;
352424 }
353425
0 commit comments