OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; | 7 const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; |
8 | 8 |
9 class _WebSocketMessageType { | 9 class _WebSocketMessageType { |
10 static const int NONE = 0; | 10 static const int NONE = 0; |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 /** | 35 /** |
36 * The web socket protocol transformer handles the protocol byte stream | 36 * The web socket protocol transformer handles the protocol byte stream |
37 * which is supplied through the [:handleData:]. As the protocol is processed, | 37 * which is supplied through the [:handleData:]. As the protocol is processed, |
38 * it'll output frame data as either a List<int> or String. | 38 * it'll output frame data as either a List<int> or String. |
39 * | 39 * |
40 * Important infomation about usage: Be sure you use cancelOnError, so the | 40 * Important infomation about usage: Be sure you use cancelOnError, so the |
41 * socket will be closed when the processer encounter an error. Not using it | 41 * socket will be closed when the processer encounter an error. Not using it |
42 * will lead to undefined behaviour. | 42 * will lead to undefined behaviour. |
43 */ | 43 */ |
44 class _WebSocketProtocolTransformer extends StreamEventTransformer { | 44 // TODO(ajohnsen): make this transformer reusable? |
| 45 class _WebSocketProtocolTransformer implements StreamTransformer, EventSink { |
45 static const int START = 0; | 46 static const int START = 0; |
46 static const int LEN_FIRST = 1; | 47 static const int LEN_FIRST = 1; |
47 static const int LEN_REST = 2; | 48 static const int LEN_REST = 2; |
48 static const int MASK = 3; | 49 static const int MASK = 3; |
49 static const int PAYLOAD = 4; | 50 static const int PAYLOAD = 4; |
50 static const int CLOSED = 5; | 51 static const int CLOSED = 5; |
51 static const int FAILURE = 6; | 52 static const int FAILURE = 6; |
52 | 53 |
53 bool _serverSide; | 54 bool _serverSide; |
| 55 EventSink _eventSink; |
54 | 56 |
55 _WebSocketProtocolTransformer([bool this._serverSide = false]) { | 57 _WebSocketProtocolTransformer([bool this._serverSide = false]) { |
56 _prepareForNextFrame(); | 58 _prepareForNextFrame(); |
57 _currentMessageType = _WebSocketMessageType.NONE; | 59 _currentMessageType = _WebSocketMessageType.NONE; |
58 } | 60 } |
59 | 61 |
| 62 Stream bind(Stream stream) { |
| 63 return new Stream.eventTransformed( |
| 64 stream, |
| 65 (EventSink eventSink) { |
| 66 if (_eventSink != null) { |
| 67 throw new StateError("WebSocket transformer already used."); |
| 68 } |
| 69 _eventSink = eventSink; |
| 70 return this; |
| 71 }); |
| 72 } |
| 73 |
| 74 void addError(Object error, [StackTrace stackTrace]) { |
| 75 _eventSink.addError(error, stackTrace); |
| 76 } |
| 77 |
| 78 void close() => _eventSink.close(); |
| 79 |
60 /** | 80 /** |
61 * Process data received from the underlying communication channel. | 81 * Process data received from the underlying communication channel. |
62 */ | 82 */ |
63 void handleData(Uint8List buffer, EventSink sink) { | 83 void add(Uint8List buffer) { |
64 int count = buffer.length; | 84 int count = buffer.length; |
65 int index = 0; | 85 int index = 0; |
66 int lastIndex = count; | 86 int lastIndex = count; |
67 try { | 87 try { |
68 if (_state == CLOSED) { | 88 if (_state == CLOSED) { |
69 throw new WebSocketException("Data on closed connection"); | 89 throw new WebSocketException("Data on closed connection"); |
70 } | 90 } |
71 if (_state == FAILURE) { | 91 if (_state == FAILURE) { |
72 throw new WebSocketException("Data on failed connection"); | 92 throw new WebSocketException("Data on failed connection"); |
73 } | 93 } |
(...skipping 17 matching lines...) Expand all Loading... |
91 case _WebSocketOpcode.TEXT: | 111 case _WebSocketOpcode.TEXT: |
92 if (_currentMessageType != _WebSocketMessageType.NONE) { | 112 if (_currentMessageType != _WebSocketMessageType.NONE) { |
93 throw new WebSocketException("Protocol error"); | 113 throw new WebSocketException("Protocol error"); |
94 } | 114 } |
95 _currentMessageType = _WebSocketMessageType.TEXT; | 115 _currentMessageType = _WebSocketMessageType.TEXT; |
96 _controller = new StreamController(sync: true); | 116 _controller = new StreamController(sync: true); |
97 _controller.stream | 117 _controller.stream |
98 .transform(UTF8.decoder) | 118 .transform(UTF8.decoder) |
99 .fold(new StringBuffer(), (buffer, str) => buffer..write(str)) | 119 .fold(new StringBuffer(), (buffer, str) => buffer..write(str)) |
100 .then((buffer) { | 120 .then((buffer) { |
101 sink.add(buffer.toString()); | 121 _eventSink.add(buffer.toString()); |
102 }, onError: sink.addError); | 122 }, onError: _eventSink.addError); |
103 break; | 123 break; |
104 | 124 |
105 case _WebSocketOpcode.BINARY: | 125 case _WebSocketOpcode.BINARY: |
106 if (_currentMessageType != _WebSocketMessageType.NONE) { | 126 if (_currentMessageType != _WebSocketMessageType.NONE) { |
107 throw new WebSocketException("Protocol error"); | 127 throw new WebSocketException("Protocol error"); |
108 } | 128 } |
109 _currentMessageType = _WebSocketMessageType.BINARY; | 129 _currentMessageType = _WebSocketMessageType.BINARY; |
110 _controller = new StreamController(sync: true); | 130 _controller = new StreamController(sync: true); |
111 _controller.stream | 131 _controller.stream |
112 .fold(new BytesBuilder(), (buffer, data) => buffer..add(data)) | 132 .fold(new BytesBuilder(), (buffer, data) => buffer..add(data)) |
113 .then((buffer) { | 133 .then((buffer) { |
114 sink.add(buffer.takeBytes()); | 134 _eventSink.add(buffer.takeBytes()); |
115 }, onError: sink.addError); | 135 }, onError: _eventSink.addError); |
116 break; | 136 break; |
117 | 137 |
118 case _WebSocketOpcode.CLOSE: | 138 case _WebSocketOpcode.CLOSE: |
119 case _WebSocketOpcode.PING: | 139 case _WebSocketOpcode.PING: |
120 case _WebSocketOpcode.PONG: | 140 case _WebSocketOpcode.PONG: |
121 // Control frames cannot be fragmented. | 141 // Control frames cannot be fragmented. |
122 if (!_fin) throw new WebSocketException("Protocol error"); | 142 if (!_fin) throw new WebSocketException("Protocol error"); |
123 break; | 143 break; |
124 | 144 |
125 default: | 145 default: |
126 throw new WebSocketException("Protocol error"); | 146 throw new WebSocketException("Protocol error"); |
127 } | 147 } |
128 _state = LEN_FIRST; | 148 _state = LEN_FIRST; |
129 break; | 149 break; |
130 | 150 |
131 case LEN_FIRST: | 151 case LEN_FIRST: |
132 _masked = (byte & 0x80) != 0; | 152 _masked = (byte & 0x80) != 0; |
133 _len = byte & 0x7F; | 153 _len = byte & 0x7F; |
134 if (_isControlFrame() && _len > 125) { | 154 if (_isControlFrame() && _len > 125) { |
135 throw new WebSocketException("Protocol error"); | 155 throw new WebSocketException("Protocol error"); |
136 } | 156 } |
137 if (_len < 126) { | 157 if (_len < 126) { |
138 _lengthDone(sink); | 158 _lengthDone(); |
139 } else if (_len == 126) { | 159 } else if (_len == 126) { |
140 _len = 0; | 160 _len = 0; |
141 _remainingLenBytes = 2; | 161 _remainingLenBytes = 2; |
142 _state = LEN_REST; | 162 _state = LEN_REST; |
143 } else if (_len == 127) { | 163 } else if (_len == 127) { |
144 _len = 0; | 164 _len = 0; |
145 _remainingLenBytes = 8; | 165 _remainingLenBytes = 8; |
146 _state = LEN_REST; | 166 _state = LEN_REST; |
147 } | 167 } |
148 break; | 168 break; |
149 | 169 |
150 case LEN_REST: | 170 case LEN_REST: |
151 _len = _len << 8 | byte; | 171 _len = _len << 8 | byte; |
152 _remainingLenBytes--; | 172 _remainingLenBytes--; |
153 if (_remainingLenBytes == 0) { | 173 if (_remainingLenBytes == 0) { |
154 _lengthDone(sink); | 174 _lengthDone(); |
155 } | 175 } |
156 break; | 176 break; |
157 | 177 |
158 case MASK: | 178 case MASK: |
159 _maskingKey = _maskingKey << 8 | byte; | 179 _maskingKey = _maskingKey << 8 | byte; |
160 _remainingMaskingKeyBytes--; | 180 _remainingMaskingKeyBytes--; |
161 if (_remainingMaskingKeyBytes == 0) { | 181 if (_remainingMaskingKeyBytes == 0) { |
162 _maskDone(sink); | 182 _maskDone(); |
163 } | 183 } |
164 break; | 184 break; |
165 | 185 |
166 case PAYLOAD: | 186 case PAYLOAD: |
167 // The payload is not handled one byte at a time but in blocks. | 187 // The payload is not handled one byte at a time but in blocks. |
168 int payload; | 188 int payload; |
169 if (lastIndex - index <= _remainingPayloadBytes) { | 189 if (lastIndex - index <= _remainingPayloadBytes) { |
170 payload = lastIndex - index; | 190 payload = lastIndex - index; |
171 } else { | 191 } else { |
172 payload = _remainingPayloadBytes; | 192 payload = _remainingPayloadBytes; |
(...skipping 15 matching lines...) Expand all Loading... |
188 // Allocate a buffer for collecting the control frame | 208 // Allocate a buffer for collecting the control frame |
189 // payload if any. | 209 // payload if any. |
190 if (_controlPayload == null) { | 210 if (_controlPayload == null) { |
191 _controlPayload = new List<int>(); | 211 _controlPayload = new List<int>(); |
192 } | 212 } |
193 _controlPayload.addAll(buffer.sublist(index, index + payload)); | 213 _controlPayload.addAll(buffer.sublist(index, index + payload)); |
194 index += payload; | 214 index += payload; |
195 } | 215 } |
196 | 216 |
197 if (_remainingPayloadBytes == 0) { | 217 if (_remainingPayloadBytes == 0) { |
198 _controlFrameEnd(sink); | 218 _controlFrameEnd(); |
199 } | 219 } |
200 } else { | 220 } else { |
201 if (_currentMessageType != _WebSocketMessageType.TEXT && | 221 if (_currentMessageType != _WebSocketMessageType.TEXT && |
202 _currentMessageType != _WebSocketMessageType.BINARY) { | 222 _currentMessageType != _WebSocketMessageType.BINARY) { |
203 throw new WebSocketException("Protocol error"); | 223 throw new WebSocketException("Protocol error"); |
204 } | 224 } |
205 _controller.add( | 225 _controller.add( |
206 new Uint8List.view(buffer.buffer, index, payload)); | 226 new Uint8List.view(buffer.buffer, index, payload)); |
207 index += payload; | 227 index += payload; |
208 if (_remainingPayloadBytes == 0) { | 228 if (_remainingPayloadBytes == 0) { |
209 _messageFrameEnd(sink); | 229 _messageFrameEnd(); |
210 } | 230 } |
211 } | 231 } |
212 | 232 |
213 // Hack - as we always do index++ below. | 233 // Hack - as we always do index++ below. |
214 index--; | 234 index--; |
215 break; | 235 break; |
216 } | 236 } |
217 | 237 |
218 // Move to the next byte. | 238 // Move to the next byte. |
219 index++; | 239 index++; |
220 } | 240 } |
221 } catch (e) { | 241 } catch (e, stackTrace) { |
222 _state = FAILURE; | 242 _state = FAILURE; |
223 sink.addError(e); | 243 _eventSink.addError(e, stackTrace); |
224 } | 244 } |
225 } | 245 } |
226 | 246 |
227 void _lengthDone(EventSink sink) { | 247 void _lengthDone() { |
228 if (_masked) { | 248 if (_masked) { |
229 if (!_serverSide) { | 249 if (!_serverSide) { |
230 throw new WebSocketException("Received masked frame from server"); | 250 throw new WebSocketException("Received masked frame from server"); |
231 } | 251 } |
232 _state = MASK; | 252 _state = MASK; |
233 _remainingMaskingKeyBytes = 4; | 253 _remainingMaskingKeyBytes = 4; |
234 } else { | 254 } else { |
235 if (_serverSide) { | 255 if (_serverSide) { |
236 throw new WebSocketException("Received unmasked frame from client"); | 256 throw new WebSocketException("Received unmasked frame from client"); |
237 } | 257 } |
238 _remainingPayloadBytes = _len; | 258 _remainingPayloadBytes = _len; |
239 _startPayload(sink); | 259 _startPayload(); |
240 } | 260 } |
241 } | 261 } |
242 | 262 |
243 void _maskDone(EventSink sink) { | 263 void _maskDone() { |
244 _remainingPayloadBytes = _len; | 264 _remainingPayloadBytes = _len; |
245 _startPayload(sink); | 265 _startPayload(); |
246 } | 266 } |
247 | 267 |
248 void _startPayload(EventSink sink) { | 268 void _startPayload() { |
249 // If there is no actual payload perform perform callbacks without | 269 // If there is no actual payload perform perform callbacks without |
250 // going through the PAYLOAD state. | 270 // going through the PAYLOAD state. |
251 if (_remainingPayloadBytes == 0) { | 271 if (_remainingPayloadBytes == 0) { |
252 if (_isControlFrame()) { | 272 if (_isControlFrame()) { |
253 switch (_opcode) { | 273 switch (_opcode) { |
254 case _WebSocketOpcode.CLOSE: | 274 case _WebSocketOpcode.CLOSE: |
255 _state = CLOSED; | 275 _state = CLOSED; |
256 sink.close(); | 276 _eventSink.close(); |
257 break; | 277 break; |
258 case _WebSocketOpcode.PING: | 278 case _WebSocketOpcode.PING: |
259 sink.add(new _WebSocketPing()); | 279 _eventSink.add(new _WebSocketPing()); |
260 break; | 280 break; |
261 case _WebSocketOpcode.PONG: | 281 case _WebSocketOpcode.PONG: |
262 sink.add(new _WebSocketPong()); | 282 _eventSink.add(new _WebSocketPong()); |
263 break; | 283 break; |
264 } | 284 } |
265 _prepareForNextFrame(); | 285 _prepareForNextFrame(); |
266 } else { | 286 } else { |
267 _messageFrameEnd(sink); | 287 _messageFrameEnd(); |
268 } | 288 } |
269 } else { | 289 } else { |
270 _state = PAYLOAD; | 290 _state = PAYLOAD; |
271 } | 291 } |
272 } | 292 } |
273 | 293 |
274 void _messageFrameEnd(EventSink sink) { | 294 void _messageFrameEnd() { |
275 if (_fin) { | 295 if (_fin) { |
276 switch (_currentMessageType) { | 296 switch (_currentMessageType) { |
277 case _WebSocketMessageType.TEXT: | 297 case _WebSocketMessageType.TEXT: |
278 _controller.close(); | 298 _controller.close(); |
279 break; | 299 break; |
280 case _WebSocketMessageType.BINARY: | 300 case _WebSocketMessageType.BINARY: |
281 _controller.close(); | 301 _controller.close(); |
282 break; | 302 break; |
283 } | 303 } |
284 _controller = null; | 304 _controller = null; |
285 _currentMessageType = _WebSocketMessageType.NONE; | 305 _currentMessageType = _WebSocketMessageType.NONE; |
286 } | 306 } |
287 _prepareForNextFrame(); | 307 _prepareForNextFrame(); |
288 } | 308 } |
289 | 309 |
290 void _controlFrameEnd(EventSink sink) { | 310 void _controlFrameEnd() { |
291 switch (_opcode) { | 311 switch (_opcode) { |
292 case _WebSocketOpcode.CLOSE: | 312 case _WebSocketOpcode.CLOSE: |
293 closeCode = WebSocketStatus.NO_STATUS_RECEIVED; | 313 closeCode = WebSocketStatus.NO_STATUS_RECEIVED; |
294 if (_controlPayload.length > 0) { | 314 if (_controlPayload.length > 0) { |
295 if (_controlPayload.length == 1) { | 315 if (_controlPayload.length == 1) { |
296 throw new WebSocketException("Protocol error"); | 316 throw new WebSocketException("Protocol error"); |
297 } | 317 } |
298 closeCode = _controlPayload[0] << 8 | _controlPayload[1]; | 318 closeCode = _controlPayload[0] << 8 | _controlPayload[1]; |
299 if (closeCode == WebSocketStatus.NO_STATUS_RECEIVED) { | 319 if (closeCode == WebSocketStatus.NO_STATUS_RECEIVED) { |
300 throw new WebSocketException("Protocol error"); | 320 throw new WebSocketException("Protocol error"); |
301 } | 321 } |
302 if (_controlPayload.length > 2) { | 322 if (_controlPayload.length > 2) { |
303 closeReason = UTF8.decode(_controlPayload.sublist(2)); | 323 closeReason = UTF8.decode(_controlPayload.sublist(2)); |
304 } | 324 } |
305 } | 325 } |
306 _state = CLOSED; | 326 _state = CLOSED; |
307 sink.close(); | 327 _eventSink.close(); |
308 break; | 328 break; |
309 | 329 |
310 case _WebSocketOpcode.PING: | 330 case _WebSocketOpcode.PING: |
311 sink.add(new _WebSocketPing(_controlPayload)); | 331 _eventSink.add(new _WebSocketPing(_controlPayload)); |
312 break; | 332 break; |
313 | 333 |
314 case _WebSocketOpcode.PONG: | 334 case _WebSocketOpcode.PONG: |
315 sink.add(new _WebSocketPong(_controlPayload)); | 335 _eventSink.add(new _WebSocketPong(_controlPayload)); |
316 break; | 336 break; |
317 } | 337 } |
318 _prepareForNextFrame(); | 338 _prepareForNextFrame(); |
319 } | 339 } |
320 | 340 |
321 bool _isControlFrame() { | 341 bool _isControlFrame() { |
322 return _opcode == _WebSocketOpcode.CLOSE || | 342 return _opcode == _WebSocketOpcode.CLOSE || |
323 _opcode == _WebSocketOpcode.PING || | 343 _opcode == _WebSocketOpcode.PING || |
324 _opcode == _WebSocketOpcode.PONG; | 344 _opcode == _WebSocketOpcode.PONG; |
325 } | 345 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 } | 453 } |
434 String key = request.headers.value("Sec-WebSocket-Key"); | 454 String key = request.headers.value("Sec-WebSocket-Key"); |
435 if (key == null) { | 455 if (key == null) { |
436 return false; | 456 return false; |
437 } | 457 } |
438 return true; | 458 return true; |
439 } | 459 } |
440 } | 460 } |
441 | 461 |
442 | 462 |
443 class _WebSocketOutgoingTransformer extends StreamEventTransformer { | 463 // TODO(ajohnsen): Make this transformer reusable. |
| 464 class _WebSocketOutgoingTransformer implements StreamTransformer, EventSink { |
444 final _WebSocketImpl webSocket; | 465 final _WebSocketImpl webSocket; |
| 466 EventSink _eventSink; |
445 | 467 |
446 _WebSocketOutgoingTransformer(_WebSocketImpl this.webSocket); | 468 _WebSocketOutgoingTransformer(_WebSocketImpl this.webSocket); |
447 | 469 |
448 void handleData(message, EventSink<List<int>> sink) { | 470 Stream bind(Stream stream) { |
| 471 return new Stream.eventTransformed( |
| 472 stream, |
| 473 (EventSink eventSink) { |
| 474 if (_eventSink != null) { |
| 475 throw new StateError("WebSocket transformer already used"); |
| 476 } |
| 477 _eventSink = eventSink; |
| 478 return this; |
| 479 }); |
| 480 } |
| 481 |
| 482 void add(message) { |
449 if (message is _WebSocketPong) { | 483 if (message is _WebSocketPong) { |
450 addFrame(_WebSocketOpcode.PONG, message.payload, sink); | 484 addFrame(_WebSocketOpcode.PONG, message.payload); |
451 return; | 485 return; |
452 } | 486 } |
453 if (message is _WebSocketPing) { | 487 if (message is _WebSocketPing) { |
454 addFrame(_WebSocketOpcode.PING, message.payload, sink); | 488 addFrame(_WebSocketOpcode.PING, message.payload); |
455 return; | 489 return; |
456 } | 490 } |
457 List<int> data; | 491 List<int> data; |
458 int opcode; | 492 int opcode; |
459 if (message != null) { | 493 if (message != null) { |
460 if (message is String) { | 494 if (message is String) { |
461 opcode = _WebSocketOpcode.TEXT; | 495 opcode = _WebSocketOpcode.TEXT; |
462 data = UTF8.encode(message); | 496 data = UTF8.encode(message); |
463 } else { | 497 } else { |
464 if (message is !List<int>) { | 498 if (message is !List<int>) { |
465 throw new ArgumentError(message); | 499 throw new ArgumentError(message); |
466 } | 500 } |
467 opcode = _WebSocketOpcode.BINARY; | 501 opcode = _WebSocketOpcode.BINARY; |
468 data = message; | 502 data = message; |
469 } | 503 } |
470 } else { | 504 } else { |
471 opcode = _WebSocketOpcode.TEXT; | 505 opcode = _WebSocketOpcode.TEXT; |
472 } | 506 } |
473 addFrame(opcode, data, sink); | 507 addFrame(opcode, data); |
474 } | 508 } |
475 | 509 |
476 void handleDone(EventSink<List<int>> sink) { | 510 void addError(Object error, [StackTrace stackTrace]) { |
| 511 _eventSink.addError(error, stackTrace); |
| 512 } |
| 513 |
| 514 void close() { |
477 int code = webSocket._outCloseCode; | 515 int code = webSocket._outCloseCode; |
478 String reason = webSocket._outCloseReason; | 516 String reason = webSocket._outCloseReason; |
479 List<int> data; | 517 List<int> data; |
480 if (code != null) { | 518 if (code != null) { |
481 data = new List<int>(); | 519 data = new List<int>(); |
482 data.add((code >> 8) & 0xFF); | 520 data.add((code >> 8) & 0xFF); |
483 data.add(code & 0xFF); | 521 data.add(code & 0xFF); |
484 if (reason != null) { | 522 if (reason != null) { |
485 data.addAll(UTF8.encode(reason)); | 523 data.addAll(UTF8.encode(reason)); |
486 } | 524 } |
487 } | 525 } |
488 addFrame(_WebSocketOpcode.CLOSE, data, sink); | 526 addFrame(_WebSocketOpcode.CLOSE, data); |
489 sink.close(); | 527 _eventSink.close(); |
490 } | 528 } |
491 | 529 |
492 void addFrame(int opcode, List<int> data, EventSink<List<int>> sink) { | 530 void addFrame(int opcode, List<int> data) { |
493 createFrame(opcode, data, webSocket._serverSide).forEach(sink.add); | 531 createFrame(opcode, data, webSocket._serverSide).forEach(_eventSink.add); |
494 } | 532 } |
495 | 533 |
496 static Iterable createFrame(int opcode, List<int> data, bool serverSide) { | 534 static Iterable createFrame(int opcode, List<int> data, bool serverSide) { |
497 bool mask = !serverSide; // Masking not implemented for server. | 535 bool mask = !serverSide; // Masking not implemented for server. |
498 int dataLength = data == null ? 0 : data.length; | 536 int dataLength = data == null ? 0 : data.length; |
499 // Determine the header size. | 537 // Determine the header size. |
500 int headerSize = (mask) ? 6 : 2; | 538 int headerSize = (mask) ? 6 : 2; |
501 if (dataLength > 65535) { | 539 if (dataLength > 65535) { |
502 headerSize += 8; | 540 headerSize += 8; |
503 } else if (dataLength > 125) { | 541 } else if (dataLength > 125) { |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 (code < WebSocketStatus.NORMAL_CLOSURE || | 928 (code < WebSocketStatus.NORMAL_CLOSURE || |
891 code == WebSocketStatus.RESERVED_1004 || | 929 code == WebSocketStatus.RESERVED_1004 || |
892 code == WebSocketStatus.NO_STATUS_RECEIVED || | 930 code == WebSocketStatus.NO_STATUS_RECEIVED || |
893 code == WebSocketStatus.ABNORMAL_CLOSURE || | 931 code == WebSocketStatus.ABNORMAL_CLOSURE || |
894 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && | 932 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && |
895 code < WebSocketStatus.RESERVED_1015) || | 933 code < WebSocketStatus.RESERVED_1015) || |
896 (code >= WebSocketStatus.RESERVED_1015 && | 934 (code >= WebSocketStatus.RESERVED_1015 && |
897 code < 3000)); | 935 code < 3000)); |
898 } | 936 } |
899 } | 937 } |
OLD | NEW |