1 //
2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.websocket.api;
20
21 /**
22 * Settings for WebSocket operations.
23 */
24 public class WebSocketPolicy
25 {
26 private static final int KB = 1024;
27
28 public static WebSocketPolicy newClientPolicy()
29 {
30 return new WebSocketPolicy(WebSocketBehavior.CLIENT);
31 }
32
33 public static WebSocketPolicy newServerPolicy()
34 {
35 return new WebSocketPolicy(WebSocketBehavior.SERVER);
36 }
37
38 /**
39 * The maximum size of a text message during parsing/generating.
40 * <p>
41 * Text messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
42 * <p>
43 * Default: 65536 (64 K)
44 */
45 private int maxTextMessageSize = 64 * KB;
46
47 /**
48 * The maximum size of a text message buffer.
49 * <p>
50 * Used ONLY for stream based message writing.
51 * <p>
52 * Default: 32768 (32 K)
53 */
54 private int maxTextMessageBufferSize = 32 * KB;
55
56 /**
57 * The maximum size of a binary message during parsing/generating.
58 * <p>
59 * Binary messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
60 * <p>
61 * Default: 65536 (64 K)
62 */
63 private int maxBinaryMessageSize = 64 * KB;
64
65 /**
66 * The maximum size of a binary message buffer
67 * <p>
68 * Used ONLY for for stream based message writing
69 * <p>
70 * Default: 32768 (32 K)
71 */
72 private int maxBinaryMessageBufferSize = 32 * KB;
73
74 /**
75 * The timeout in ms (milliseconds) for async write operations.
76 * <p>
77 * Negative values indicate a disabled timeout.
78 */
79 private long asyncWriteTimeout = 60000;
80
81 /**
82 * The time in ms (milliseconds) that a websocket may be idle before closing.
83 * <p>
84 * Default: 300000 (ms)
85 */
86 private long idleTimeout = 300000;
87
88 /**
89 * The size of the input (read from network layer) buffer size.
90 * <p>
91 * Default: 4096 (4 K)
92 */
93 private int inputBufferSize = 4 * KB;
94
95 /**
96 * Behavior of the websockets
97 */
98 private final WebSocketBehavior behavior;
99
100 public WebSocketPolicy(WebSocketBehavior behavior)
101 {
102 this.behavior = behavior;
103 }
104
105 private void assertLessThan(String name, long size, String otherName, long otherSize)
106 {
107 if (size > otherSize)
108 {
109 throw new IllegalArgumentException(String.format("%s [%d] must be less than %s [%d]",name,size,otherName,otherSize));
110 }
111 }
112
113 private void assertGreaterThan(String name, long size, long minSize)
114 {
115 if (size < minSize)
116 {
117 throw new IllegalArgumentException(String.format("%s [%d] must be a greater than or equal to " + minSize,name,size));
118 }
119 }
120
121 public void assertValidBinaryMessageSize(int requestedSize)
122 {
123 if (maxBinaryMessageSize > 0)
124 {
125 // validate it
126 if (requestedSize > maxBinaryMessageSize)
127 {
128 throw new MessageTooLargeException("Binary message size [" + requestedSize + "] exceeds maximum size [" + maxBinaryMessageSize + "]");
129 }
130 }
131 }
132
133 public void assertValidTextMessageSize(int requestedSize)
134 {
135 if (maxTextMessageSize > 0)
136 {
137 // validate it
138 if (requestedSize > maxTextMessageSize)
139 {
140 throw new MessageTooLargeException("Text message size [" + requestedSize + "] exceeds maximum size [" + maxTextMessageSize + "]");
141 }
142 }
143 }
144
145 public WebSocketPolicy clonePolicy()
146 {
147 WebSocketPolicy clone = new WebSocketPolicy(this.behavior);
148 clone.idleTimeout = this.idleTimeout;
149 clone.maxTextMessageSize = this.maxTextMessageSize;
150 clone.maxTextMessageBufferSize = this.maxTextMessageBufferSize;
151 clone.maxBinaryMessageSize = this.maxBinaryMessageSize;
152 clone.maxBinaryMessageBufferSize = this.maxBinaryMessageBufferSize;
153 clone.inputBufferSize = this.inputBufferSize;
154 clone.asyncWriteTimeout = this.asyncWriteTimeout;
155 return clone;
156 }
157
158 /**
159 * The timeout in ms (milliseconds) for async write operations.
160 * <p>
161 * Negative values indicate a disabled timeout.
162 *
163 * @return the timeout for async write operations. negative values indicate disabled timeout.
164 */
165 public long getAsyncWriteTimeout()
166 {
167 return asyncWriteTimeout;
168 }
169
170 public WebSocketBehavior getBehavior()
171 {
172 return behavior;
173 }
174
175 /**
176 * The time in ms (milliseconds) that a websocket connection mad by idle before being closed automatically.
177 *
178 * @return the timeout in milliseconds for idle timeout.
179 */
180 public long getIdleTimeout()
181 {
182 return idleTimeout;
183 }
184
185 /**
186 * The size of the input (read from network layer) buffer size.
187 * <p>
188 * This is the raw read operation buffer size, before the parsing of the websocket frames.
189 *
190 * @return the raw network bytes read operation buffer size.
191 */
192 public int getInputBufferSize()
193 {
194 return inputBufferSize;
195 }
196
197 /**
198 * Get the maximum size of a binary message buffer (for streaming writing)
199 *
200 * @return the maximum size of a binary message buffer
201 */
202 public int getMaxBinaryMessageBufferSize()
203 {
204 return maxBinaryMessageBufferSize;
205 }
206
207 /**
208 * Get the maximum size of a binary message during parsing/generating.
209 * <p>
210 * Binary messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
211 *
212 * @return the maximum size of a binary message
213 */
214 public int getMaxBinaryMessageSize()
215 {
216 return maxBinaryMessageSize;
217 }
218
219 /**
220 * Get the maximum size of a text message buffer (for streaming writing)
221 *
222 * @return the maximum size of a text message buffer
223 */
224 public int getMaxTextMessageBufferSize()
225 {
226 return maxTextMessageBufferSize;
227 }
228
229 /**
230 * Get the maximum size of a text message during parsing/generating.
231 * <p>
232 * Text messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
233 *
234 * @return the maximum size of a text message.
235 */
236 public int getMaxTextMessageSize()
237 {
238 return maxTextMessageSize;
239 }
240
241 /**
242 * The timeout in ms (milliseconds) for async write operations.
243 * <p>
244 * Negative values indicate a disabled timeout.
245 *
246 * @param ms
247 * the timeout in milliseconds
248 */
249 public void setAsyncWriteTimeout(long ms)
250 {
251 assertLessThan("AsyncWriteTimeout",ms,"IdleTimeout",idleTimeout);
252 this.asyncWriteTimeout = ms;
253 }
254
255 /**
256 * The time in ms (milliseconds) that a websocket may be idle before closing.
257 *
258 * @param ms
259 * the timeout in milliseconds
260 */
261 public void setIdleTimeout(long ms)
262 {
263 assertGreaterThan("IdleTimeout",ms,0);
264 this.idleTimeout = ms;
265 }
266
267 /**
268 * The size of the input (read from network layer) buffer size.
269 *
270 * @param size
271 * the size in bytes
272 */
273 public void setInputBufferSize(int size)
274 {
275 assertGreaterThan("InputBufferSize",size,1);
276 assertLessThan("InputBufferSize",size,"MaxTextMessageBufferSize",maxTextMessageBufferSize);
277 assertLessThan("InputBufferSize",size,"MaxBinaryMessageBufferSize",maxBinaryMessageBufferSize);
278
279 this.inputBufferSize = size;
280 }
281
282 /**
283 * The maximum size of a binary message buffer.
284 * <p>
285 * Used ONLY for stream based message writing.
286 *
287 * @param size
288 * the maximum size of the binary message buffer
289 */
290 public void setMaxBinaryMessageBufferSize(int size)
291 {
292 assertGreaterThan("MaxBinaryMessageBufferSize",size,1);
293
294 this.maxBinaryMessageBufferSize = size;
295 }
296
297 /**
298 * The maximum size of a binary message during parsing/generating.
299 * <p>
300 * Binary messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
301 *
302 * @param size
303 * the maximum allowed size of a binary message.
304 */
305 public void setMaxBinaryMessageSize(int size)
306 {
307 assertGreaterThan("MaxBinaryMessageSize",size,1);
308
309 this.maxBinaryMessageSize = size;
310 }
311
312 /**
313 * The maximum size of a text message buffer.
314 * <p>
315 * Used ONLY for stream based message writing.
316 *
317 * @param size
318 * the maximum size of the text message buffer
319 */
320 public void setMaxTextMessageBufferSize(int size)
321 {
322 assertGreaterThan("MaxTextMessageBufferSize",size,1);
323
324 this.maxTextMessageBufferSize = size;
325 }
326
327 /**
328 * The maximum size of a text message during parsing/generating.
329 * <p>
330 * Text messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
331 *
332 * @param size
333 * the maximum allowed size of a text message.
334 */
335 public void setMaxTextMessageSize(int size)
336 {
337 assertGreaterThan("MaxTextMessageSize",size,1);
338
339 this.maxTextMessageSize = size;
340 }
341
342 @Override
343 public String toString()
344 {
345 StringBuilder builder = new StringBuilder();
346 builder.append("WebSocketPolicy@").append(Integer.toHexString(hashCode()));
347 builder.append("[behavior=").append(behavior);
348 builder.append(",maxTextMessageSize=").append(maxTextMessageSize);
349 builder.append(",maxTextMessageBufferSize=").append(maxTextMessageBufferSize);
350 builder.append(",maxBinaryMessageSize=").append(maxBinaryMessageSize);
351 builder.append(",maxBinaryMessageBufferSize=").append(maxBinaryMessageBufferSize);
352 builder.append(",asyncWriteTimeout=").append(asyncWriteTimeout);
353 builder.append(",idleTimeout=").append(idleTimeout);
354 builder.append(",inputBufferSize=").append(inputBufferSize);
355 builder.append("]");
356 return builder.toString();
357 }
358 }