| 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 19 matching lines...) Expand all Loading... |
| 30 static const int PING = 9; | 30 static const int PING = 9; |
| 31 static const int PONG = 10; | 31 static const int PONG = 10; |
| 32 static const int RESERVED_B = 11; | 32 static const int RESERVED_B = 11; |
| 33 static const int RESERVED_C = 12; | 33 static const int RESERVED_C = 12; |
| 34 static const int RESERVED_D = 13; | 34 static const int RESERVED_D = 13; |
| 35 static const int RESERVED_E = 14; | 35 static const int RESERVED_E = 14; |
| 36 static const int RESERVED_F = 15; | 36 static const int RESERVED_F = 15; |
| 37 } | 37 } |
| 38 | 38 |
| 39 /** | 39 /** |
| 40 * Stores the header and integer value derived from negotiation of |
| 41 * client_max_window_bits and server_max_window_bits. headerValue will be |
| 42 * set in the Websocket response headers. |
| 43 */ |
| 44 class _CompressionMaxWindowBits { |
| 45 String headerValue; |
| 46 int maxWindowBits; |
| 47 _CompressionMaxWindowBits([this.headerValue, this.maxWindowBits]); |
| 48 String toString() => headerValue; |
| 49 } |
| 50 |
| 51 /** |
| 40 * The web socket protocol transformer handles the protocol byte stream | 52 * The web socket protocol transformer handles the protocol byte stream |
| 41 * which is supplied through the [:handleData:]. As the protocol is processed, | 53 * which is supplied through the [:handleData:]. As the protocol is processed, |
| 42 * it'll output frame data as either a List<int> or String. | 54 * it'll output frame data as either a List<int> or String. |
| 43 * | 55 * |
| 44 * Important information about usage: Be sure you use cancelOnError, so the | 56 * Important information about usage: Be sure you use cancelOnError, so the |
| 45 * socket will be closed when the processor encounter an error. Not using it | 57 * socket will be closed when the processor encounter an error. Not using it |
| 46 * will lead to undefined behaviour. | 58 * will lead to undefined behaviour. |
| 47 */ | 59 */ |
| 48 // TODO(ajohnsen): make this transformer reusable? | 60 // TODO(ajohnsen): make this transformer reusable? |
| 49 class _WebSocketProtocolTransformer implements StreamTransformer, EventSink { | 61 class _WebSocketProtocolTransformer implements StreamTransformer, EventSink { |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 }).then(upgrade); | 463 }).then(upgrade); |
| 452 } else { | 464 } else { |
| 453 return upgrade(null); | 465 return upgrade(null); |
| 454 } | 466 } |
| 455 } | 467 } |
| 456 | 468 |
| 457 static _WebSocketPerMessageDeflate _negotiateCompression(HttpRequest request, | 469 static _WebSocketPerMessageDeflate _negotiateCompression(HttpRequest request, |
| 458 HttpResponse response, CompressionOptions compression) { | 470 HttpResponse response, CompressionOptions compression) { |
| 459 var extensionHeader = request.headers.value("Sec-WebSocket-Extensions"); | 471 var extensionHeader = request.headers.value("Sec-WebSocket-Extensions"); |
| 460 | 472 |
| 461 if (extensionHeader == null) { | 473 extensionHeader ??= ""; |
| 462 extensionHeader = ""; | |
| 463 } | |
| 464 | 474 |
| 465 var hv = HeaderValue.parse(extensionHeader, valueSeparator: ','); | 475 var hv = HeaderValue.parse(extensionHeader, valueSeparator: ','); |
| 466 if (compression.enabled && hv.value == _WebSocketImpl.PER_MESSAGE_DEFLATE) { | 476 if (compression.enabled && hv.value == _WebSocketImpl.PER_MESSAGE_DEFLATE) { |
| 467 var info = compression._createHeader(hv); | 477 var info = compression._createHeader(hv); |
| 468 | 478 |
| 469 response.headers.add("Sec-WebSocket-Extensions", info[0]); | 479 response.headers.add("Sec-WebSocket-Extensions", info.headerValue); |
| 470 var serverNoContextTakeover = | 480 var serverNoContextTakeover = |
| 471 hv.parameters.containsKey(_serverNoContextTakeover); | 481 hv.parameters.containsKey(_serverNoContextTakeover); |
| 472 var clientNoContextTakeover = | 482 var clientNoContextTakeover = |
| 473 hv.parameters.containsKey(_clientNoContextTakeover); | 483 hv.parameters.containsKey(_clientNoContextTakeover); |
| 474 var deflate = new _WebSocketPerMessageDeflate( | 484 var deflate = new _WebSocketPerMessageDeflate( |
| 475 serverNoContextTakeover: serverNoContextTakeover, | 485 serverNoContextTakeover: serverNoContextTakeover, |
| 476 clientNoContextTakeover: clientNoContextTakeover, | 486 clientNoContextTakeover: clientNoContextTakeover, |
| 477 serverMaxWindowBits: info[1], | 487 serverMaxWindowBits: info.maxWindowBits, |
| 478 clientMaxWindowBits: info[1], | 488 clientMaxWindowBits: info.maxWindowBits, |
| 479 serverSide: true); | 489 serverSide: true); |
| 480 | 490 |
| 481 return deflate; | 491 return deflate; |
| 482 } | 492 } |
| 483 | 493 |
| 484 return null; | 494 return null; |
| 485 } | 495 } |
| 486 | 496 |
| 487 static bool _isUpgradeRequest(HttpRequest request) { | 497 static bool _isUpgradeRequest(HttpRequest request) { |
| 488 if (request.method != "GET") { | 498 if (request.method != "GET") { |
| (...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1231 return code != null && | 1241 return code != null && |
| 1232 (code < WebSocketStatus.NORMAL_CLOSURE || | 1242 (code < WebSocketStatus.NORMAL_CLOSURE || |
| 1233 code == WebSocketStatus.RESERVED_1004 || | 1243 code == WebSocketStatus.RESERVED_1004 || |
| 1234 code == WebSocketStatus.NO_STATUS_RECEIVED || | 1244 code == WebSocketStatus.NO_STATUS_RECEIVED || |
| 1235 code == WebSocketStatus.ABNORMAL_CLOSURE || | 1245 code == WebSocketStatus.ABNORMAL_CLOSURE || |
| 1236 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && | 1246 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && |
| 1237 code < WebSocketStatus.RESERVED_1015) || | 1247 code < WebSocketStatus.RESERVED_1015) || |
| 1238 (code >= WebSocketStatus.RESERVED_1015 && code < 3000)); | 1248 (code >= WebSocketStatus.RESERVED_1015 && code < 3000)); |
| 1239 } | 1249 } |
| 1240 } | 1250 } |
| OLD | NEW |