Chromium Code Reviews| 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)); |
| } |