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

Side by Side Diff: runtime/bin/websocket_impl.dart

Issue 10383039: Implemented W3C complient web socket client interface (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed additional review comments Created 8 years, 7 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 final String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 5 final String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
6 6
7 class _WebSocketMessageType { 7 class _WebSocketMessageType {
8 static final int NONE = 0; 8 static final int NONE = 0;
9 static final int BINARY = 1; 9 static final int BINARY = 1;
10 static final int TEXT = 2; 10 static final int TEXT = 2;
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 339
340 Function onMessageStart; 340 Function onMessageStart;
341 Function onMessageData; 341 Function onMessageData;
342 Function onMessageEnd; 342 Function onMessageEnd;
343 Function onClosed; 343 Function onClosed;
344 Function onError; 344 Function onError;
345 } 345 }
346 346
347 347
348 class _WebSocketConnectionBase { 348 class _WebSocketConnectionBase {
349 void _socketReady(DetachedSocket detached) { 349 void _socketConnected(Socket socket) {
350 assert(detached.socket != null); 350 _socket = socket;
351 _socket = detached.socket; 351 _socket.onError = (e) {
352 _reportError(e);
353 _socket.close();
354 };
355 }
356
357 void _startProcessing(List<int> unparsedData) {
352 _WebSocketProtocolProcessor processor = new _WebSocketProtocolProcessor(); 358 _WebSocketProtocolProcessor processor = new _WebSocketProtocolProcessor();
353 processor.onMessageStart = _onWebSocketMessageStart; 359 processor.onMessageStart = _onWebSocketMessageStart;
354 processor.onMessageData = _onWebSocketMessageData; 360 processor.onMessageData = _onWebSocketMessageData;
355 processor.onMessageEnd = _onWebSocketMessageEnd; 361 processor.onMessageEnd = _onWebSocketMessageEnd;
356 processor.onClosed = _onWebSocketClosed; 362 processor.onClosed = _onWebSocketClosed;
357 processor.onError = _onWebSocketError; 363 processor.onError = _onWebSocketError;
358 if (detached.unparsedData != null) { 364 if (unparsedData != null) {
359 processor.update(detached.unparsedData, 0, detached.unparsedData.length); 365 processor.update(unparsedData, 0, unparsedData.length);
360 } 366 }
361 _socket.onData = () { 367 _socket.onData = () {
362 int available = _socket.available(); 368 int available = _socket.available();
363 List<int> data = new List<int>(available); 369 List<int> data = new List<int>(available);
364 int read = _socket.readList(data, 0, available); 370 int read = _socket.readList(data, 0, available);
365 processor.update(data, 0, read); 371 processor.update(data, 0, read);
366 }; 372 };
367 _socket.onClosed = () { 373 _socket.onClosed = () {
368 processor.closed(); 374 processor.closed();
369 if (_closeSent) { 375 if (_closeSent) {
370 // Got socket close in response to close frame. Don't treat 376 // Got socket close in response to close frame. Don't treat
371 // that as an error. 377 // that as an error.
372 if (_closeTimer != null) _closeTimer.cancel(); 378 if (_closeTimer != null) _closeTimer.cancel();
373 } else { 379 } else {
374 _reportError(new WebSocketException("Unexpected close")); 380 _reportError(new WebSocketException("Unexpected close"));
375 } 381 }
376 _socket.close(); 382 _socket.close();
377 }; 383 };
378 _socket.onError = (e) {
379 _reportError(e);
380 _socket.close();
381 };
382 } 384 }
383 385
384 void set onMessage(void callback(Object message)) { 386 void set onMessage(void callback(Object message)) {
385 _onMessage = callback; 387 _onMessage = callback;
386 } 388 }
387 389
388 void set onClosed(void callback(int status, String reason)) { 390 void set onClosed(void callback(int status, String reason)) {
389 _onClosed = callback; 391 _onClosed = callback;
390 } 392 }
391 393
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 _StringDecoder _decoder; 555 _StringDecoder _decoder;
554 ListOutputStream _outputStream; 556 ListOutputStream _outputStream;
555 bool _closeReceived = false; 557 bool _closeReceived = false;
556 bool _closeSent = false; 558 bool _closeSent = false;
557 } 559 }
558 560
559 561
560 class _WebSocketConnection 562 class _WebSocketConnection
561 extends _WebSocketConnectionBase implements WebSocketConnection { 563 extends _WebSocketConnectionBase implements WebSocketConnection {
562 _WebSocketConnection(DetachedSocket detached) { 564 _WebSocketConnection(DetachedSocket detached) {
563 _socketReady(detached); 565 _socketConnected(detached.socket);
566 _startProcessing(detached.unparsedData);
564 } 567 }
565 } 568 }
566 569
567 570
568 class _WebSocketHandler implements WebSocketHandler { 571 class _WebSocketHandler implements WebSocketHandler {
569 void onRequest(HttpRequest request, HttpResponse response) { 572 void onRequest(HttpRequest request, HttpResponse response) {
570 // Check that this is a web socket upgrade. 573 // Check that this is a web socket upgrade.
571 if (!_isWebSocketUpgrade(request)) { 574 if (!_isWebSocketUpgrade(request)) {
572 response.statusCode = HttpStatus.BAD_REQUEST; 575 response.statusCode = HttpStatus.BAD_REQUEST;
573 response.outputStream.close(); 576 response.outputStream.close();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 return; 674 return;
672 } 675 }
673 676
674 if (!_isWebSocketUpgrade(response)) { 677 if (!_isWebSocketUpgrade(response)) {
675 _conn.detachSocket().socket.close(); 678 _conn.detachSocket().socket.close();
676 throw new WebSocketException("Protocol upgrade failed"); 679 throw new WebSocketException("Protocol upgrade failed");
677 return; 680 return;
678 } 681 }
679 682
680 // Connection upgrade successful. 683 // Connection upgrade successful.
681 _socketReady(_conn.detachSocket()); 684 DetachedSocket detached = _conn.detachSocket();
685 _socketConnected(detached.socket);
682 if (_onOpen != null) _onOpen(); 686 if (_onOpen != null) _onOpen();
687 _startProcessing(detached.unparsedData);
683 } 688 }
684 689
685 void _generateNonce() { 690 void _generateNonce() {
686 assert(_nonce == null); 691 assert(_nonce == null);
687 void intToBigEndianBytes(int value, List<int> bytes, int offset) { 692 void intToBigEndianBytes(int value, List<int> bytes, int offset) {
688 bytes[offset] = (value >> 24) & 0xFF; 693 bytes[offset] = (value >> 24) & 0xFF;
689 bytes[offset + 1] = (value >> 16) & 0xFF; 694 bytes[offset + 1] = (value >> 16) & 0xFF;
690 bytes[offset + 2] = (value >> 8) & 0xFF; 695 bytes[offset + 2] = (value >> 8) & 0xFF;
691 bytes[offset + 3] = value & 0xFF; 696 bytes[offset + 3] = value & 0xFF;
692 } 697 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 } 731 }
727 return true; 732 return true;
728 } 733 }
729 734
730 Function _onRequest; 735 Function _onRequest;
731 Function _onOpen; 736 Function _onOpen;
732 Function _onNoUpgrade; 737 Function _onNoUpgrade;
733 HttpClientConnection _conn; 738 HttpClientConnection _conn;
734 String _nonce; 739 String _nonce;
735 } 740 }
741
742
743 class _WebSocket implements WebSocket {
744 _WebSocket(String url, [protocols]) {
745 Uri uri = new Uri.fromString(url);
746 if (uri.scheme != "ws") {
747 throw new WebSocketException("Unsupported URL scheme ${uri.scheme}");
748 }
749 if (uri.userInfo != "") {
750 throw new WebSocketException("Unsupported user info ${uri.userInfo}");
751 }
752 int port = uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : uri.port;
753 String path;
754 if (uri.query != "") {
755 if (uri.fragment != "") {
756 path = "${uri.path}?${uri.query}#${uri.fragment}";
757 } else {
758 path = "${uri.path}?${uri.query}";
759 }
760 } else {
761 path = uri.path;
762 }
763
764 HttpClient client = new HttpClient();
765 HttpClientConnection conn = client.open("GET", uri.domain, port, path);
766 if (protocols is String) protocols = [protocols];
767 _wsconn = new WebSocketClientConnection(conn, protocols);
768 _wsconn.onOpen = () {
769 // HTTP client not needed after socket have been detached.
770 client.shutdown();
771 client = null;
772 _readyState = WebSocket.OPEN;
773 if (_onopen != null) _onopen();
774 };
775 _wsconn.onMessage = (message) {
776 if (_onmessage != null) {
777 _onmessage(new _WebSocketMessageEvent(message));
778 }
779 };
780 _wsconn.onClosed = (status, reason) {
781 _readyState = WebSocket.CLOSED;
782 if (_onclose != null) {
783 _onclose(new _WebSocketCloseEvent(true, status, reason));
784 }
785 };
786 _wsconn.onNoUpgrade = (response) {
787 if (_onerror != null) _onerror("Failed web socket connection");
788 };
789 _wsconn.onError = (e) {
790 if (_onerror != null) _onerror(e);
791 };
792 }
793
794 int get readyState() => _readyState;
795 int get bufferedAmount() => 0;
796
797 void set onopen(Function callback) {
798 _onopen = callback;
799 }
800
801 void set onerror(Function callback) {
802 _onerror = callback;
803 }
804
805 void set onclose(Function callback) {
806 _onclose = callback;
807 }
808
809 String get extensions() => null;
810 String get protocol() => null;
811
812 void close(int code, String reason) {
813 if (_readyState < WebSocket.CLOSING) _readyState = WebSocket.CLOSING;
814 _wsconn.close(code, reason);
815 }
816
817 void set onmessage(Function callback) {
818 _onmessage = callback;
819 }
820
821 void send(data) {
822 _wsconn.send(data);
823 }
824
825 WebSocketClientConnection _wsconn;
826 int _readyState = WebSocket.CONNECTING;
827 Function _onopen;
828 Function _onerror;
829 Function _onclose;
830 Function _onmessage;
831 }
832
833
834 class _WebSocketMessageEvent implements MessageEvent {
835 _WebSocketMessageEvent(this._data);
836 get data() => _data;
837 var _data;
838 }
839
840
841 class _WebSocketCloseEvent implements CloseEvent {
842 _WebSocketCloseEvent(this._wasClean, this._code, this._reason);
843 bool get wasClean() => _wasClean;
844 int get code() => _code;
845 String get reason() => _reason;
846 bool _wasClean;
847 int _code;
848 String _reason;
849 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698