Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: runtime/bin/http_impl.dart

Issue 11092044: Add support for multiple HTTP proxies (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/standalone/io/http_proxy_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 class _HttpHeaders implements HttpHeaders { 5 class _HttpHeaders implements HttpHeaders {
6 _HttpHeaders() : _headers = new Map<String, List<String>>(); 6 _HttpHeaders() : _headers = new Map<String, List<String>>();
7 7
8 List<String> operator[](String name) { 8 List<String> operator[](String name) {
9 name = name.toLowerCase(); 9 name = name.toLowerCase();
10 return _headers[name]; 10 return _headers[name];
(...skipping 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after
2098 void _cancelEvictionTimer() { 2098 void _cancelEvictionTimer() {
2099 _evictionTimer.cancel(); 2099 _evictionTimer.cancel();
2100 _evictionTimer = null; 2100 _evictionTimer = null;
2101 } 2101 }
2102 2102
2103 String _connectionKey(String host, int port) { 2103 String _connectionKey(String host, int port) {
2104 return "$host:$port"; 2104 return "$host:$port";
2105 } 2105 }
2106 2106
2107 HttpClientConnection _prepareHttpClientConnection( 2107 HttpClientConnection _prepareHttpClientConnection(
2108 String method, 2108 String method,
2109 Uri url, 2109 Uri url,
2110 [_HttpClientConnection connection]) { 2110 [_HttpClientConnection connection]) {
2111 2111
2112 void _establishConnection(String host,
2113 int port,
2114 _ProxyConfiguration proxyConfiguration,
2115 int proxyIndex) {
2116
2117 void _connectionOpened(_SocketConnection socketConn,
2118 _HttpClientConnection connection,
2119 bool usingProxy) {
2120 connection._usingProxy = usingProxy;
2121 connection._connectionEstablished(socketConn);
2122 HttpClientRequest request = connection.open(method, url);
2123 request.headers.host = host;
2124 request.headers.port = port;
2125 if (connection._onRequest != null) {
2126 connection._onRequest(request);
2127 } else {
2128 request.outputStream.close();
2129 }
2130 }
2131
2132 assert(proxyIndex < proxyConfiguration.proxies.length);
2133
2134 // Determine the actual host to connect to.
2135 String connectHost;
2136 int connectPort;
2137 _Proxy proxy = proxyConfiguration.proxies[proxyIndex];
2138 if (proxy.isDirect) {
2139 connectHost = host;
2140 connectPort = port;
2141 } else {
2142 connectHost = proxy.host;
2143 connectPort = proxy.port;
2144 }
2145
2146 // If there are active connections for this key get the first one
2147 // otherwise create a new one.
2148 String key = _connectionKey(connectHost, connectPort);
2149 Queue socketConnections = _openSockets[key];
2150 if (socketConnections == null || socketConnections.isEmpty()) {
2151 Socket socket = new Socket(connectHost, connectPort);
2152 // Until the connection is established handle connection errors
2153 // here as the HttpClientConnection object is not yet associated
2154 // with the socket.
2155 socket.onError = (e) {
2156 proxyIndex++;
2157 if (proxyIndex < proxyConfiguration.proxies.length) {
2158 // Try the next proxy in the list.
2159 _establishConnection(host, port, proxyConfiguration, proxyIndex);
2160 } else {
2161 // Report the error through the HttpClientConnection object to
2162 // the client.
2163 connection._onError(e);
2164 }
2165 };
2166 socket.onConnect = () {
2167 // When the connection is established, clear the error
2168 // callback as it will now be handled by the
2169 // HttpClientConnection object which will be associated with
2170 // the connected socket.
2171 socket.onError = null;
2172 _SocketConnection socketConn =
2173 new _SocketConnection(connectHost, connectPort, socket);
2174 _activeSockets.add(socketConn);
2175 _connectionOpened(socketConn, connection, !proxy.isDirect);
2176 };
2177 } else {
2178 _SocketConnection socketConn = socketConnections.removeFirst();
2179 _activeSockets.add(socketConn);
2180 new Timer(0, (ignored) =>
2181 _connectionOpened(socketConn, connection, !proxy.isDirect));
2182
2183 // Get rid of eviction timer if there are no more active connections.
2184 if (socketConnections.isEmpty()) _openSockets.remove(key);
2185 if (_openSockets.isEmpty()) _cancelEvictionTimer();
2186 }
2187 }
2188
2189 // Find the TCP host and port.
2112 String host = url.domain; 2190 String host = url.domain;
2113 int port = url.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : url.port; 2191 int port = url.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : url.port;
2114 2192
2115 void _connectionOpened(_SocketConnection socketConn, 2193 // Create a new connection object if we are not re-using an existing one.
2116 _HttpClientConnection connection,
2117 bool usingProxy) {
2118 connection._usingProxy = usingProxy;
2119 connection._connectionEstablished(socketConn);
2120 HttpClientRequest request = connection.open(method, url);
2121 request.headers.host = host;
2122 request.headers.port = port;
2123 if (connection._onRequest != null) {
2124 connection._onRequest(request);
2125 } else {
2126 request.outputStream.close();
2127 }
2128 }
2129
2130 // Create a new connection if we are not re-using an existing one.
2131 if (connection == null) { 2194 if (connection == null) {
2132 connection = new _HttpClientConnection(this); 2195 connection = new _HttpClientConnection(this);
2133 } 2196 }
2134 connection.onDetach = () => _activeSockets.remove(connection._socketConn); 2197 connection.onDetach = () => _activeSockets.remove(connection._socketConn);
2135 2198
2136 // Check to see if a proxy server should be used for this connection. 2199 // Check to see if a proxy server should be used for this connection.
2137 _ProxyConfiguration proxyConfiguration = const _ProxyConfiguration.direct(); 2200 _ProxyConfiguration proxyConfiguration = const _ProxyConfiguration.direct();
2138 if (_findProxy != null) { 2201 if (_findProxy != null) {
2139 // TODO(sgjesse): Keep a map of these as normally only a few 2202 // TODO(sgjesse): Keep a map of these as normally only a few
2140 // configuration strings will be used. 2203 // configuration strings will be used.
2141 proxyConfiguration = new _ProxyConfiguration(_findProxy(url)); 2204 proxyConfiguration = new _ProxyConfiguration(_findProxy(url));
2142 } 2205 }
2143 2206
2144 // Determine the actual host to connect to. 2207 // Establish the connection starting with the first proxy configured.
2145 String connectHost; 2208 _establishConnection(host, port, proxyConfiguration, 0);
2146 int connectPort;
2147 _Proxy proxy = proxyConfiguration.proxies[0];
2148 if (proxy.isDirect) {
2149 connectHost = host;
2150 connectPort = port;
2151 } else {
2152 connectHost = proxy.host;
2153 connectPort = proxy.port;
2154 }
2155
2156 // If there are active connections for this key get the first one
2157 // otherwise create a new one.
2158 String key = _connectionKey(connectHost, connectPort);
2159 Queue socketConnections = _openSockets[key];
2160 if (socketConnections == null || socketConnections.isEmpty()) {
2161 Socket socket = new Socket(connectHost, connectPort);
2162 // Until the connection is established handle connection errors
2163 // here as the HttpClientConnection object is not yet associated
2164 // with the socket.
2165 socket.onError = (e) {
2166 // Report the error through the HttpClientConnection object to
2167 // the client.
2168 connection._onError(e);
2169 };
2170 socket.onConnect = () {
2171 // When the connection is established, clear the error
2172 // callback as it will now be handled by the
2173 // HttpClientConnection object which will be associated with
2174 // the connected socket.
2175 socket.onError = null;
2176 _SocketConnection socketConn =
2177 new _SocketConnection(connectHost, connectPort, socket);
2178 _activeSockets.add(socketConn);
2179 _connectionOpened(socketConn, connection, !proxy.isDirect);
2180 };
2181 } else {
2182 _SocketConnection socketConn = socketConnections.removeFirst();
2183 _activeSockets.add(socketConn);
2184 new Timer(0, (ignored) =>
2185 _connectionOpened(socketConn, connection, !proxy.isDirect));
2186
2187 // Get rid of eviction timer if there are no more active connections.
2188 if (socketConnections.isEmpty()) _openSockets.remove(key);
2189 if (_openSockets.isEmpty()) _cancelEvictionTimer();
2190 }
2191 2209
2192 return connection; 2210 return connection;
2193 } 2211 }
2194 2212
2195 void _returnSocketConnection(_SocketConnection socketConn) { 2213 void _returnSocketConnection(_SocketConnection socketConn) {
2196 // Mark socket as returned to unregister from the old connection. 2214 // Mark socket as returned to unregister from the old connection.
2197 socketConn._markReturned(); 2215 socketConn._markReturned();
2198 2216
2199 // If the HTTP client is beeing shutdown don't return the connection. 2217 // If the HTTP client is beeing shutdown don't return the connection.
2200 if (_shutdown) { 2218 if (_shutdown) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2273 2291
2274 2292
2275 class _RedirectInfo implements RedirectInfo { 2293 class _RedirectInfo implements RedirectInfo {
2276 const _RedirectInfo(int this.statusCode, 2294 const _RedirectInfo(int this.statusCode,
2277 String this.method, 2295 String this.method,
2278 Uri this.location); 2296 Uri this.location);
2279 final int statusCode; 2297 final int statusCode;
2280 final String method; 2298 final String method;
2281 final Uri location; 2299 final Uri location;
2282 } 2300 }
OLDNEW
« no previous file with comments | « no previous file | tests/standalone/io/http_proxy_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698