1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.codec.http.websocketx;
17
18 import io.netty5.handler.codec.http.EmptyHttpHeaders;
19 import io.netty5.handler.codec.http.HttpHeaders;
20
21 import java.net.URI;
22 import java.util.Objects;
23
24 import static io.netty5.handler.codec.http.websocketx.WebSocketServerProtocolConfig.DEFAULT_HANDSHAKE_TIMEOUT_MILLIS;
25 import static io.netty5.util.internal.ObjectUtil.checkPositive;
26
27
28
29
30 public final class WebSocketClientProtocolConfig {
31
32 static final boolean DEFAULT_PERFORM_MASKING = true;
33 static final boolean DEFAULT_ALLOW_MASK_MISMATCH = false;
34 static final boolean DEFAULT_HANDLE_CLOSE_FRAMES = true;
35 static final boolean DEFAULT_DROP_PONG_FRAMES = true;
36
37 private final URI webSocketUri;
38 private final String subprotocol;
39 private final WebSocketVersion version;
40 private final boolean allowExtensions;
41 private final HttpHeaders customHeaders;
42 private final int maxFramePayloadLength;
43 private final boolean performMasking;
44 private final boolean allowMaskMismatch;
45 private final boolean handleCloseFrames;
46 private final WebSocketCloseStatus sendCloseFrame;
47 private final boolean dropPongFrames;
48 private final long handshakeTimeoutMillis;
49 private final long forceCloseTimeoutMillis;
50 private final boolean absoluteUpgradeUrl;
51
52 private WebSocketClientProtocolConfig(
53 URI webSocketUri,
54 String subprotocol,
55 WebSocketVersion version,
56 boolean allowExtensions,
57 HttpHeaders customHeaders,
58 int maxFramePayloadLength,
59 boolean performMasking,
60 boolean allowMaskMismatch,
61 boolean handleCloseFrames,
62 WebSocketCloseStatus sendCloseFrame,
63 boolean dropPongFrames,
64 long handshakeTimeoutMillis,
65 long forceCloseTimeoutMillis,
66 boolean absoluteUpgradeUrl
67 ) {
68 this.webSocketUri = webSocketUri;
69 this.subprotocol = subprotocol;
70 this.version = version;
71 this.allowExtensions = allowExtensions;
72 this.customHeaders = customHeaders;
73 this.maxFramePayloadLength = maxFramePayloadLength;
74 this.performMasking = performMasking;
75 this.allowMaskMismatch = allowMaskMismatch;
76 this.forceCloseTimeoutMillis = forceCloseTimeoutMillis;
77 this.handleCloseFrames = handleCloseFrames;
78 this.sendCloseFrame = sendCloseFrame;
79 this.dropPongFrames = dropPongFrames;
80 this.handshakeTimeoutMillis = checkPositive(handshakeTimeoutMillis, "handshakeTimeoutMillis");
81 this.absoluteUpgradeUrl = absoluteUpgradeUrl;
82 }
83
84 public URI webSocketUri() {
85 return webSocketUri;
86 }
87
88 public String subprotocol() {
89 return subprotocol;
90 }
91
92 public WebSocketVersion version() {
93 return version;
94 }
95
96 public boolean allowExtensions() {
97 return allowExtensions;
98 }
99
100 public HttpHeaders customHeaders() {
101 return customHeaders;
102 }
103
104 public int maxFramePayloadLength() {
105 return maxFramePayloadLength;
106 }
107
108 public boolean performMasking() {
109 return performMasking;
110 }
111
112 public boolean allowMaskMismatch() {
113 return allowMaskMismatch;
114 }
115
116 public boolean handleCloseFrames() {
117 return handleCloseFrames;
118 }
119
120 public WebSocketCloseStatus sendCloseFrame() {
121 return sendCloseFrame;
122 }
123
124 public boolean dropPongFrames() {
125 return dropPongFrames;
126 }
127
128 public long handshakeTimeoutMillis() {
129 return handshakeTimeoutMillis;
130 }
131
132 public long forceCloseTimeoutMillis() {
133 return forceCloseTimeoutMillis;
134 }
135
136 public boolean absoluteUpgradeUrl() {
137 return absoluteUpgradeUrl;
138 }
139
140 @Override
141 public String toString() {
142 return "WebSocketClientProtocolConfig" +
143 " {webSocketUri=" + webSocketUri +
144 ", subprotocol=" + subprotocol +
145 ", version=" + version +
146 ", allowExtensions=" + allowExtensions +
147 ", customHeaders=" + customHeaders +
148 ", maxFramePayloadLength=" + maxFramePayloadLength +
149 ", performMasking=" + performMasking +
150 ", allowMaskMismatch=" + allowMaskMismatch +
151 ", handleCloseFrames=" + handleCloseFrames +
152 ", sendCloseFrame=" + sendCloseFrame +
153 ", dropPongFrames=" + dropPongFrames +
154 ", handshakeTimeoutMillis=" + handshakeTimeoutMillis +
155 ", forceCloseTimeoutMillis=" + forceCloseTimeoutMillis +
156 ", absoluteUpgradeUrl=" + absoluteUpgradeUrl +
157 "}";
158 }
159
160 public Builder toBuilder() {
161 return new Builder(this);
162 }
163
164 public static Builder newBuilder() {
165 return new Builder(
166 URI.create("https://localhost/"),
167 null,
168 WebSocketVersion.V13,
169 false,
170 EmptyHttpHeaders.INSTANCE,
171 65536,
172 DEFAULT_PERFORM_MASKING,
173 DEFAULT_ALLOW_MASK_MISMATCH,
174 DEFAULT_HANDLE_CLOSE_FRAMES,
175 WebSocketCloseStatus.NORMAL_CLOSURE,
176 DEFAULT_DROP_PONG_FRAMES,
177 DEFAULT_HANDSHAKE_TIMEOUT_MILLIS,
178 -1,
179 false);
180 }
181
182 public static final class Builder {
183 private URI webSocketUri;
184 private String subprotocol;
185 private WebSocketVersion version;
186 private boolean allowExtensions;
187 private HttpHeaders customHeaders;
188 private int maxFramePayloadLength;
189 private boolean performMasking;
190 private boolean allowMaskMismatch;
191 private boolean handleCloseFrames;
192 private WebSocketCloseStatus sendCloseFrame;
193 private boolean dropPongFrames;
194 private long handshakeTimeoutMillis;
195 private long forceCloseTimeoutMillis;
196 private boolean absoluteUpgradeUrl;
197
198 private Builder(WebSocketClientProtocolConfig clientConfig) {
199 this(Objects.requireNonNull(clientConfig, "clientConfig").webSocketUri(),
200 clientConfig.subprotocol(),
201 clientConfig.version(),
202 clientConfig.allowExtensions(),
203 clientConfig.customHeaders(),
204 clientConfig.maxFramePayloadLength(),
205 clientConfig.performMasking(),
206 clientConfig.allowMaskMismatch(),
207 clientConfig.handleCloseFrames(),
208 clientConfig.sendCloseFrame(),
209 clientConfig.dropPongFrames(),
210 clientConfig.handshakeTimeoutMillis(),
211 clientConfig.forceCloseTimeoutMillis(),
212 clientConfig.absoluteUpgradeUrl());
213 }
214
215 private Builder(URI webSocketUri,
216 String subprotocol,
217 WebSocketVersion version,
218 boolean allowExtensions,
219 HttpHeaders customHeaders,
220 int maxFramePayloadLength,
221 boolean performMasking,
222 boolean allowMaskMismatch,
223 boolean handleCloseFrames,
224 WebSocketCloseStatus sendCloseFrame,
225 boolean dropPongFrames,
226 long handshakeTimeoutMillis,
227 long forceCloseTimeoutMillis,
228 boolean absoluteUpgradeUrl) {
229 this.webSocketUri = webSocketUri;
230 this.subprotocol = subprotocol;
231 this.version = version;
232 this.allowExtensions = allowExtensions;
233 this.customHeaders = customHeaders;
234 this.maxFramePayloadLength = maxFramePayloadLength;
235 this.performMasking = performMasking;
236 this.allowMaskMismatch = allowMaskMismatch;
237 this.handleCloseFrames = handleCloseFrames;
238 this.sendCloseFrame = sendCloseFrame;
239 this.dropPongFrames = dropPongFrames;
240 this.handshakeTimeoutMillis = handshakeTimeoutMillis;
241 this.forceCloseTimeoutMillis = forceCloseTimeoutMillis;
242 this.absoluteUpgradeUrl = absoluteUpgradeUrl;
243 }
244
245
246
247
248
249 public Builder webSocketUri(String webSocketUri) {
250 return webSocketUri(URI.create(webSocketUri));
251 }
252
253
254
255
256
257 public Builder webSocketUri(URI webSocketUri) {
258 this.webSocketUri = webSocketUri;
259 return this;
260 }
261
262
263
264
265 public Builder subprotocol(String subprotocol) {
266 this.subprotocol = subprotocol;
267 return this;
268 }
269
270
271
272
273 public Builder version(WebSocketVersion version) {
274 this.version = version;
275 return this;
276 }
277
278
279
280
281 public Builder allowExtensions(boolean allowExtensions) {
282 this.allowExtensions = allowExtensions;
283 return this;
284 }
285
286
287
288
289 public Builder customHeaders(HttpHeaders customHeaders) {
290 this.customHeaders = customHeaders;
291 return this;
292 }
293
294
295
296
297 public Builder maxFramePayloadLength(int maxFramePayloadLength) {
298 this.maxFramePayloadLength = maxFramePayloadLength;
299 return this;
300 }
301
302
303
304
305
306
307 public Builder performMasking(boolean performMasking) {
308 this.performMasking = performMasking;
309 return this;
310 }
311
312
313
314
315 public Builder allowMaskMismatch(boolean allowMaskMismatch) {
316 this.allowMaskMismatch = allowMaskMismatch;
317 return this;
318 }
319
320
321
322
323 public Builder handleCloseFrames(boolean handleCloseFrames) {
324 this.handleCloseFrames = handleCloseFrames;
325 return this;
326 }
327
328
329
330
331 public Builder sendCloseFrame(WebSocketCloseStatus sendCloseFrame) {
332 this.sendCloseFrame = sendCloseFrame;
333 return this;
334 }
335
336
337
338
339 public Builder dropPongFrames(boolean dropPongFrames) {
340 this.dropPongFrames = dropPongFrames;
341 return this;
342 }
343
344
345
346
347
348 public Builder handshakeTimeoutMillis(long handshakeTimeoutMillis) {
349 this.handshakeTimeoutMillis = handshakeTimeoutMillis;
350 return this;
351 }
352
353
354
355
356 public Builder forceCloseTimeoutMillis(long forceCloseTimeoutMillis) {
357 this.forceCloseTimeoutMillis = forceCloseTimeoutMillis;
358 return this;
359 }
360
361
362
363
364 public Builder absoluteUpgradeUrl(boolean absoluteUpgradeUrl) {
365 this.absoluteUpgradeUrl = absoluteUpgradeUrl;
366 return this;
367 }
368
369
370
371
372 public WebSocketClientProtocolConfig build() {
373 return new WebSocketClientProtocolConfig(
374 webSocketUri,
375 subprotocol,
376 version,
377 allowExtensions,
378 customHeaders,
379 maxFramePayloadLength,
380 performMasking,
381 allowMaskMismatch,
382 handleCloseFrames,
383 sendCloseFrame,
384 dropPongFrames,
385 handshakeTimeoutMillis,
386 forceCloseTimeoutMillis,
387 absoluteUpgradeUrl
388 );
389 }
390 }
391 }