Index: runtime/bin/socket_patch.dart |
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart |
index bb71cc24c981a26192643b5efe87f36b2f093c76..93184aad9d05aaf347cedc08d51f22370f07bd5f 100644 |
--- a/runtime/bin/socket_patch.dart |
+++ b/runtime/bin/socket_patch.dart |
@@ -12,12 +12,33 @@ patch class RawServerSocket { |
patch class RawSocket { |
- /* patch */ static Future<RawSocket> connect(String host, int port) { |
+ /* patch */ static Future<RawSocket> connect(host, int port) { |
return _RawSocket.connect(host, port); |
} |
} |
+patch class InternetAddress { |
+ /* patch */ static Future<List<InternetAddress>> lookup(String host) { |
+ return _NativeSocket.lookup(host); |
+ } |
+} |
+ |
+class _InternetAddress implements InternetAddress { |
+ final InternetAddressType type; |
+ final String address; |
+ final Uint8List _sockaddr_storage; |
+ |
+ _InternetAddress(InternetAddressType this.type, |
+ String this.address, |
+ List<int> this._sockaddr_storage); |
+ |
+ String toString() { |
+ return "InternetAddress('$address', ${type.name})"; |
+ } |
+} |
+ |
+ |
// The _NativeSocket class encapsulates an OS socket. |
class _NativeSocket extends NativeFieldWrapperClass1 { |
// Bit flags used when communicating between the eventhandler and |
@@ -77,49 +98,84 @@ class _NativeSocket extends NativeFieldWrapperClass1 { |
// Native port for socket services. |
static SendPort socketService; |
- static Future<_NativeSocket> connect(String host, int port) { |
- var completer = new Completer(); |
+ static Future<List<InternetAddress>> lookup(String host) { |
ensureSocketService(); |
- socketService.call([HOST_NAME_LOOKUP, host]).then((response) { |
- if (isErrorResponse(response)) { |
- completer.completeError( |
- createError(response, "Failed host name lookup")); |
- } else { |
- var socket = new _NativeSocket.normal(); |
- var result = socket.nativeCreateConnect(response, port); |
- if (result is OSError) { |
- completer.completeError(createError(result, "Connection failed")); |
- } else { |
- // Setup handlers for receiving the first write event which |
- // indicate that the socket is fully connected. |
- socket.setHandlers( |
- write: () { |
- socket.setListening(read: false, write: false); |
- completer.complete(socket); |
- }, |
- error: (e) { |
- socket.close(); |
- completer.completeError(createError(e, "Connection failed")); |
- } |
- ); |
- socket.setListening(read: false, write: true); |
- } |
- } |
- }); |
- return completer.future; |
+ return socketService.call([HOST_NAME_LOOKUP, host]) |
+ .then((response) { |
Søren Gjesse
2013/04/18 12:59:24
You better add a comment here that this is checkin
Anders Johnsen
2013/04/19 09:45:36
Done.
|
+ if (response is List && |
+ response.length > 0 && |
+ response.first is int) { |
+ return []; |
Søren Gjesse
2013/04/18 12:59:24
Throw an OSError here.
Anders Johnsen
2013/04/19 09:45:36
Done.
|
+ } else { |
+ return response.map((result) { |
+ var type = new InternetAddressType._(result[0]); |
+ return new _InternetAddress(type, result[1], result[2]); |
+ }).toList(); |
+ } |
+ }); |
+ } |
+ |
+ static Future<_NativeSocket> connect(host, int port) { |
+ return new Future.value(host) |
+ .then((host) { |
+ if (host is _InternetAddress) return host; |
+ return lookup(host) |
+ .then((list) { |
+ if (list.length == 0) { |
+ throw createError(response, "Failed host name lookup"); |
+ } |
+ return list[0]; |
+ }); |
+ }) |
+ .then((address) { |
+ ensureSocketService(); |
+ var socket = new _NativeSocket.normal(); |
+ var result = socket.nativeCreateConnect( |
+ address._sockaddr_storage, port); |
+ if (result is OSError) { |
+ throw createError(result, "Connection failed"); |
+ } else { |
+ var completer = new Completer(); |
+ // Setup handlers for receiving the first write event which |
+ // indicate that the socket is fully connected. |
+ socket.setHandlers( |
+ write: () { |
+ socket.setListening(read: false, write: false); |
+ completer.complete(socket); |
+ }, |
+ error: (e) { |
+ socket.close(); |
+ completer.completeError(createError(e, "Connection failed")); |
+ } |
+ ); |
+ socket.setListening(read: false, write: true); |
+ return completer.future; |
+ } |
+ }); |
} |
static Future<_NativeSocket> bind(String address, |
int port, |
int backlog) { |
- var socket = new _NativeSocket.listen(); |
- var result = socket.nativeCreateBindListen(address, port, backlog); |
- if (result is OSError) { |
- return new Future.error( |
- new SocketIOException("Failed to create server socket", result)); |
- } |
- if (port != 0) socket.localPort = port; |
- return new Future.value(socket); |
+ return lookup(address) |
+ .then((list) { |
+ if (list.length == 0) { |
+ throw createError(response, "Failed host name lookup"); |
+ } |
+ return list[0]; |
+ }) |
+ .then((address) { |
+ var socket = new _NativeSocket.listen(); |
+ var result = socket.nativeCreateBindListen(address._sockaddr_storage, |
+ port, |
+ backlog); |
+ if (result is OSError) { |
+ throw new SocketIOException( |
+ "Failed to create server socket", result); |
+ } |
+ if (port != 0) socket.localPort = port; |
+ return socket; |
+ }); |
} |
_NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { |
@@ -402,8 +458,9 @@ class _NativeSocket extends NativeFieldWrapperClass1 { |
nativeRead(int len) native "Socket_Read"; |
nativeWrite(List<int> buffer, int offset, int bytes) |
native "Socket_WriteList"; |
- nativeCreateConnect(String host, int port) native "Socket_CreateConnect"; |
- nativeCreateBindListen(String address, int port, int backlog) |
+ nativeCreateConnect(List<int> addr, |
+ int port) native "Socket_CreateConnect"; |
+ nativeCreateBindListen(List<int> addr, int port, int backlog) |
native "ServerSocket_CreateBindListen"; |
nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
int nativeGetPort() native "Socket_GetPort"; |
@@ -496,7 +553,7 @@ class _RawSocket extends Stream<RawSocketEvent> |
bool _readEventsEnabled = true; |
bool _writeEventsEnabled = true; |
- static Future<RawSocket> connect(String host, int port) { |
+ static Future<RawSocket> connect(host, int port) { |
return _NativeSocket.connect(host, port) |
.then((socket) => new _RawSocket(socket)); |
} |
@@ -650,7 +707,7 @@ class _ServerSocket extends Stream<Socket> |
patch class Socket { |
- /* patch */ static Future<Socket> connect(String host, int port) { |
+ /* patch */ static Future<Socket> connect(host, int port) { |
return RawSocket.connect(host, port).then( |
(socket) => new _Socket(socket)); |
} |