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 List<int> _data; | |
Søren Gjesse
2013/04/18 09:07:40
I don't like having this here, but I guess keeoing
Anders Johnsen
2013/04/18 12:09:45
Done.
| |
31 | |
32 _InternetAddress(InternetAddressType this.type, | |
33 String this.address, | |
34 List<int> this._data); | |
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 | 91 |
71 // The type flags for this socket. | 92 // The type flags for this socket. |
72 final int typeFlags; | 93 final int typeFlags; |
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 // Native port for socket services. | 98 // Native port for socket services. |
78 static SendPort socketService; | 99 static SendPort socketService; |
79 | 100 |
80 static Future<_NativeSocket> connect(String host, int port) { | 101 static Future<List<InternetAddress>> lookup(String host) { |
81 var completer = new Completer(); | |
82 ensureSocketService(); | 102 ensureSocketService(); |
83 socketService.call([HOST_NAME_LOOKUP, host]).then((response) { | 103 return socketService.call([HOST_NAME_LOOKUP, host]) |
84 if (isErrorResponse(response)) { | 104 .then((response) { |
85 completer.completeError( | 105 if (response is List && |
86 createError(response, "Failed host name lookup")); | 106 response.length > 0 && |
87 } else { | 107 response.first is int) { |
88 var socket = new _NativeSocket.normal(); | 108 return []; |
89 var result = socket.nativeCreateConnect(response, port); | 109 } else { |
90 if (result is OSError) { | 110 return response.map((result) { |
91 completer.completeError(createError(result, "Connection failed")); | 111 var type = result[0] == 1 ? |
92 } else { | 112 InternetAddressType.IPv6 : InternetAddressType.IPv4; |
93 // Setup handlers for receiving the first write event which | 113 return new _InternetAddress(type, result[1], result[2]); |
94 // indicate that the socket is fully connected. | 114 }).toList(); |
95 socket.setHandlers( | 115 } |
96 write: () { | 116 }); |
97 socket.setListening(read: false, write: false); | 117 } |
98 completer.complete(socket); | 118 |
99 }, | 119 static Future<_NativeSocket> connect(host, int port) { |
Søren Gjesse
2013/04/18 09:07:40
Should we add type checks now that checked mode wi
Anders Johnsen
2013/04/18 12:09:45
The runtime-call will actually do the check for us
| |
100 error: (e) { | 120 return new Future.value(host) |
101 socket.close(); | 121 .then((host) { |
102 completer.completeError(createError(e, "Connection failed")); | 122 if (host is _InternetAddress) return host; |
103 } | 123 return lookup(host) |
104 ); | 124 .then((list) { |
105 socket.setListening(read: false, write: true); | 125 if (list.length == 0) { |
106 } | 126 throw createError(response, "Failed host name lookup"); |
107 } | 127 } |
108 }); | 128 return list[0]; |
109 return completer.future; | 129 }); |
130 }) | |
131 .then((address) { | |
132 ensureSocketService(); | |
133 var socket = new _NativeSocket.normal(); | |
134 int type = address.type == InternetAddressType.IPv6 ? 1 : 0; | |
135 var result = socket.nativeCreateConnect(type, address._data, port); | |
136 if (result is OSError) { | |
137 throw createError(result, "Connection failed"); | |
138 } else { | |
139 var completer = new Completer(); | |
140 // Setup handlers for receiving the first write event which | |
141 // indicate that the socket is fully connected. | |
142 socket.setHandlers( | |
143 write: () { | |
144 socket.setListening(read: false, write: false); | |
145 completer.complete(socket); | |
146 }, | |
147 error: (e) { | |
148 socket.close(); | |
149 completer.completeError(createError(e, "Connection failed")); | |
150 } | |
151 ); | |
152 socket.setListening(read: false, write: true); | |
153 return completer.future; | |
154 } | |
155 }); | |
110 } | 156 } |
111 | 157 |
112 static Future<_NativeSocket> bind(String address, | 158 static Future<_NativeSocket> bind(String address, |
113 int port, | 159 int port, |
114 int backlog) { | 160 int backlog) { |
115 var socket = new _NativeSocket.listen(); | 161 return lookup(address) |
116 var result = socket.nativeCreateBindListen(address, port, backlog); | 162 .then((list) { |
117 if (result is OSError) { | 163 if (list.length == 0) { |
118 return new Future.error( | 164 throw createError(response, "Failed host name lookup"); |
119 new SocketIOException("Failed to create server socket", result)); | 165 } |
120 } | 166 return list[0]; |
121 if (port != 0) socket.localPort = port; | 167 }) |
122 return new Future.value(socket); | 168 .then((address) { |
169 var socket = new _NativeSocket.listen(); | |
170 int type = address.type == InternetAddressType.IPv6 ? 1 : 0; | |
171 var result = socket.nativeCreateBindListen(type, | |
172 address._data, | |
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 }); | |
123 } | 182 } |
124 | 183 |
125 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { | 184 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { |
126 eventHandlers = new List(EVENT_COUNT + 1); | 185 eventHandlers = new List(EVENT_COUNT + 1); |
127 _EventHandler._start(); | 186 _EventHandler._start(); |
128 } | 187 } |
129 | 188 |
130 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { | 189 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { |
131 eventHandlers = new List(EVENT_COUNT + 1); | 190 eventHandlers = new List(EVENT_COUNT + 1); |
132 _EventHandler._start(); | 191 _EventHandler._start(); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
395 bool setOption(SocketOption option, bool enabled) { | 454 bool setOption(SocketOption option, bool enabled) { |
396 if (option is! SocketOption) throw new ArgumentError(options); | 455 if (option is! SocketOption) throw new ArgumentError(options); |
397 if (enabled is! bool) throw new ArgumentError(enabled); | 456 if (enabled is! bool) throw new ArgumentError(enabled); |
398 return nativeSetOption(option._value, enabled); | 457 return nativeSetOption(option._value, enabled); |
399 } | 458 } |
400 | 459 |
401 nativeAvailable() native "Socket_Available"; | 460 nativeAvailable() native "Socket_Available"; |
402 nativeRead(int len) native "Socket_Read"; | 461 nativeRead(int len) native "Socket_Read"; |
403 nativeWrite(List<int> buffer, int offset, int bytes) | 462 nativeWrite(List<int> buffer, int offset, int bytes) |
404 native "Socket_WriteList"; | 463 native "Socket_WriteList"; |
405 nativeCreateConnect(String host, int port) native "Socket_CreateConnect"; | 464 nativeCreateConnect(int type, |
406 nativeCreateBindListen(String address, int port, int backlog) | 465 List<int> host, |
466 int port) native "Socket_CreateConnect"; | |
467 nativeCreateBindListen(int type, List<int> address, int port, int backlog) | |
407 native "ServerSocket_CreateBindListen"; | 468 native "ServerSocket_CreateBindListen"; |
408 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; | 469 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
409 int nativeGetPort() native "Socket_GetPort"; | 470 int nativeGetPort() native "Socket_GetPort"; |
410 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; | 471 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; |
411 OSError nativeGetError() native "Socket_GetError"; | 472 OSError nativeGetError() native "Socket_GetError"; |
412 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; | 473 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; |
413 | 474 |
414 static SendPort newServicePort() native "Socket_NewServicePort"; | 475 static SendPort newServicePort() native "Socket_NewServicePort"; |
415 } | 476 } |
416 | 477 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 } | 550 } |
490 | 551 |
491 | 552 |
492 class _RawSocket extends Stream<RawSocketEvent> | 553 class _RawSocket extends Stream<RawSocketEvent> |
493 implements RawSocket { | 554 implements RawSocket { |
494 final _NativeSocket _socket; | 555 final _NativeSocket _socket; |
495 StreamController<RawSocketEvent> _controller; | 556 StreamController<RawSocketEvent> _controller; |
496 bool _readEventsEnabled = true; | 557 bool _readEventsEnabled = true; |
497 bool _writeEventsEnabled = true; | 558 bool _writeEventsEnabled = true; |
498 | 559 |
499 static Future<RawSocket> connect(String host, int port) { | 560 static Future<RawSocket> connect(host, int port) { |
500 return _NativeSocket.connect(host, port) | 561 return _NativeSocket.connect(host, port) |
501 .then((socket) => new _RawSocket(socket)); | 562 .then((socket) => new _RawSocket(socket)); |
502 } | 563 } |
503 | 564 |
504 _RawSocket(this._socket) { | 565 _RawSocket(this._socket) { |
505 _controller = new StreamController( | 566 _controller = new StreamController( |
506 onListen: _onSubscriptionStateChange, | 567 onListen: _onSubscriptionStateChange, |
507 onCancel: _onSubscriptionStateChange, | 568 onCancel: _onSubscriptionStateChange, |
508 onPause: _onPauseStateChange, | 569 onPause: _onPauseStateChange, |
509 onResume: _onPauseStateChange); | 570 onResume: _onPauseStateChange); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
643 cancelOnError: cancelOnError); | 704 cancelOnError: cancelOnError); |
644 } | 705 } |
645 | 706 |
646 int get port => _socket.port; | 707 int get port => _socket.port; |
647 | 708 |
648 void close() => _socket.close(); | 709 void close() => _socket.close(); |
649 } | 710 } |
650 | 711 |
651 | 712 |
652 patch class Socket { | 713 patch class Socket { |
653 /* patch */ static Future<Socket> connect(String host, int port) { | 714 /* patch */ static Future<Socket> connect(host, int port) { |
654 return RawSocket.connect(host, port).then( | 715 return RawSocket.connect(host, port).then( |
655 (socket) => new _Socket(socket)); | 716 (socket) => new _Socket(socket)); |
656 } | 717 } |
657 } | 718 } |
658 | 719 |
659 | 720 |
660 patch class SecureSocket { | 721 patch class SecureSocket { |
661 /* patch */ factory SecureSocket._(RawSecureSocket rawSocket) => | 722 /* patch */ factory SecureSocket._(RawSecureSocket rawSocket) => |
662 new _SecureSocket(rawSocket); | 723 new _SecureSocket(rawSocket); |
663 } | 724 } |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 _raw.onBadCertificate = callback; | 1008 _raw.onBadCertificate = callback; |
948 } | 1009 } |
949 | 1010 |
950 X509Certificate get peerCertificate { | 1011 X509Certificate get peerCertificate { |
951 if (_raw == null) { | 1012 if (_raw == null) { |
952 throw new StateError("peerCertificate called on destroyed SecureSocket"); | 1013 throw new StateError("peerCertificate called on destroyed SecureSocket"); |
953 } | 1014 } |
954 return _raw.peerCertificate; | 1015 return _raw.peerCertificate; |
955 } | 1016 } |
956 } | 1017 } |
OLD | NEW |