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 |