Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(670)

Side by Side Diff: sdk/lib/io/websocket_impl.dart

Issue 12400002: Add individual HTTP request to web socket upgrade support (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 class _WebSocketMessageType { 9 class _WebSocketMessageType {
10 static const int NONE = 0; 10 static const int NONE = 0;
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 Function onClosed; 356 Function onClosed;
357 } 357 }
358 358
359 359
360 class _WebSocketTransformerImpl implements WebSocketTransformer { 360 class _WebSocketTransformerImpl implements WebSocketTransformer {
361 final StreamController<WebSocket> _controller = 361 final StreamController<WebSocket> _controller =
362 new StreamController<WebSocket>(); 362 new StreamController<WebSocket>();
363 363
364 Stream<WebSocket> bind(Stream<HttpRequest> stream) { 364 Stream<WebSocket> bind(Stream<HttpRequest> stream) {
365 stream.listen((request) { 365 stream.listen((request) {
366 var response = request.response; 366 _upgrade(request)
367 if (!_isWebSocketUpgrade(request)) { 367 .then((WebSocket webSocket) => _controller.add(webSocket))
368 _controller.signalError( 368 .catchError((error) => _controller.signalError(error));
369 new AsyncError(
370 new WebSocketException("Invalid WebSocket upgrade request")));
371 request.listen((_) {}, onDone: () {
372 response.statusCode = HttpStatus.BAD_REQUEST;
373 response.contentLength = 0;
374 response.close();
375 });
376 return;
377 }
378 // Send the upgrade response.
379 response.statusCode = HttpStatus.SWITCHING_PROTOCOLS;
380 response.headers.add(HttpHeaders.CONNECTION, "Upgrade");
381 response.headers.add(HttpHeaders.UPGRADE, "websocket");
382 String key = request.headers.value("Sec-WebSocket-Key");
383 SHA1 sha1 = new SHA1();
384 sha1.add("$key$_webSocketGUID".codeUnits);
385 String accept = _Base64._encode(sha1.close());
386 response.headers.add("Sec-WebSocket-Accept", accept);
387 response.headers.contentLength = 0;
388 response.detachSocket()
389 .then((socket) {
390 _controller.add(new _WebSocketImpl._fromSocket(socket));
391 }, onError: (error) {
392 _controller.signalError(error);
393 });
394 }); 369 });
395 370
396 return _controller.stream; 371 return _controller.stream;
397 } 372 }
398 373
399 bool _isWebSocketUpgrade(HttpRequest request) { 374 static Future<WebSocket> _upgrade(HttpRequest request) {
375 var response = request.response;
376 if (!_isUpgradeRequest(request)) {
377 // Send error response and drain the request.
378 request.listen((_) {}, onDone: () {
379 response.statusCode = HttpStatus.BAD_REQUEST;
380 response.contentLength = 0;
381 response.close();
382 });
383 return new Future.immediateError(
384 new WebSocketException("Invalid WebSocket upgrade request"));
385 }
386
387 // Send the upgrade response.
388 response.statusCode = HttpStatus.SWITCHING_PROTOCOLS;
389 response.headers.add(HttpHeaders.CONNECTION, "Upgrade");
390 response.headers.add(HttpHeaders.UPGRADE, "websocket");
391 String key = request.headers.value("Sec-WebSocket-Key");
392 SHA1 sha1 = new SHA1();
393 sha1.add("$key$_webSocketGUID".codeUnits);
394 String accept = _Base64._encode(sha1.close());
395 response.headers.add("Sec-WebSocket-Accept", accept);
396 response.headers.contentLength = 0;
397 return response.detachSocket()
398 .then((socket) => new _WebSocketImpl._fromSocket(socket));
399 }
400
401 static bool _isUpgradeRequest(HttpRequest request) {
400 if (request.method != "GET") { 402 if (request.method != "GET") {
401 return false; 403 return false;
402 } 404 }
403 if (request.headers[HttpHeaders.CONNECTION] == null) { 405 if (request.headers[HttpHeaders.CONNECTION] == null) {
404 return false; 406 return false;
405 } 407 }
406 bool isUpgrade = false; 408 bool isUpgrade = false;
407 request.headers[HttpHeaders.CONNECTION].forEach((String value) { 409 request.headers[HttpHeaders.CONNECTION].forEach((String value) {
408 if (value.toLowerCase() == "upgrade") isUpgrade = true; 410 if (value.toLowerCase() == "upgrade") isUpgrade = true;
409 }); 411 });
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 for (int i = 0; i < lengthBytes; i++) { 685 for (int i = 0; i < lengthBytes; i++) {
684 header[index++] = dataLength >> (((lengthBytes - 1) - i) * 8) & 0xFF; 686 header[index++] = dataLength >> (((lengthBytes - 1) - i) * 8) & 0xFF;
685 } 687 }
686 assert(index == headerSize); 688 assert(index == headerSize);
687 _socket.add(header); 689 _socket.add(header);
688 if (data != null) { 690 if (data != null) {
689 _socket.add(data); 691 _socket.add(data);
690 } 692 }
691 } 693 }
692 } 694 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698