| 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 /** | 7 /** |
| 8 * WebSocket status codes used when closing a WebSocket connection. | 8 * WebSocket status codes used when closing a WebSocket connection. |
| 9 */ | 9 */ |
| 10 abstract class WebSocketStatus { | 10 abstract class WebSocketStatus { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 final int serverMaxWindowBits; | 65 final int serverMaxWindowBits; |
| 66 | 66 |
| 67 /** | 67 /** |
| 68 * Enables or disables WebSocket compression. | 68 * Enables or disables WebSocket compression. |
| 69 */ | 69 */ |
| 70 final bool enabled; | 70 final bool enabled; |
| 71 | 71 |
| 72 const CompressionOptions( | 72 const CompressionOptions( |
| 73 {this.clientNoContextTakeover: false, | 73 {this.clientNoContextTakeover: false, |
| 74 this.serverNoContextTakeover: false, | 74 this.serverNoContextTakeover: false, |
| 75 this.clientMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS, | 75 this.clientMaxWindowBits, |
| 76 this.serverMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS, | 76 this.serverMaxWindowBits, |
| 77 this.enabled: true}); | 77 this.enabled: true}); |
| 78 | 78 |
| 79 /// Parses list of requested server headers to return server compression | 79 /// Parses list of requested server headers to return server compression |
| 80 /// response headers. Uses [serverMaxWindowBits] value if set, otherwise will | 80 /// response headers. Uses [serverMaxWindowBits] value if set, otherwise will |
| 81 /// attempt to use value from headers. Defaults to | 81 /// attempt to use value from headers. Defaults to |
| 82 /// [WebSocket.DEFAULT_WINDOW_BITS] | 82 /// [WebSocket.DEFAULT_WINDOW_BITS]. Returns a [_CompressionMaxWindowBits] |
| 83 List _createServerResponseHeader(HeaderValue requested) { | 83 /// object which contains the response headers and negotiated max window bits. |
| 84 var info = new List(2); | 84 _CompressionMaxWindowBits _createServerResponseHeader(HeaderValue requested) { |
| 85 var info = new _CompressionMaxWindowBits(); |
| 85 | 86 |
| 86 int mwb; | 87 int mwb; |
| 87 var part = requested.parameters[_serverMaxWindowBits]; | 88 String part; |
| 89 if (requested?.parameters != null) { |
| 90 part = requested.parameters[_serverMaxWindowBits]; |
| 91 } |
| 88 if (part != null) { | 92 if (part != null) { |
| 89 if (part.length >= 2 && part.startsWith('0')) { | 93 if (part.length >= 2 && part.startsWith('0')) { |
| 90 throw new ArgumentError("Illegal 0 padding on value."); | 94 throw new ArgumentError("Illegal 0 padding on value."); |
| 91 } else { | 95 } else { |
| 92 mwb = serverMaxWindowBits == null | 96 mwb = serverMaxWindowBits == null |
| 93 ? int.parse(part, | 97 ? int.parse(part, |
| 94 onError: (source) => _WebSocketImpl.DEFAULT_WINDOW_BITS) | 98 onError: (source) => _WebSocketImpl.DEFAULT_WINDOW_BITS) |
| 95 : serverMaxWindowBits; | 99 : serverMaxWindowBits; |
| 96 info[0] = "; server_max_window_bits=${mwb}"; | 100 info.headerValue = "; server_max_window_bits=${mwb}"; |
| 97 info[1] = mwb; | 101 info.maxWindowBits = mwb; |
| 98 } | 102 } |
| 99 } else { | 103 } else { |
| 100 info[1] = _WebSocketImpl.DEFAULT_WINDOW_BITS; | 104 info.headerValue = ""; |
| 105 info.maxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS; |
| 101 } | 106 } |
| 102 return info; | 107 return info; |
| 103 } | 108 } |
| 104 | 109 |
| 105 /// Returns default values for client compression request headers. | 110 /// Returns default values for client compression request headers. |
| 106 List _createClientRequestHeader(HeaderValue requested) { | 111 String _createClientRequestHeader(HeaderValue requested, int size) { |
| 107 var info = new List(2); | 112 var info = ""; |
| 108 | 113 |
| 109 info[1] = _WebSocketImpl.DEFAULT_WINDOW_BITS; | 114 // If responding to a valid request, specify size |
| 110 if (requested != null && | 115 if (requested != null) { |
| 111 requested.parameters[_clientMaxWindowBits] != null) { | 116 info = "; client_max_window_bits=$size"; |
| 112 info[0] = "; client_max_window_bits=${info[1]}"; | |
| 113 } else { | 117 } else { |
| 114 info[0] = "; client_max_window_bits"; | 118 // Client request. Specify default |
| 119 info = "; client_max_window_bits"; |
| 115 } | 120 } |
| 116 | 121 |
| 117 return info; | 122 return info; |
| 118 } | 123 } |
| 119 | 124 |
| 120 /// Create a Compression Header. If [requested] is null or contains | 125 /// Create a Compression Header. If [requested] is null or contains |
| 121 /// client request headers, returns Client compression request headers. | 126 /// client request headers, returns Client compression request headers with |
| 127 /// default settings for `client_max_window_bits` header value. |
| 122 /// If [requested] contains server response headers this method returns | 128 /// If [requested] contains server response headers this method returns |
| 123 /// a Server compression response header. | 129 /// a Server compression response header negotiating the max window bits |
| 124 List _createHeader([HeaderValue requested]) { | 130 /// for both client and server as requested server_max_window_bits value. |
| 131 /// This method returns a [_CompressionMaxWindowBits] object with the |
| 132 /// response headers and negotiated maxWindowBits value. |
| 133 _CompressionMaxWindowBits _createHeader([HeaderValue requested]) { |
| 134 var info = new _CompressionMaxWindowBits("", 0); |
| 125 if (!enabled) { | 135 if (!enabled) { |
| 126 return ["", 0]; | 136 return info; |
| 127 } | 137 } |
| 128 | 138 |
| 129 var info = new List(2); | 139 info.headerValue = _WebSocketImpl.PER_MESSAGE_DEFLATE; |
| 130 var header = _WebSocketImpl.PER_MESSAGE_DEFLATE; | |
| 131 | 140 |
| 132 if (clientNoContextTakeover && | 141 if (clientNoContextTakeover && |
| 133 (requested != null && | 142 (requested != null && |
| 134 requested.parameters.containsKey(_clientNoContextTakeover))) { | 143 requested.parameters.containsKey(_clientNoContextTakeover))) { |
| 135 header += "; client_no_context_takeover"; | 144 info.headerValue += "; client_no_context_takeover"; |
| 136 } | 145 } |
| 137 | 146 |
| 138 if (serverNoContextTakeover && | 147 if (serverNoContextTakeover && |
| 139 (requested != null && | 148 (requested != null && |
| 140 requested.parameters.containsKey(_serverNoContextTakeover))) { | 149 requested.parameters.containsKey(_serverNoContextTakeover))) { |
| 141 header += "; server_no_context_takeover"; | 150 info.headerValue += "; server_no_context_takeover"; |
| 142 } | 151 } |
| 143 | 152 |
| 144 if (requested == null || | 153 var headerList = _createServerResponseHeader(requested); |
| 145 requested.parameters.containsKey(_clientMaxWindowBits)) { | 154 info.headerValue += headerList.headerValue; |
| 146 var clientList = _createClientRequestHeader(requested); | 155 info.maxWindowBits = headerList.maxWindowBits; |
| 147 header += clientList[0]; | |
| 148 info[1] = clientList[1]; | |
| 149 } else { | |
| 150 var headerList = _createServerResponseHeader(requested); | |
| 151 header += headerList[0]; | |
| 152 info[1] = headerList[1]; | |
| 153 } | |
| 154 | 156 |
| 155 info[0] = header; | 157 info.headerValue += |
| 158 _createClientRequestHeader(requested, info.maxWindowBits); |
| 156 | 159 |
| 157 return info; | 160 return info; |
| 158 } | 161 } |
| 159 } | 162 } |
| 160 | 163 |
| 161 /** | 164 /** |
| 162 * The [WebSocketTransformer] provides the ability to upgrade a | 165 * The [WebSocketTransformer] provides the ability to upgrade a |
| 163 * [HttpRequest] to a [WebSocket] connection. It supports both | 166 * [HttpRequest] to a [WebSocket] connection. It supports both |
| 164 * upgrading a single [HttpRequest] and upgrading a stream of | 167 * upgrading a single [HttpRequest] and upgrading a stream of |
| 165 * [HttpRequest]s. | 168 * [HttpRequest]s. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 Future addStream(Stream stream); | 394 Future addStream(Stream stream); |
| 392 } | 395 } |
| 393 | 396 |
| 394 class WebSocketException implements IOException { | 397 class WebSocketException implements IOException { |
| 395 final String message; | 398 final String message; |
| 396 | 399 |
| 397 const WebSocketException([this.message = ""]); | 400 const WebSocketException([this.message = ""]); |
| 398 | 401 |
| 399 String toString() => "WebSocketException: $message"; | 402 String toString() => "WebSocketException: $message"; |
| 400 } | 403 } |
| OLD | NEW |