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 java.util.Objects;
19
20 import static io.netty5.util.internal.ObjectUtil.checkPositive;
21
22
23
24
25 public final class WebSocketServerProtocolConfig {
26
27 static final long DEFAULT_HANDSHAKE_TIMEOUT_MILLIS = 10000L;
28
29 private final String websocketPath;
30 private final String subprotocols;
31 private final boolean checkStartsWith;
32 private final long handshakeTimeoutMillis;
33 private final long forceCloseTimeoutMillis;
34 private final boolean handleCloseFrames;
35 private final WebSocketCloseStatus sendCloseFrame;
36 private final boolean dropPongFrames;
37 private final WebSocketDecoderConfig decoderConfig;
38
39 private WebSocketServerProtocolConfig(
40 String websocketPath,
41 String subprotocols,
42 boolean checkStartsWith,
43 long handshakeTimeoutMillis,
44 long forceCloseTimeoutMillis,
45 boolean handleCloseFrames,
46 WebSocketCloseStatus sendCloseFrame,
47 boolean dropPongFrames,
48 WebSocketDecoderConfig decoderConfig
49 ) {
50 this.websocketPath = websocketPath;
51 this.subprotocols = subprotocols;
52 this.checkStartsWith = checkStartsWith;
53 this.handshakeTimeoutMillis = checkPositive(handshakeTimeoutMillis, "handshakeTimeoutMillis");
54 this.forceCloseTimeoutMillis = forceCloseTimeoutMillis;
55 this.handleCloseFrames = handleCloseFrames;
56 this.sendCloseFrame = sendCloseFrame;
57 this.dropPongFrames = dropPongFrames;
58 this.decoderConfig = decoderConfig == null ? WebSocketDecoderConfig.DEFAULT : decoderConfig;
59 }
60
61 public String websocketPath() {
62 return websocketPath;
63 }
64
65 public String subprotocols() {
66 return subprotocols;
67 }
68
69 public boolean checkStartsWith() {
70 return checkStartsWith;
71 }
72
73 public long handshakeTimeoutMillis() {
74 return handshakeTimeoutMillis;
75 }
76
77 public long forceCloseTimeoutMillis() {
78 return forceCloseTimeoutMillis;
79 }
80
81 public boolean handleCloseFrames() {
82 return handleCloseFrames;
83 }
84
85 public WebSocketCloseStatus sendCloseFrame() {
86 return sendCloseFrame;
87 }
88
89 public boolean dropPongFrames() {
90 return dropPongFrames;
91 }
92
93 public WebSocketDecoderConfig decoderConfig() {
94 return decoderConfig;
95 }
96
97 @Override
98 public String toString() {
99 return "WebSocketServerProtocolConfig" +
100 " {websocketPath=" + websocketPath +
101 ", subprotocols=" + subprotocols +
102 ", checkStartsWith=" + checkStartsWith +
103 ", handshakeTimeoutMillis=" + handshakeTimeoutMillis +
104 ", forceCloseTimeoutMillis=" + forceCloseTimeoutMillis +
105 ", handleCloseFrames=" + handleCloseFrames +
106 ", sendCloseFrame=" + sendCloseFrame +
107 ", dropPongFrames=" + dropPongFrames +
108 ", decoderConfig=" + decoderConfig +
109 "}";
110 }
111
112 public Builder toBuilder() {
113 return new Builder(this);
114 }
115
116 public static Builder newBuilder() {
117 return new Builder("/", null, false, DEFAULT_HANDSHAKE_TIMEOUT_MILLIS, 0L,
118 true, WebSocketCloseStatus.NORMAL_CLOSURE, true, WebSocketDecoderConfig.DEFAULT);
119 }
120
121 public static final class Builder {
122 private String websocketPath;
123 private String subprotocols;
124 private boolean checkStartsWith;
125 private long handshakeTimeoutMillis;
126 private long forceCloseTimeoutMillis;
127 private boolean handleCloseFrames;
128 private WebSocketCloseStatus sendCloseFrame;
129 private boolean dropPongFrames;
130 private WebSocketDecoderConfig decoderConfig;
131 private WebSocketDecoderConfig.Builder decoderConfigBuilder;
132
133 private Builder(WebSocketServerProtocolConfig serverConfig) {
134 this(Objects.requireNonNull(serverConfig, "serverConfig").websocketPath(),
135 serverConfig.subprotocols(),
136 serverConfig.checkStartsWith(),
137 serverConfig.handshakeTimeoutMillis(),
138 serverConfig.forceCloseTimeoutMillis(),
139 serverConfig.handleCloseFrames(),
140 serverConfig.sendCloseFrame(),
141 serverConfig.dropPongFrames(),
142 serverConfig.decoderConfig()
143 );
144 }
145
146 private Builder(String websocketPath,
147 String subprotocols,
148 boolean checkStartsWith,
149 long handshakeTimeoutMillis,
150 long forceCloseTimeoutMillis,
151 boolean handleCloseFrames,
152 WebSocketCloseStatus sendCloseFrame,
153 boolean dropPongFrames,
154 WebSocketDecoderConfig decoderConfig) {
155 this.websocketPath = websocketPath;
156 this.subprotocols = subprotocols;
157 this.checkStartsWith = checkStartsWith;
158 this.handshakeTimeoutMillis = handshakeTimeoutMillis;
159 this.forceCloseTimeoutMillis = forceCloseTimeoutMillis;
160 this.handleCloseFrames = handleCloseFrames;
161 this.sendCloseFrame = sendCloseFrame;
162 this.dropPongFrames = dropPongFrames;
163 this.decoderConfig = decoderConfig;
164 }
165
166
167
168
169 public Builder websocketPath(String websocketPath) {
170 this.websocketPath = websocketPath;
171 return this;
172 }
173
174
175
176
177 public Builder subprotocols(String subprotocols) {
178 this.subprotocols = subprotocols;
179 return this;
180 }
181
182
183
184
185
186 public Builder checkStartsWith(boolean checkStartsWith) {
187 this.checkStartsWith = checkStartsWith;
188 return this;
189 }
190
191
192
193
194
195 public Builder handshakeTimeoutMillis(long handshakeTimeoutMillis) {
196 this.handshakeTimeoutMillis = handshakeTimeoutMillis;
197 return this;
198 }
199
200
201
202
203 public Builder forceCloseTimeoutMillis(long forceCloseTimeoutMillis) {
204 this.forceCloseTimeoutMillis = forceCloseTimeoutMillis;
205 return this;
206 }
207
208
209
210
211 public Builder handleCloseFrames(boolean handleCloseFrames) {
212 this.handleCloseFrames = handleCloseFrames;
213 return this;
214 }
215
216
217
218
219 public Builder sendCloseFrame(WebSocketCloseStatus sendCloseFrame) {
220 this.sendCloseFrame = sendCloseFrame;
221 return this;
222 }
223
224
225
226
227 public Builder dropPongFrames(boolean dropPongFrames) {
228 this.dropPongFrames = dropPongFrames;
229 return this;
230 }
231
232
233
234
235 public Builder decoderConfig(WebSocketDecoderConfig decoderConfig) {
236 this.decoderConfig = decoderConfig == null ? WebSocketDecoderConfig.DEFAULT : decoderConfig;
237 this.decoderConfigBuilder = null;
238 return this;
239 }
240
241 private WebSocketDecoderConfig.Builder decoderConfigBuilder() {
242 if (decoderConfigBuilder == null) {
243 decoderConfigBuilder = decoderConfig.toBuilder();
244 }
245 return decoderConfigBuilder;
246 }
247
248 public Builder maxFramePayloadLength(int maxFramePayloadLength) {
249 decoderConfigBuilder().maxFramePayloadLength(maxFramePayloadLength);
250 return this;
251 }
252
253 public Builder expectMaskedFrames(boolean expectMaskedFrames) {
254 decoderConfigBuilder().expectMaskedFrames(expectMaskedFrames);
255 return this;
256 }
257
258 public Builder allowMaskMismatch(boolean allowMaskMismatch) {
259 decoderConfigBuilder().allowMaskMismatch(allowMaskMismatch);
260 return this;
261 }
262
263 public Builder allowExtensions(boolean allowExtensions) {
264 decoderConfigBuilder().allowExtensions(allowExtensions);
265 return this;
266 }
267
268 public Builder closeOnProtocolViolation(boolean closeOnProtocolViolation) {
269 decoderConfigBuilder().closeOnProtocolViolation(closeOnProtocolViolation);
270 return this;
271 }
272
273 public Builder withUTF8Validator(boolean withUTF8Validator) {
274 decoderConfigBuilder().withUTF8Validator(withUTF8Validator);
275 return this;
276 }
277
278
279
280
281 public WebSocketServerProtocolConfig build() {
282 return new WebSocketServerProtocolConfig(
283 websocketPath,
284 subprotocols,
285 checkStartsWith,
286 handshakeTimeoutMillis,
287 forceCloseTimeoutMillis,
288 handleCloseFrames,
289 sendCloseFrame,
290 dropPongFrames,
291 decoderConfigBuilder == null ? decoderConfig : decoderConfigBuilder.build()
292 );
293 }
294 }
295 }