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