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 patch class RawServerSocket { | 5 patch class RawServerSocket { |
6 /* patch */ static Future<RawServerSocket> bind([String address = "127.0.0.1", | 6 /* patch */ static Future<RawServerSocket> bind([String address = "127.0.0.1", |
7 int port = 0, | 7 int port = 0, |
8 int backlog = 0]) { | 8 int backlog = 0]) { |
9 return _RawServerSocket.bind(address, port, backlog); | 9 return _RawServerSocket.bind(address, port, backlog); |
10 } | 10 } |
11 } | 11 } |
12 | 12 |
13 | 13 |
14 patch class RawSocket { | 14 patch class RawSocket { |
15 /* patch */ static Future<RawSocket> connect(String host, int port) { | 15 /* patch */ static Future<RawSocket> connect(host, int port) { |
16 return _RawSocket.connect(host, port); | 16 return _RawSocket.connect(host, port); |
17 } | 17 } |
18 } | 18 } |
19 | 19 |
20 | 20 |
| 21 patch class InternetAddress { |
| 22 /* patch */ static Future<List<InternetAddress>> lookup(String host) { |
| 23 return _NativeSocket.lookup(host); |
| 24 } |
| 25 } |
| 26 |
| 27 class _InternetAddress implements InternetAddress { |
| 28 final InternetAddressType type; |
| 29 final String address; |
| 30 final Uint8List _sockaddr_storage; |
| 31 |
| 32 _InternetAddress(InternetAddressType this.type, |
| 33 String this.address, |
| 34 List<int> this._sockaddr_storage); |
| 35 |
| 36 String toString() { |
| 37 return "InternetAddress('$address', ${type.name})"; |
| 38 } |
| 39 } |
| 40 |
| 41 |
21 // The _NativeSocket class encapsulates an OS socket. | 42 // The _NativeSocket class encapsulates an OS socket. |
22 class _NativeSocket extends NativeFieldWrapperClass1 { | 43 class _NativeSocket extends NativeFieldWrapperClass1 { |
23 // Bit flags used when communicating between the eventhandler and | 44 // Bit flags used when communicating between the eventhandler and |
24 // dart code. The EVENT flags are used to indicate events of | 45 // dart code. The EVENT flags are used to indicate events of |
25 // interest when sending a message from dart code to the | 46 // interest when sending a message from dart code to the |
26 // eventhandler. When receiving a message from the eventhandler the | 47 // eventhandler. When receiving a message from the eventhandler the |
27 // EVENT flags indicate the events that actually happened. The | 48 // EVENT flags indicate the events that actually happened. The |
28 // COMMAND flags are used to send commands from dart to the | 49 // COMMAND flags are used to send commands from dart to the |
29 // eventhandler. COMMAND flags are never received from the | 50 // eventhandler. COMMAND flags are never received from the |
30 // eventhandler. Additional flags are used to communicate other | 51 // eventhandler. Additional flags are used to communicate other |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 94 |
74 // Holds the port of the socket, null if not known. | 95 // Holds the port of the socket, null if not known. |
75 int localPort; | 96 int localPort; |
76 | 97 |
77 // Holds the host or address used to connect or bind the socket. | 98 // Holds the host or address used to connect or bind the socket. |
78 String localHost; | 99 String localHost; |
79 | 100 |
80 // Native port for socket services. | 101 // Native port for socket services. |
81 static SendPort socketService; | 102 static SendPort socketService; |
82 | 103 |
83 static Future<_NativeSocket> connect(String host, int port) { | 104 static Future<List<InternetAddress>> lookup(String host) { |
84 var completer = new Completer(); | |
85 ensureSocketService(); | 105 ensureSocketService(); |
86 socketService.call([HOST_NAME_LOOKUP, host]).then((response) { | 106 return socketService.call([HOST_NAME_LOOKUP, host]) |
87 if (isErrorResponse(response)) { | 107 .then((response) { |
88 completer.completeError( | 108 if (isErrorResponse(response)) { |
89 createError(response, "Failed host name lookup")); | 109 throw createError(response, "Failed host name lookup"); |
90 } else { | 110 } else { |
91 var socket = new _NativeSocket.normal(); | 111 return response.skip(1).map((result) { |
92 socket.localHost = host; | 112 var type = new InternetAddressType._(result[0]); |
93 var result = socket.nativeCreateConnect(response, port); | 113 return new _InternetAddress(type, result[1], result[2]); |
94 if (result is OSError) { | 114 }).toList(); |
95 completer.completeError(createError(result, "Connection failed")); | 115 } |
96 } else { | 116 }); |
97 // Setup handlers for receiving the first write event which | 117 } |
98 // indicate that the socket is fully connected. | 118 |
99 socket.setHandlers( | 119 static Future<_NativeSocket> connect(host, int port) { |
100 write: () { | 120 return new Future.value(host) |
101 socket.setListening(read: false, write: false); | 121 .then((host) { |
102 completer.complete(socket); | 122 if (host is _InternetAddress) return host; |
103 }, | 123 return lookup(host) |
104 error: (e) { | 124 .then((list) { |
105 socket.close(); | 125 if (list.length == 0) { |
106 completer.completeError(createError(e, "Connection failed")); | 126 throw createError(response, "Failed host name lookup"); |
107 } | 127 } |
108 ); | 128 return list[0]; |
109 socket.setListening(read: false, write: true); | 129 }); |
110 } | 130 }) |
111 } | 131 .then((address) { |
112 }); | 132 ensureSocketService(); |
113 return completer.future; | 133 var socket = new _NativeSocket.normal(); |
| 134 socket.localHost = address.address; |
| 135 var result = socket.nativeCreateConnect( |
| 136 address._sockaddr_storage, port); |
| 137 if (result is OSError) { |
| 138 throw createError(result, "Connection failed"); |
| 139 } else { |
| 140 var completer = new Completer(); |
| 141 // Setup handlers for receiving the first write event which |
| 142 // indicate that the socket is fully connected. |
| 143 socket.setHandlers( |
| 144 write: () { |
| 145 socket.setListening(read: false, write: false); |
| 146 completer.complete(socket); |
| 147 }, |
| 148 error: (e) { |
| 149 socket.close(); |
| 150 completer.completeError(createError(e, "Connection failed")); |
| 151 } |
| 152 ); |
| 153 socket.setListening(read: false, write: true); |
| 154 return completer.future; |
| 155 } |
| 156 }); |
114 } | 157 } |
115 | 158 |
116 static Future<_NativeSocket> bind(String address, | 159 static Future<_NativeSocket> bind(String address, |
117 int port, | 160 int port, |
118 int backlog) { | 161 int backlog) { |
119 var socket = new _NativeSocket.listen(); | 162 return lookup(address) |
120 socket.localHost = address; | 163 .then((list) { |
121 var result = socket.nativeCreateBindListen(address, port, backlog); | 164 if (list.length == 0) { |
122 if (result is OSError) { | 165 throw createError(response, "Failed host name lookup"); |
123 return new Future.error( | 166 } |
124 new SocketIOException("Failed to create server socket", result)); | 167 return list[0]; |
125 } | 168 }) |
126 if (port != 0) socket.localPort = port; | 169 .then((address) { |
127 return new Future.value(socket); | 170 var socket = new _NativeSocket.listen(); |
| 171 socket.localHost = address.address; |
| 172 var result = socket.nativeCreateBindListen(address._sockaddr_storage, |
| 173 port, |
| 174 backlog); |
| 175 if (result is OSError) { |
| 176 throw new SocketIOException( |
| 177 "Failed to create server socket", result); |
| 178 } |
| 179 if (port != 0) socket.localPort = port; |
| 180 return socket; |
| 181 }); |
128 } | 182 } |
129 | 183 |
130 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { | 184 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { |
131 eventHandlers = new List(EVENT_COUNT + 1); | 185 eventHandlers = new List(EVENT_COUNT + 1); |
132 _EventHandler._start(); | 186 _EventHandler._start(); |
133 } | 187 } |
134 | 188 |
135 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { | 189 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { |
136 eventHandlers = new List(EVENT_COUNT + 1); | 190 eventHandlers = new List(EVENT_COUNT + 1); |
137 _EventHandler._start(); | 191 _EventHandler._start(); |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 bool setOption(SocketOption option, bool enabled) { | 456 bool setOption(SocketOption option, bool enabled) { |
403 if (option is! SocketOption) throw new ArgumentError(options); | 457 if (option is! SocketOption) throw new ArgumentError(options); |
404 if (enabled is! bool) throw new ArgumentError(enabled); | 458 if (enabled is! bool) throw new ArgumentError(enabled); |
405 return nativeSetOption(option._value, enabled); | 459 return nativeSetOption(option._value, enabled); |
406 } | 460 } |
407 | 461 |
408 nativeAvailable() native "Socket_Available"; | 462 nativeAvailable() native "Socket_Available"; |
409 nativeRead(int len) native "Socket_Read"; | 463 nativeRead(int len) native "Socket_Read"; |
410 nativeWrite(List<int> buffer, int offset, int bytes) | 464 nativeWrite(List<int> buffer, int offset, int bytes) |
411 native "Socket_WriteList"; | 465 native "Socket_WriteList"; |
412 nativeCreateConnect(String host, int port) native "Socket_CreateConnect"; | 466 nativeCreateConnect(List<int> addr, |
413 nativeCreateBindListen(String address, int port, int backlog) | 467 int port) native "Socket_CreateConnect"; |
| 468 nativeCreateBindListen(List<int> addr, int port, int backlog) |
414 native "ServerSocket_CreateBindListen"; | 469 native "ServerSocket_CreateBindListen"; |
415 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; | 470 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
416 int nativeGetPort() native "Socket_GetPort"; | 471 int nativeGetPort() native "Socket_GetPort"; |
417 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; | 472 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; |
418 OSError nativeGetError() native "Socket_GetError"; | 473 OSError nativeGetError() native "Socket_GetError"; |
419 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; | 474 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; |
420 | 475 |
421 static SendPort newServicePort() native "Socket_NewServicePort"; | 476 static SendPort newServicePort() native "Socket_NewServicePort"; |
422 } | 477 } |
423 | 478 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 } | 551 } |
497 | 552 |
498 | 553 |
499 class _RawSocket extends Stream<RawSocketEvent> | 554 class _RawSocket extends Stream<RawSocketEvent> |
500 implements RawSocket { | 555 implements RawSocket { |
501 final _NativeSocket _socket; | 556 final _NativeSocket _socket; |
502 StreamController<RawSocketEvent> _controller; | 557 StreamController<RawSocketEvent> _controller; |
503 bool _readEventsEnabled = true; | 558 bool _readEventsEnabled = true; |
504 bool _writeEventsEnabled = true; | 559 bool _writeEventsEnabled = true; |
505 | 560 |
506 static Future<RawSocket> connect(String host, int port) { | 561 static Future<RawSocket> connect(host, int port) { |
507 return _NativeSocket.connect(host, port) | 562 return _NativeSocket.connect(host, port) |
508 .then((socket) => new _RawSocket(socket)); | 563 .then((socket) => new _RawSocket(socket)); |
509 } | 564 } |
510 | 565 |
511 _RawSocket(this._socket) { | 566 _RawSocket(this._socket) { |
512 _controller = new StreamController( | 567 _controller = new StreamController( |
513 onListen: _onSubscriptionStateChange, | 568 onListen: _onSubscriptionStateChange, |
514 onCancel: _onSubscriptionStateChange, | 569 onCancel: _onSubscriptionStateChange, |
515 onPause: _onPauseStateChange, | 570 onPause: _onPauseStateChange, |
516 onResume: _onPauseStateChange); | 571 onResume: _onPauseStateChange); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 cancelOnError: cancelOnError); | 707 cancelOnError: cancelOnError); |
653 } | 708 } |
654 | 709 |
655 int get port => _socket.port; | 710 int get port => _socket.port; |
656 | 711 |
657 void close() => _socket.close(); | 712 void close() => _socket.close(); |
658 } | 713 } |
659 | 714 |
660 | 715 |
661 patch class Socket { | 716 patch class Socket { |
662 /* patch */ static Future<Socket> connect(String host, int port) { | 717 /* patch */ static Future<Socket> connect(host, int port) { |
663 return RawSocket.connect(host, port).then( | 718 return RawSocket.connect(host, port).then( |
664 (socket) => new _Socket(socket)); | 719 (socket) => new _Socket(socket)); |
665 } | 720 } |
666 } | 721 } |
667 | 722 |
668 | 723 |
669 patch class SecureSocket { | 724 patch class SecureSocket { |
670 /* patch */ factory SecureSocket._(RawSecureSocket rawSocket) => | 725 /* patch */ factory SecureSocket._(RawSecureSocket rawSocket) => |
671 new _SecureSocket(rawSocket); | 726 new _SecureSocket(rawSocket); |
672 } | 727 } |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 _raw.onBadCertificate = callback; | 1011 _raw.onBadCertificate = callback; |
957 } | 1012 } |
958 | 1013 |
959 X509Certificate get peerCertificate { | 1014 X509Certificate get peerCertificate { |
960 if (_raw == null) { | 1015 if (_raw == null) { |
961 throw new StateError("peerCertificate called on destroyed SecureSocket"); | 1016 throw new StateError("peerCertificate called on destroyed SecureSocket"); |
962 } | 1017 } |
963 return _raw.peerCertificate; | 1018 return _raw.peerCertificate; |
964 } | 1019 } |
965 } | 1020 } |
OLD | NEW |