| 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 const String _clientNoContextTakeover = "client_no_context_takeover"; | 8 const String _clientNoContextTakeover = "client_no_context_takeover"; |
| 9 const String _serverNoContextTakeover = "server_no_context_takeover"; | 9 const String _serverNoContextTakeover = "server_no_context_takeover"; |
| 10 const String _clientMaxWindowBits = "client_max_window_bits"; | 10 const String _clientMaxWindowBits = "client_max_window_bits"; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 int byte = buffer[index]; | 126 int byte = buffer[index]; |
| 127 if (_state <= LEN_REST) { | 127 if (_state <= LEN_REST) { |
| 128 if (_state == START) { | 128 if (_state == START) { |
| 129 _fin = (byte & FIN) != 0; | 129 _fin = (byte & FIN) != 0; |
| 130 | 130 |
| 131 if((byte & (RSV2 | RSV3)) != 0) { | 131 if((byte & (RSV2 | RSV3)) != 0) { |
| 132 // The RSV2, RSV3 bits must both be zero. | 132 // The RSV2, RSV3 bits must both be zero. |
| 133 throw new WebSocketException("Protocol error"); | 133 throw new WebSocketException("Protocol error"); |
| 134 } | 134 } |
| 135 | 135 |
| 136 if ((byte & RSV1) != 0) { | 136 _opcode = (byte & OPCODE); |
| 137 _compressed = true; | 137 |
| 138 } else { | 138 if (_opcode != _WebSocketOpcode.CONTINUATION) { |
| 139 _compressed = false; | 139 if ((byte & RSV1) != 0) { |
| 140 _compressed = true; |
| 141 } else { |
| 142 _compressed = false; |
| 143 } |
| 140 } | 144 } |
| 141 _opcode = (byte & OPCODE); | |
| 142 | 145 |
| 143 if (_opcode <= _WebSocketOpcode.BINARY) { | 146 if (_opcode <= _WebSocketOpcode.BINARY) { |
| 144 if (_opcode == _WebSocketOpcode.CONTINUATION) { | 147 if (_opcode == _WebSocketOpcode.CONTINUATION) { |
| 145 if (_currentMessageType == _WebSocketMessageType.NONE) { | 148 if (_currentMessageType == _WebSocketMessageType.NONE) { |
| 146 throw new WebSocketException("Protocol error"); | 149 throw new WebSocketException("Protocol error"); |
| 147 } | 150 } |
| 148 } else { | 151 } else { |
| 149 assert(_opcode == _WebSocketOpcode.TEXT || | 152 assert(_opcode == _WebSocketOpcode.TEXT || |
| 150 _opcode == _WebSocketOpcode.BINARY); | 153 _opcode == _WebSocketOpcode.BINARY); |
| 151 if (_currentMessageType != _WebSocketMessageType.NONE) { | 154 if (_currentMessageType != _WebSocketMessageType.NONE) { |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 } | 563 } |
| 561 | 564 |
| 562 Uint8List processIncomingMessage(List<int> msg) { | 565 Uint8List processIncomingMessage(List<int> msg) { |
| 563 _ensureDecoder(); | 566 _ensureDecoder(); |
| 564 | 567 |
| 565 var data = []; | 568 var data = []; |
| 566 data.addAll(msg); | 569 data.addAll(msg); |
| 567 data.addAll(const [0x00, 0x00, 0xff, 0xff]); | 570 data.addAll(const [0x00, 0x00, 0xff, 0xff]); |
| 568 | 571 |
| 569 decoder.process(data, 0, data.length); | 572 decoder.process(data, 0, data.length); |
| 570 var reuse = | |
| 571 !(serverSide ? clientNoContextTakeover : serverNoContextTakeover); | |
| 572 var result = []; | 573 var result = []; |
| 573 var out; | 574 var out; |
| 574 | 575 |
| 575 while ((out = decoder.processed(flush: reuse)) != null) { | 576 while ((out = decoder.processed()) != null) { |
| 576 result.addAll(out); | 577 result.addAll(out); |
| 577 } | 578 } |
| 578 | 579 |
| 579 decoder.processed(flush: reuse); | |
| 580 | |
| 581 if (!reuse) { | |
| 582 decoder.end(); | |
| 583 decoder = null; | |
| 584 } | |
| 585 return new Uint8List.fromList(result); | 580 return new Uint8List.fromList(result); |
| 586 } | 581 } |
| 587 | 582 |
| 588 List<int> processOutgoingMessage(List<int> msg) { | 583 List<int> processOutgoingMessage(List<int> msg) { |
| 589 _ensureEncoder(); | 584 _ensureEncoder(); |
| 590 var reuse = | |
| 591 !(serverSide ? serverNoContextTakeover : clientNoContextTakeover); | |
| 592 var result = []; | 585 var result = []; |
| 593 Uint8List buffer; | 586 Uint8List buffer; |
| 594 var out; | 587 var out; |
| 595 | 588 |
| 596 if (msg is! Uint8List) { | 589 if (msg is! Uint8List) { |
| 597 for (var i = 0; i < msg.length; i++) { | 590 for (var i = 0; i < msg.length; i++) { |
| 598 if (msg[i] < 0 || 255 < msg[i]) { | 591 if (msg[i] < 0 || 255 < msg[i]) { |
| 599 throw new ArgumentError("List element is not a byte value " | 592 throw new ArgumentError("List element is not a byte value " |
| 600 "(value ${msg[i]} at index $i)"); | 593 "(value ${msg[i]} at index $i)"); |
| 601 } | 594 } |
| 602 } | 595 } |
| 603 buffer = new Uint8List.fromList(msg); | 596 buffer = new Uint8List.fromList(msg); |
| 604 } else { | 597 } else { |
| 605 buffer = msg; | 598 buffer = msg; |
| 606 } | 599 } |
| 607 | 600 |
| 608 encoder.process(buffer, 0, buffer.length); | 601 encoder.process(buffer, 0, buffer.length); |
| 609 | 602 |
| 610 while ((out = encoder.processed(flush: reuse)) != null) { | 603 while ((out = encoder.processed()) != null) { |
| 611 result.addAll(out); | 604 result.addAll(out); |
| 612 } | 605 } |
| 613 | 606 |
| 614 if (serverSide ? serverNoContextTakeover : clientNoContextTakeover) { | |
| 615 encoder.end(); | |
| 616 encoder = null; | |
| 617 } | |
| 618 | |
| 619 if (result.length > 4) { | 607 if (result.length > 4) { |
| 620 result = result.sublist(0, result.length - 4); | 608 result = result.sublist(0, result.length - 4); |
| 621 } | 609 } |
| 622 | 610 |
| 623 return result; | 611 return result; |
| 624 } | 612 } |
| 625 } | 613 } |
| 626 | 614 |
| 627 // TODO(ajohnsen): Make this transformer reusable. | 615 // TODO(ajohnsen): Make this transformer reusable. |
| 628 class _WebSocketOutgoingTransformer implements StreamTransformer, EventSink { | 616 class _WebSocketOutgoingTransformer implements StreamTransformer, EventSink { |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 return code != null && | 1229 return code != null && |
| 1242 (code < WebSocketStatus.NORMAL_CLOSURE || | 1230 (code < WebSocketStatus.NORMAL_CLOSURE || |
| 1243 code == WebSocketStatus.RESERVED_1004 || | 1231 code == WebSocketStatus.RESERVED_1004 || |
| 1244 code == WebSocketStatus.NO_STATUS_RECEIVED || | 1232 code == WebSocketStatus.NO_STATUS_RECEIVED || |
| 1245 code == WebSocketStatus.ABNORMAL_CLOSURE || | 1233 code == WebSocketStatus.ABNORMAL_CLOSURE || |
| 1246 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && | 1234 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && |
| 1247 code < WebSocketStatus.RESERVED_1015) || | 1235 code < WebSocketStatus.RESERVED_1015) || |
| 1248 (code >= WebSocketStatus.RESERVED_1015 && code < 3000)); | 1236 (code >= WebSocketStatus.RESERVED_1015 && code < 3000)); |
| 1249 } | 1237 } |
| 1250 } | 1238 } |
| OLD | NEW |