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..acbc6ead5c96d80f661f54791f9b6fe4ee0a44b9 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 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.
|
| + |
| + _InternetAddress(InternetAddressType this.type, |
| + String this.address, |
| + List<int> this._data); |
| + |
| + 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,87 @@ 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) { |
| + if (response is List && |
| + response.length > 0 && |
| + response.first is int) { |
| + return []; |
| + } else { |
| + return response.map((result) { |
| + var type = result[0] == 1 ? |
| + InternetAddressType.IPv6 : InternetAddressType.IPv4; |
| + return new _InternetAddress(type, result[1], result[2]); |
| + }).toList(); |
| + } |
| + }); |
| + } |
| + |
| + 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
|
| + 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(); |
| + int type = address.type == InternetAddressType.IPv6 ? 1 : 0; |
| + var result = socket.nativeCreateConnect(type, address._data, 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(); |
| + int type = address.type == InternetAddressType.IPv6 ? 1 : 0; |
| + var result = socket.nativeCreateBindListen(type, |
| + address._data, |
| + 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 +461,10 @@ 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(int type, |
| + List<int> host, |
| + int port) native "Socket_CreateConnect"; |
| + nativeCreateBindListen(int type, List<int> address, int port, int backlog) |
| native "ServerSocket_CreateBindListen"; |
| nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
| int nativeGetPort() native "Socket_GetPort"; |
| @@ -496,7 +557,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 +711,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)); |
| } |