| 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 // Matches _WebSocketOpcode. | 9 // Matches _WebSocketOpcode. |
| 10 class _WebSocketMessageType { | 10 class _WebSocketMessageType { |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 _controller.add(data); | 858 _controller.add(data); |
| 859 } | 859 } |
| 860 }, | 860 }, |
| 861 onError: (error) { | 861 onError: (error) { |
| 862 if (_closeTimer != null) _closeTimer.cancel(); | 862 if (_closeTimer != null) _closeTimer.cancel(); |
| 863 if (error is FormatException) { | 863 if (error is FormatException) { |
| 864 _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA); | 864 _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA); |
| 865 } else { | 865 } else { |
| 866 _close(WebSocketStatus.PROTOCOL_ERROR); | 866 _close(WebSocketStatus.PROTOCOL_ERROR); |
| 867 } | 867 } |
| 868 // An error happened, set the close code set above. |
| 869 _closeCode = _outCloseCode; |
| 870 _closeReason = _outCloseReason; |
| 868 _controller.close(); | 871 _controller.close(); |
| 869 }, | 872 }, |
| 870 onDone: () { | 873 onDone: () { |
| 871 if (_closeTimer != null) _closeTimer.cancel(); | 874 if (_closeTimer != null) _closeTimer.cancel(); |
| 872 if (_readyState == WebSocket.OPEN) { | 875 if (_readyState == WebSocket.OPEN) { |
| 873 _readyState = WebSocket.CLOSING; | 876 _readyState = WebSocket.CLOSING; |
| 874 if (!_isReservedStatusCode(transformer.closeCode)) { | 877 if (!_isReservedStatusCode(transformer.closeCode)) { |
| 875 _close(transformer.closeCode); | 878 _close(transformer.closeCode); |
| 876 } else { | 879 } else { |
| 877 _close(); | 880 _close(); |
| 878 } | 881 } |
| 879 _readyState = WebSocket.CLOSED; | 882 _readyState = WebSocket.CLOSED; |
| 880 } | 883 } |
| 884 // Protocol close, use close code from transformer. |
| 881 _closeCode = transformer.closeCode; | 885 _closeCode = transformer.closeCode; |
| 882 _closeReason = transformer.closeReason; | 886 _closeReason = transformer.closeReason; |
| 883 _controller.close(); | 887 _controller.close(); |
| 884 }, | 888 }, |
| 885 cancelOnError: true); | 889 cancelOnError: true); |
| 886 _subscription.pause(); | 890 _subscription.pause(); |
| 887 _controller = new StreamController(sync: true, | 891 _controller = new StreamController(sync: true, |
| 888 onListen: _subscription.resume, | 892 onListen: _subscription.resume, |
| 889 onPause: _subscription.pause, | 893 onPause: _subscription.pause, |
| 890 onResume: _subscription.resume); | 894 onResume: _subscription.resume); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 if (_isReservedStatusCode(code)) { | 939 if (_isReservedStatusCode(code)) { |
| 936 throw new WebSocketException("Reserved status code $code"); | 940 throw new WebSocketException("Reserved status code $code"); |
| 937 } | 941 } |
| 938 if (_outCloseCode == null) { | 942 if (_outCloseCode == null) { |
| 939 _outCloseCode = code; | 943 _outCloseCode = code; |
| 940 _outCloseReason = reason; | 944 _outCloseReason = reason; |
| 941 } | 945 } |
| 942 if (_closeTimer == null && !_controller.isClosed) { | 946 if (_closeTimer == null && !_controller.isClosed) { |
| 943 // When closing the web-socket, we no longer accept data. | 947 // When closing the web-socket, we no longer accept data. |
| 944 _closeTimer = new Timer(const Duration(seconds: 5), () { | 948 _closeTimer = new Timer(const Duration(seconds: 5), () { |
| 949 // Reuse code and reason from the local close. |
| 950 _closeCode = _outCloseCode; |
| 951 _closeReason = _outCloseReason; |
| 945 _subscription.cancel(); | 952 _subscription.cancel(); |
| 946 _controller.close(); | 953 _controller.close(); |
| 947 }); | 954 }); |
| 948 } | 955 } |
| 949 return _sink.close(); | 956 return _sink.close(); |
| 950 } | 957 } |
| 951 | 958 |
| 952 void _close([int code, String reason]) { | 959 void _close([int code, String reason]) { |
| 953 if (_writeClosed) return; | 960 if (_writeClosed) return; |
| 954 if (_outCloseCode == null) { | 961 if (_outCloseCode == null) { |
| 955 _outCloseCode = code; | 962 _outCloseCode = code; |
| 956 _outCloseReason = reason; | 963 _outCloseReason = reason; |
| 957 } | 964 } |
| 958 _writeClosed = true; | 965 _writeClosed = true; |
| 959 _consumer.closeSocket(); | 966 _consumer.closeSocket(); |
| 960 } | 967 } |
| 961 | 968 |
| 962 static bool _isReservedStatusCode(int code) { | 969 static bool _isReservedStatusCode(int code) { |
| 963 return code != null && | 970 return code != null && |
| 964 (code < WebSocketStatus.NORMAL_CLOSURE || | 971 (code < WebSocketStatus.NORMAL_CLOSURE || |
| 965 code == WebSocketStatus.RESERVED_1004 || | 972 code == WebSocketStatus.RESERVED_1004 || |
| 966 code == WebSocketStatus.NO_STATUS_RECEIVED || | 973 code == WebSocketStatus.NO_STATUS_RECEIVED || |
| 967 code == WebSocketStatus.ABNORMAL_CLOSURE || | 974 code == WebSocketStatus.ABNORMAL_CLOSURE || |
| 968 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && | 975 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && |
| 969 code < WebSocketStatus.RESERVED_1015) || | 976 code < WebSocketStatus.RESERVED_1015) || |
| 970 (code >= WebSocketStatus.RESERVED_1015 && | 977 (code >= WebSocketStatus.RESERVED_1015 && |
| 971 code < 3000)); | 978 code < 3000)); |
| 972 } | 979 } |
| 973 } | 980 } |
| OLD | NEW |