Index: runtime/bin/http_impl.dart |
diff --git a/runtime/bin/http_impl.dart b/runtime/bin/http_impl.dart |
index 7e71ca814cf62f870d31fd308c67de0fc77ac576..a0d73baee293f486f2eca039d54a2e727da750d3 100644 |
--- a/runtime/bin/http_impl.dart |
+++ b/runtime/bin/http_impl.dart |
@@ -2105,29 +2105,92 @@ class _HttpClient implements HttpClient { |
} |
HttpClientConnection _prepareHttpClientConnection( |
- String method, |
- Uri url, |
- [_HttpClientConnection connection]) { |
+ String method, |
+ Uri url, |
+ [_HttpClientConnection connection]) { |
+ |
+ void _establishConnection(String host, |
+ int port, |
+ _ProxyConfiguration proxyConfiguration, |
+ int proxyIndex) { |
+ |
+ void _connectionOpened(_SocketConnection socketConn, |
+ _HttpClientConnection connection, |
+ bool usingProxy) { |
+ connection._usingProxy = usingProxy; |
+ connection._connectionEstablished(socketConn); |
+ HttpClientRequest request = connection.open(method, url); |
+ request.headers.host = host; |
+ request.headers.port = port; |
+ if (connection._onRequest != null) { |
+ connection._onRequest(request); |
+ } else { |
+ request.outputStream.close(); |
+ } |
+ } |
- String host = url.domain; |
- int port = url.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : url.port; |
+ assert(proxyIndex < proxyConfiguration.proxies.length); |
- void _connectionOpened(_SocketConnection socketConn, |
- _HttpClientConnection connection, |
- bool usingProxy) { |
- connection._usingProxy = usingProxy; |
- connection._connectionEstablished(socketConn); |
- HttpClientRequest request = connection.open(method, url); |
- request.headers.host = host; |
- request.headers.port = port; |
- if (connection._onRequest != null) { |
- connection._onRequest(request); |
+ // Determine the actual host to connect to. |
+ String connectHost; |
+ int connectPort; |
+ _Proxy proxy = proxyConfiguration.proxies[proxyIndex]; |
+ if (proxy.isDirect) { |
+ connectHost = host; |
+ connectPort = port; |
} else { |
- request.outputStream.close(); |
+ connectHost = proxy.host; |
+ connectPort = proxy.port; |
+ } |
+ |
+ // If there are active connections for this key get the first one |
+ // otherwise create a new one. |
+ String key = _connectionKey(connectHost, connectPort); |
+ Queue socketConnections = _openSockets[key]; |
+ if (socketConnections == null || socketConnections.isEmpty()) { |
+ Socket socket = new Socket(connectHost, connectPort); |
+ // Until the connection is established handle connection errors |
+ // here as the HttpClientConnection object is not yet associated |
+ // with the socket. |
+ socket.onError = (e) { |
+ proxyIndex++; |
+ if (proxyIndex < proxyConfiguration.proxies.length) { |
+ // Try the next proxy in the list. |
+ _establishConnection(host, port, proxyConfiguration, proxyIndex); |
+ } else { |
+ // Report the error through the HttpClientConnection object to |
+ // the client. |
+ connection._onError(e); |
+ } |
+ }; |
+ socket.onConnect = () { |
+ // When the connection is established, clear the error |
+ // callback as it will now be handled by the |
+ // HttpClientConnection object which will be associated with |
+ // the connected socket. |
+ socket.onError = null; |
+ _SocketConnection socketConn = |
+ new _SocketConnection(connectHost, connectPort, socket); |
+ _activeSockets.add(socketConn); |
+ _connectionOpened(socketConn, connection, !proxy.isDirect); |
+ }; |
+ } else { |
+ _SocketConnection socketConn = socketConnections.removeFirst(); |
+ _activeSockets.add(socketConn); |
+ new Timer(0, (ignored) => |
+ _connectionOpened(socketConn, connection, !proxy.isDirect)); |
+ |
+ // Get rid of eviction timer if there are no more active connections. |
+ if (socketConnections.isEmpty()) _openSockets.remove(key); |
+ if (_openSockets.isEmpty()) _cancelEvictionTimer(); |
} |
} |
- // Create a new connection if we are not re-using an existing one. |
+ // Find the TCP host and port. |
+ String host = url.domain; |
+ int port = url.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : url.port; |
+ |
+ // Create a new connection object if we are not re-using an existing one. |
if (connection == null) { |
connection = new _HttpClientConnection(this); |
} |
@@ -2141,53 +2204,8 @@ class _HttpClient implements HttpClient { |
proxyConfiguration = new _ProxyConfiguration(_findProxy(url)); |
} |
- // Determine the actual host to connect to. |
- String connectHost; |
- int connectPort; |
- _Proxy proxy = proxyConfiguration.proxies[0]; |
- if (proxy.isDirect) { |
- connectHost = host; |
- connectPort = port; |
- } else { |
- connectHost = proxy.host; |
- connectPort = proxy.port; |
- } |
- |
- // If there are active connections for this key get the first one |
- // otherwise create a new one. |
- String key = _connectionKey(connectHost, connectPort); |
- Queue socketConnections = _openSockets[key]; |
- if (socketConnections == null || socketConnections.isEmpty()) { |
- Socket socket = new Socket(connectHost, connectPort); |
- // Until the connection is established handle connection errors |
- // here as the HttpClientConnection object is not yet associated |
- // with the socket. |
- socket.onError = (e) { |
- // Report the error through the HttpClientConnection object to |
- // the client. |
- connection._onError(e); |
- }; |
- socket.onConnect = () { |
- // When the connection is established, clear the error |
- // callback as it will now be handled by the |
- // HttpClientConnection object which will be associated with |
- // the connected socket. |
- socket.onError = null; |
- _SocketConnection socketConn = |
- new _SocketConnection(connectHost, connectPort, socket); |
- _activeSockets.add(socketConn); |
- _connectionOpened(socketConn, connection, !proxy.isDirect); |
- }; |
- } else { |
- _SocketConnection socketConn = socketConnections.removeFirst(); |
- _activeSockets.add(socketConn); |
- new Timer(0, (ignored) => |
- _connectionOpened(socketConn, connection, !proxy.isDirect)); |
- |
- // Get rid of eviction timer if there are no more active connections. |
- if (socketConnections.isEmpty()) _openSockets.remove(key); |
- if (_openSockets.isEmpty()) _cancelEvictionTimer(); |
- } |
+ // Establish the connection starting with the first proxy configured. |
+ _establishConnection(host, port, proxyConfiguration, 0); |
return connection; |
} |