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