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( |
| 23 String host, {InternetAddressType type: InternetAddressType.ANY}) { |
| 24 return _NativeSocket.lookup(host, type: type); |
| 25 } |
| 26 } |
| 27 |
| 28 class _InternetAddress implements InternetAddress { |
| 29 final InternetAddressType type; |
| 30 final String address; |
| 31 final String host; |
| 32 final Uint8List _sockaddr_storage; |
| 33 |
| 34 _InternetAddress(InternetAddressType this.type, |
| 35 String this.address, |
| 36 String this.host, |
| 37 List<int> this._sockaddr_storage); |
| 38 |
| 39 String toString() { |
| 40 return "InternetAddress('$address', ${type.name})"; |
| 41 } |
| 42 } |
| 43 |
| 44 |
21 // The _NativeSocket class encapsulates an OS socket. | 45 // The _NativeSocket class encapsulates an OS socket. |
22 class _NativeSocket extends NativeFieldWrapperClass1 { | 46 class _NativeSocket extends NativeFieldWrapperClass1 { |
23 // Bit flags used when communicating between the eventhandler and | 47 // Bit flags used when communicating between the eventhandler and |
24 // dart code. The EVENT flags are used to indicate events of | 48 // dart code. The EVENT flags are used to indicate events of |
25 // interest when sending a message from dart code to the | 49 // interest when sending a message from dart code to the |
26 // eventhandler. When receiving a message from the eventhandler the | 50 // eventhandler. When receiving a message from the eventhandler the |
27 // EVENT flags indicate the events that actually happened. The | 51 // EVENT flags indicate the events that actually happened. The |
28 // COMMAND flags are used to send commands from dart to the | 52 // COMMAND flags are used to send commands from dart to the |
29 // eventhandler. COMMAND flags are never received from the | 53 // eventhandler. COMMAND flags are never received from the |
30 // eventhandler. Additional flags are used to communicate other | 54 // eventhandler. Additional flags are used to communicate other |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 | 91 |
68 // Indicates if native interrupts can be activated. | 92 // Indicates if native interrupts can be activated. |
69 bool canActivateEvents = true; | 93 bool canActivateEvents = true; |
70 | 94 |
71 // The type flags for this socket. | 95 // The type flags for this socket. |
72 final int typeFlags; | 96 final int typeFlags; |
73 | 97 |
74 // Holds the port of the socket, null if not known. | 98 // Holds the port of the socket, null if not known. |
75 int localPort; | 99 int localPort; |
76 | 100 |
77 // Holds the host or address used to connect or bind the socket. | 101 // Holds the address used to connect or bind the socket. |
78 String localHost; | 102 InternetAddress address; |
79 | 103 |
80 // Native port for socket services. | 104 // Native port for socket services. |
81 static SendPort socketService; | 105 static SendPort socketService; |
82 | 106 |
83 static Future<_NativeSocket> connect(String host, int port) { | 107 static Future<List<InternetAddress>> lookup( |
84 var completer = new Completer(); | 108 String host, {InternetAddressType type: InternetAddressType.ANY}) { |
85 ensureSocketService(); | 109 ensureSocketService(); |
86 socketService.call([HOST_NAME_LOOKUP, host]).then((response) { | 110 return socketService.call([HOST_NAME_LOOKUP, host, type._value]) |
87 if (isErrorResponse(response)) { | 111 .then((response) { |
88 completer.completeError( | 112 if (isErrorResponse(response)) { |
89 createError(response, "Failed host name lookup")); | 113 throw createError(response, "Failed host name lookup"); |
90 } else { | 114 } else { |
91 var socket = new _NativeSocket.normal(); | 115 return response.skip(1).map((result) { |
92 socket.localHost = host; | 116 var type = new InternetAddressType._from(result[0]); |
93 var result = socket.nativeCreateConnect(response, port); | 117 return new _InternetAddress(type, result[1], host, result[2]); |
94 if (result is OSError) { | 118 }).toList(); |
95 completer.completeError(createError(result, "Connection failed")); | 119 } |
96 } else { | 120 }); |
97 // Setup handlers for receiving the first write event which | 121 } |
98 // indicate that the socket is fully connected. | 122 |
99 socket.setHandlers( | 123 static Future<_NativeSocket> connect(host, int port) { |
100 write: () { | 124 return new Future.value(host) |
101 socket.setListening(read: false, write: false); | 125 .then((host) { |
102 completer.complete(socket); | 126 if (host is _InternetAddress) return host; |
103 }, | 127 return lookup(host) |
104 error: (e) { | 128 .then((list) { |
105 socket.close(); | 129 if (list.length == 0) { |
106 completer.completeError(createError(e, "Connection failed")); | 130 throw createError(response, "Failed host name lookup"); |
107 } | 131 } |
108 ); | 132 return list[0]; |
109 socket.setListening(read: false, write: true); | 133 }); |
110 } | 134 }) |
111 } | 135 .then((address) { |
112 }); | 136 ensureSocketService(); |
113 return completer.future; | 137 var socket = new _NativeSocket.normal(); |
| 138 socket.address = address; |
| 139 var result = socket.nativeCreateConnect( |
| 140 address._sockaddr_storage, port); |
| 141 if (result is OSError) { |
| 142 throw createError(result, "Connection failed"); |
| 143 } else { |
| 144 var completer = new Completer(); |
| 145 // Setup handlers for receiving the first write event which |
| 146 // indicate that the socket is fully connected. |
| 147 socket.setHandlers( |
| 148 write: () { |
| 149 socket.setListening(read: false, write: false); |
| 150 completer.complete(socket); |
| 151 }, |
| 152 error: (e) { |
| 153 socket.close(); |
| 154 completer.completeError(createError(e, "Connection failed")); |
| 155 } |
| 156 ); |
| 157 socket.setListening(read: false, write: true); |
| 158 return completer.future; |
| 159 } |
| 160 }); |
114 } | 161 } |
115 | 162 |
116 static Future<_NativeSocket> bind(String address, | 163 static Future<_NativeSocket> bind(String address, |
117 int port, | 164 int port, |
118 int backlog) { | 165 int backlog) { |
119 var socket = new _NativeSocket.listen(); | 166 return lookup(address) |
120 socket.localHost = address; | 167 .then((list) { |
121 var result = socket.nativeCreateBindListen(address, port, backlog); | 168 if (list.length == 0) { |
122 if (result is OSError) { | 169 throw createError(response, "Failed host name lookup"); |
123 return new Future.error( | 170 } |
124 new SocketIOException("Failed to create server socket", result)); | 171 return list[0]; |
125 } | 172 }) |
126 if (port != 0) socket.localPort = port; | 173 .then((address) { |
127 return new Future.value(socket); | 174 var socket = new _NativeSocket.listen(); |
| 175 socket.address = address; |
| 176 var result = socket.nativeCreateBindListen(address._sockaddr_storage, |
| 177 port, |
| 178 backlog); |
| 179 if (result is OSError) { |
| 180 throw new SocketIOException( |
| 181 "Failed to create server socket", result); |
| 182 } |
| 183 if (port != 0) socket.localPort = port; |
| 184 return socket; |
| 185 }); |
128 } | 186 } |
129 | 187 |
130 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { | 188 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { |
131 eventHandlers = new List(EVENT_COUNT + 1); | 189 eventHandlers = new List(EVENT_COUNT + 1); |
132 _EventHandler._start(); | 190 _EventHandler._start(); |
133 } | 191 } |
134 | 192 |
135 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { | 193 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { |
136 eventHandlers = new List(EVENT_COUNT + 1); | 194 eventHandlers = new List(EVENT_COUNT + 1); |
137 _EventHandler._start(); | 195 _EventHandler._start(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 if (result is OSError) { | 245 if (result is OSError) { |
188 reportError(result, "Write failed"); | 246 reportError(result, "Write failed"); |
189 result = 0; | 247 result = 0; |
190 } | 248 } |
191 return result; | 249 return result; |
192 } | 250 } |
193 | 251 |
194 _NativeSocket accept() { | 252 _NativeSocket accept() { |
195 var socket = new _NativeSocket.normal(); | 253 var socket = new _NativeSocket.normal(); |
196 if (nativeAccept(socket) != true) return null; | 254 if (nativeAccept(socket) != true) return null; |
| 255 socket.localPort = localPort; |
| 256 socket.address = address; |
197 return socket; | 257 return socket; |
198 } | 258 } |
199 | 259 |
200 int get port { | 260 int get port { |
201 if (localPort != null) return localPort; | 261 if (localPort != null) return localPort; |
202 return localPort = nativeGetPort(); | 262 return localPort = nativeGetPort(); |
203 } | 263 } |
204 | 264 |
205 int get remotePort { | 265 int get remotePort { |
206 return nativeGetRemotePeer()[1]; | 266 return nativeGetRemotePeer()[1]; |
207 } | 267 } |
208 | 268 |
209 String get host => localHost; | |
210 | |
211 String get remoteHost { | 269 String get remoteHost { |
212 return nativeGetRemotePeer()[0]; | 270 return nativeGetRemotePeer()[0]; |
213 } | 271 } |
214 | 272 |
215 // Multiplexes socket events to the socket handlers. | 273 // Multiplexes socket events to the socket handlers. |
216 void multiplex(int events) { | 274 void multiplex(int events) { |
217 canActivateEvents = false; | 275 canActivateEvents = false; |
218 for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) { | 276 for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) { |
219 if (((events & (1 << i)) != 0)) { | 277 if (((events & (1 << i)) != 0)) { |
220 if (i == CLOSED_EVENT && | 278 if (i == CLOSED_EVENT && |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 bool setOption(SocketOption option, bool enabled) { | 460 bool setOption(SocketOption option, bool enabled) { |
403 if (option is! SocketOption) throw new ArgumentError(options); | 461 if (option is! SocketOption) throw new ArgumentError(options); |
404 if (enabled is! bool) throw new ArgumentError(enabled); | 462 if (enabled is! bool) throw new ArgumentError(enabled); |
405 return nativeSetOption(option._value, enabled); | 463 return nativeSetOption(option._value, enabled); |
406 } | 464 } |
407 | 465 |
408 nativeAvailable() native "Socket_Available"; | 466 nativeAvailable() native "Socket_Available"; |
409 nativeRead(int len) native "Socket_Read"; | 467 nativeRead(int len) native "Socket_Read"; |
410 nativeWrite(List<int> buffer, int offset, int bytes) | 468 nativeWrite(List<int> buffer, int offset, int bytes) |
411 native "Socket_WriteList"; | 469 native "Socket_WriteList"; |
412 nativeCreateConnect(String host, int port) native "Socket_CreateConnect"; | 470 nativeCreateConnect(List<int> addr, |
413 nativeCreateBindListen(String address, int port, int backlog) | 471 int port) native "Socket_CreateConnect"; |
| 472 nativeCreateBindListen(List<int> addr, int port, int backlog) |
414 native "ServerSocket_CreateBindListen"; | 473 native "ServerSocket_CreateBindListen"; |
415 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; | 474 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
416 int nativeGetPort() native "Socket_GetPort"; | 475 int nativeGetPort() native "Socket_GetPort"; |
417 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; | 476 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; |
418 OSError nativeGetError() native "Socket_GetError"; | 477 OSError nativeGetError() native "Socket_GetError"; |
419 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; | 478 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; |
420 | 479 |
421 static SendPort newServicePort() native "Socket_NewServicePort"; | 480 static SendPort newServicePort() native "Socket_NewServicePort"; |
422 } | 481 } |
423 | 482 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 } | 555 } |
497 | 556 |
498 | 557 |
499 class _RawSocket extends Stream<RawSocketEvent> | 558 class _RawSocket extends Stream<RawSocketEvent> |
500 implements RawSocket { | 559 implements RawSocket { |
501 final _NativeSocket _socket; | 560 final _NativeSocket _socket; |
502 StreamController<RawSocketEvent> _controller; | 561 StreamController<RawSocketEvent> _controller; |
503 bool _readEventsEnabled = true; | 562 bool _readEventsEnabled = true; |
504 bool _writeEventsEnabled = true; | 563 bool _writeEventsEnabled = true; |
505 | 564 |
506 static Future<RawSocket> connect(String host, int port) { | 565 static Future<RawSocket> connect(host, int port) { |
507 return _NativeSocket.connect(host, port) | 566 return _NativeSocket.connect(host, port) |
508 .then((socket) => new _RawSocket(socket)); | 567 .then((socket) => new _RawSocket(socket)); |
509 } | 568 } |
510 | 569 |
511 _RawSocket(this._socket) { | 570 _RawSocket(this._socket) { |
512 _controller = new StreamController( | 571 _controller = new StreamController( |
513 onListen: _onSubscriptionStateChange, | 572 onListen: _onSubscriptionStateChange, |
514 onCancel: _onSubscriptionStateChange, | 573 onCancel: _onSubscriptionStateChange, |
515 onPause: _onPauseStateChange, | 574 onPause: _onPauseStateChange, |
516 onResume: _onPauseStateChange); | 575 onResume: _onPauseStateChange); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 _socket.write(buffer, offset, count); | 623 _socket.write(buffer, offset, count); |
565 | 624 |
566 void close() => _socket.close(); | 625 void close() => _socket.close(); |
567 | 626 |
568 void shutdown(SocketDirection direction) => _socket.shutdown(direction); | 627 void shutdown(SocketDirection direction) => _socket.shutdown(direction); |
569 | 628 |
570 int get port => _socket.port; | 629 int get port => _socket.port; |
571 | 630 |
572 int get remotePort => _socket.remotePort; | 631 int get remotePort => _socket.remotePort; |
573 | 632 |
574 String get host => _socket.host; | 633 InternetAddress get address => _socket.address; |
575 | 634 |
576 String get remoteHost => _socket.remoteHost; | 635 String get remoteHost => _socket.remoteHost; |
577 | 636 |
578 bool get readEventsEnabled => _readEventsEnabled; | 637 bool get readEventsEnabled => _readEventsEnabled; |
579 void set readEventsEnabled(bool value) { | 638 void set readEventsEnabled(bool value) { |
580 if (value != _readEventsEnabled) { | 639 if (value != _readEventsEnabled) { |
581 _readEventsEnabled = value; | 640 _readEventsEnabled = value; |
582 if (!_controller.isPaused) _resume(); | 641 if (!_controller.isPaused) _resume(); |
583 } | 642 } |
584 } | 643 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 cancelOnError: cancelOnError); | 711 cancelOnError: cancelOnError); |
653 } | 712 } |
654 | 713 |
655 int get port => _socket.port; | 714 int get port => _socket.port; |
656 | 715 |
657 void close() => _socket.close(); | 716 void close() => _socket.close(); |
658 } | 717 } |
659 | 718 |
660 | 719 |
661 patch class Socket { | 720 patch class Socket { |
662 /* patch */ static Future<Socket> connect(String host, int port) { | 721 /* patch */ static Future<Socket> connect(host, int port) { |
663 return RawSocket.connect(host, port).then( | 722 return RawSocket.connect(host, port).then( |
664 (socket) => new _Socket(socket)); | 723 (socket) => new _Socket(socket)); |
665 } | 724 } |
666 } | 725 } |
667 | 726 |
668 | 727 |
669 patch class SecureSocket { | 728 patch class SecureSocket { |
670 /* patch */ factory SecureSocket._(RawSecureSocket rawSocket) => | 729 /* patch */ factory SecureSocket._(RawSecureSocket rawSocket) => |
671 new _SecureSocket(rawSocket); | 730 new _SecureSocket(rawSocket); |
672 } | 731 } |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 _raw.onBadCertificate = callback; | 1031 _raw.onBadCertificate = callback; |
973 } | 1032 } |
974 | 1033 |
975 X509Certificate get peerCertificate { | 1034 X509Certificate get peerCertificate { |
976 if (_raw == null) { | 1035 if (_raw == null) { |
977 throw new StateError("peerCertificate called on destroyed SecureSocket"); | 1036 throw new StateError("peerCertificate called on destroyed SecureSocket"); |
978 } | 1037 } |
979 return _raw.peerCertificate; | 1038 return _raw.peerCertificate; |
980 } | 1039 } |
981 } | 1040 } |
OLD | NEW |