1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package io.netty5.handler.codec.http2;
16
17 import io.netty5.util.collection.CharObjectHashMap;
18 import io.netty5.util.internal.UnstableApi;
19
20 import static io.netty5.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_LIST_SIZE;
21 import static io.netty5.handler.codec.http2.Http2CodecUtil.MAX_CONCURRENT_STREAMS;
22 import static io.netty5.handler.codec.http2.Http2CodecUtil.MAX_HEADER_LIST_SIZE;
23 import static io.netty5.handler.codec.http2.Http2CodecUtil.MAX_HEADER_TABLE_SIZE;
24 import static io.netty5.handler.codec.http2.Http2CodecUtil.MAX_INITIAL_WINDOW_SIZE;
25 import static io.netty5.handler.codec.http2.Http2CodecUtil.MIN_CONCURRENT_STREAMS;
26 import static io.netty5.handler.codec.http2.Http2CodecUtil.MIN_HEADER_LIST_SIZE;
27 import static io.netty5.handler.codec.http2.Http2CodecUtil.MIN_HEADER_TABLE_SIZE;
28 import static io.netty5.handler.codec.http2.Http2CodecUtil.MIN_INITIAL_WINDOW_SIZE;
29 import static io.netty5.handler.codec.http2.Http2CodecUtil.NUM_STANDARD_SETTINGS;
30 import static io.netty5.handler.codec.http2.Http2CodecUtil.SETTINGS_ENABLE_PUSH;
31 import static io.netty5.handler.codec.http2.Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE;
32 import static io.netty5.handler.codec.http2.Http2CodecUtil.SETTINGS_INITIAL_WINDOW_SIZE;
33 import static io.netty5.handler.codec.http2.Http2CodecUtil.SETTINGS_MAX_CONCURRENT_STREAMS;
34 import static io.netty5.handler.codec.http2.Http2CodecUtil.SETTINGS_MAX_FRAME_SIZE;
35 import static io.netty5.handler.codec.http2.Http2CodecUtil.SETTINGS_MAX_HEADER_LIST_SIZE;
36 import static io.netty5.handler.codec.http2.Http2CodecUtil.isMaxFrameSizeValid;
37 import static java.util.Objects.requireNonNull;
38
39
40
41
42
43
44 @UnstableApi
45 public final class Http2Settings extends CharObjectHashMap<Long> {
46
47
48
49
50 private static final int DEFAULT_CAPACITY = (int) (NUM_STANDARD_SETTINGS / DEFAULT_LOAD_FACTOR) + 1;
51 private static final Long FALSE = 0L;
52 private static final Long TRUE = 1L;
53
54 public Http2Settings() {
55 this(DEFAULT_CAPACITY);
56 }
57
58 public Http2Settings(int initialCapacity, float loadFactor) {
59 super(initialCapacity, loadFactor);
60 }
61
62 public Http2Settings(int initialCapacity) {
63 super(initialCapacity);
64 }
65
66
67
68
69
70
71
72 @Override
73 public Long put(char key, Long value) {
74 verifyStandardSetting(key, value);
75 return super.put(key, value);
76 }
77
78
79
80
81 public Long headerTableSize() {
82 return get(SETTINGS_HEADER_TABLE_SIZE);
83 }
84
85
86
87
88
89
90 public Http2Settings headerTableSize(long value) {
91 put(SETTINGS_HEADER_TABLE_SIZE, Long.valueOf(value));
92 return this;
93 }
94
95
96
97
98 public Boolean pushEnabled() {
99 Long value = get(SETTINGS_ENABLE_PUSH);
100 if (value == null) {
101 return null;
102 }
103 return TRUE.equals(value);
104 }
105
106
107
108
109 public Http2Settings pushEnabled(boolean enabled) {
110 put(SETTINGS_ENABLE_PUSH, enabled ? TRUE : FALSE);
111 return this;
112 }
113
114
115
116
117 public Long maxConcurrentStreams() {
118 return get(SETTINGS_MAX_CONCURRENT_STREAMS);
119 }
120
121
122
123
124
125
126 public Http2Settings maxConcurrentStreams(long value) {
127 put(SETTINGS_MAX_CONCURRENT_STREAMS, Long.valueOf(value));
128 return this;
129 }
130
131
132
133
134 public Integer initialWindowSize() {
135 return getIntValue(SETTINGS_INITIAL_WINDOW_SIZE);
136 }
137
138
139
140
141
142
143 public Http2Settings initialWindowSize(int value) {
144 put(SETTINGS_INITIAL_WINDOW_SIZE, Long.valueOf(value));
145 return this;
146 }
147
148
149
150
151 public Integer maxFrameSize() {
152 return getIntValue(SETTINGS_MAX_FRAME_SIZE);
153 }
154
155
156
157
158
159
160 public Http2Settings maxFrameSize(int value) {
161 put(SETTINGS_MAX_FRAME_SIZE, Long.valueOf(value));
162 return this;
163 }
164
165
166
167
168 public Long maxHeaderListSize() {
169 return get(SETTINGS_MAX_HEADER_LIST_SIZE);
170 }
171
172
173
174
175
176
177 public Http2Settings maxHeaderListSize(long value) {
178 put(SETTINGS_MAX_HEADER_LIST_SIZE, Long.valueOf(value));
179 return this;
180 }
181
182
183
184
185 public Http2Settings copyFrom(Http2Settings settings) {
186 clear();
187 putAll(settings);
188 return this;
189 }
190
191
192
193
194
195
196 public Integer getIntValue(char key) {
197 Long value = get(key);
198 if (value == null) {
199 return null;
200 }
201 return value.intValue();
202 }
203
204 private static void verifyStandardSetting(int key, Long value) {
205 requireNonNull(value, "value");
206 switch (key) {
207 case SETTINGS_HEADER_TABLE_SIZE:
208 if (value < MIN_HEADER_TABLE_SIZE || value > MAX_HEADER_TABLE_SIZE) {
209 throw new IllegalArgumentException("Setting HEADER_TABLE_SIZE is invalid: " + value);
210 }
211 break;
212 case SETTINGS_ENABLE_PUSH:
213 if (value != 0L && value != 1L) {
214 throw new IllegalArgumentException("Setting ENABLE_PUSH is invalid: " + value);
215 }
216 break;
217 case SETTINGS_MAX_CONCURRENT_STREAMS:
218 if (value < MIN_CONCURRENT_STREAMS || value > MAX_CONCURRENT_STREAMS) {
219 throw new IllegalArgumentException(
220 "Setting MAX_CONCURRENT_STREAMS is invalid: " + value);
221 }
222 break;
223 case SETTINGS_INITIAL_WINDOW_SIZE:
224 if (value < MIN_INITIAL_WINDOW_SIZE || value > MAX_INITIAL_WINDOW_SIZE) {
225 throw new IllegalArgumentException("Setting INITIAL_WINDOW_SIZE is invalid: "
226 + value);
227 }
228 break;
229 case SETTINGS_MAX_FRAME_SIZE:
230 if (!isMaxFrameSizeValid(value.intValue())) {
231 throw new IllegalArgumentException("Setting MAX_FRAME_SIZE is invalid: " + value);
232 }
233 break;
234 case SETTINGS_MAX_HEADER_LIST_SIZE:
235 if (value < MIN_HEADER_LIST_SIZE || value > MAX_HEADER_LIST_SIZE) {
236 throw new IllegalArgumentException("Setting MAX_HEADER_LIST_SIZE is invalid: " + value);
237 }
238 break;
239 default:
240
241 break;
242 }
243 }
244
245 @Override
246 protected String keyToString(char key) {
247 switch (key) {
248 case SETTINGS_HEADER_TABLE_SIZE:
249 return "HEADER_TABLE_SIZE";
250 case SETTINGS_ENABLE_PUSH:
251 return "ENABLE_PUSH";
252 case SETTINGS_MAX_CONCURRENT_STREAMS:
253 return "MAX_CONCURRENT_STREAMS";
254 case SETTINGS_INITIAL_WINDOW_SIZE:
255 return "INITIAL_WINDOW_SIZE";
256 case SETTINGS_MAX_FRAME_SIZE:
257 return "MAX_FRAME_SIZE";
258 case SETTINGS_MAX_HEADER_LIST_SIZE:
259 return "MAX_HEADER_LIST_SIZE";
260 default:
261
262 return super.keyToString(key);
263 }
264 }
265
266 public static Http2Settings defaultSettings() {
267 return new Http2Settings().maxHeaderListSize(DEFAULT_HEADER_LIST_SIZE);
268 }
269 }