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 |