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