| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |