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 2020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 static const String PROXY_PREFIX = "PROXY "; | 2031 static const String PROXY_PREFIX = "PROXY "; |
2032 static const String DIRECT_PREFIX = "DIRECT"; | 2032 static const String DIRECT_PREFIX = "DIRECT"; |
2033 | 2033 |
2034 _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() { | 2034 _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() { |
2035 if (configuration == null) { | 2035 if (configuration == null) { |
2036 throw new HttpException("Invalid proxy configuration $configuration"); | 2036 throw new HttpException("Invalid proxy configuration $configuration"); |
2037 } | 2037 } |
2038 List<String> list = configuration.split(";"); | 2038 List<String> list = configuration.split(";"); |
2039 list.forEach((String proxy) { | 2039 list.forEach((String proxy) { |
2040 proxy = proxy.trim(); | 2040 proxy = proxy.trim(); |
2041 if (!proxy.isEmpty()) { | 2041 if (!proxy.isEmpty) { |
2042 if (proxy.startsWith(PROXY_PREFIX)) { | 2042 if (proxy.startsWith(PROXY_PREFIX)) { |
2043 int colon = proxy.indexOf(":"); | 2043 int colon = proxy.indexOf(":"); |
2044 if (colon == -1 || colon == 0 || colon == proxy.length - 1) { | 2044 if (colon == -1 || colon == 0 || colon == proxy.length - 1) { |
2045 throw new HttpException( | 2045 throw new HttpException( |
2046 "Invalid proxy configuration $configuration"); | 2046 "Invalid proxy configuration $configuration"); |
2047 } | 2047 } |
2048 // Skip the "PROXY " prefix. | 2048 // Skip the "PROXY " prefix. |
2049 String host = proxy.substring(PROXY_PREFIX.length, colon).trim(); | 2049 String host = proxy.substring(PROXY_PREFIX.length, colon).trim(); |
2050 String portString = proxy.substring(colon + 1).trim(); | 2050 String portString = proxy.substring(colon + 1).trim(); |
2051 int port; | 2051 int port; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2093 // TODO(sgjesse): The path set here can contain both query and | 2093 // TODO(sgjesse): The path set here can contain both query and |
2094 // fragment. They should be cracked and set correctly. | 2094 // fragment. They should be cracked and set correctly. |
2095 return _open(method, new Uri.fromComponents( | 2095 return _open(method, new Uri.fromComponents( |
2096 scheme: "http", domain: host, port: port, path: path)); | 2096 scheme: "http", domain: host, port: port, path: path)); |
2097 } | 2097 } |
2098 | 2098 |
2099 HttpClientConnection _open(String method, | 2099 HttpClientConnection _open(String method, |
2100 Uri uri, | 2100 Uri uri, |
2101 [_HttpClientConnection connection]) { | 2101 [_HttpClientConnection connection]) { |
2102 if (_shutdown) throw new HttpException("HttpClient shutdown"); | 2102 if (_shutdown) throw new HttpException("HttpClient shutdown"); |
2103 if (method == null || uri.domain.isEmpty()) { | 2103 if (method == null || uri.domain.isEmpty) { |
2104 throw new ArgumentError(null); | 2104 throw new ArgumentError(null); |
2105 } | 2105 } |
2106 return _prepareHttpClientConnection(method, uri, connection); | 2106 return _prepareHttpClientConnection(method, uri, connection); |
2107 } | 2107 } |
2108 | 2108 |
2109 HttpClientConnection openUrl(String method, Uri url) { | 2109 HttpClientConnection openUrl(String method, Uri url) { |
2110 return _openUrl(method, url); | 2110 return _openUrl(method, url); |
2111 } | 2111 } |
2112 | 2112 |
2113 HttpClientConnection _openUrl(String method, | 2113 HttpClientConnection _openUrl(String method, |
(...skipping 17 matching lines...) Expand all Loading... |
2131 HttpClientConnection post(String host, int port, String path) { | 2131 HttpClientConnection post(String host, int port, String path) { |
2132 return open("POST", host, port, path); | 2132 return open("POST", host, port, path); |
2133 } | 2133 } |
2134 | 2134 |
2135 HttpClientConnection postUrl(Uri url) => _openUrl("POST", url); | 2135 HttpClientConnection postUrl(Uri url) => _openUrl("POST", url); |
2136 | 2136 |
2137 set findProxy(String f(Uri uri)) => _findProxy = f; | 2137 set findProxy(String f(Uri uri)) => _findProxy = f; |
2138 | 2138 |
2139 void shutdown() { | 2139 void shutdown() { |
2140 _openSockets.forEach((String key, Queue<_SocketConnection> connections) { | 2140 _openSockets.forEach((String key, Queue<_SocketConnection> connections) { |
2141 while (!connections.isEmpty()) { | 2141 while (!connections.isEmpty) { |
2142 _SocketConnection socketConn = connections.removeFirst(); | 2142 _SocketConnection socketConn = connections.removeFirst(); |
2143 socketConn._socket.close(); | 2143 socketConn._socket.close(); |
2144 } | 2144 } |
2145 }); | 2145 }); |
2146 _activeSockets.forEach((_SocketConnection socketConn) { | 2146 _activeSockets.forEach((_SocketConnection socketConn) { |
2147 socketConn._socket.close(); | 2147 socketConn._socket.close(); |
2148 }); | 2148 }); |
2149 if (_evictionTimer != null) _cancelEvictionTimer(); | 2149 if (_evictionTimer != null) _cancelEvictionTimer(); |
2150 _shutdown = true; | 2150 _shutdown = true; |
2151 } | 2151 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 connectPort = port; | 2195 connectPort = port; |
2196 } else { | 2196 } else { |
2197 connectHost = proxy.host; | 2197 connectHost = proxy.host; |
2198 connectPort = proxy.port; | 2198 connectPort = proxy.port; |
2199 } | 2199 } |
2200 | 2200 |
2201 // If there are active connections for this key get the first one | 2201 // If there are active connections for this key get the first one |
2202 // otherwise create a new one. | 2202 // otherwise create a new one. |
2203 String key = _connectionKey(connectHost, connectPort); | 2203 String key = _connectionKey(connectHost, connectPort); |
2204 Queue socketConnections = _openSockets[key]; | 2204 Queue socketConnections = _openSockets[key]; |
2205 if (socketConnections == null || socketConnections.isEmpty()) { | 2205 if (socketConnections == null || socketConnections.isEmpty) { |
2206 Socket socket = new Socket(connectHost, connectPort); | 2206 Socket socket = new Socket(connectHost, connectPort); |
2207 // Until the connection is established handle connection errors | 2207 // Until the connection is established handle connection errors |
2208 // here as the HttpClientConnection object is not yet associated | 2208 // here as the HttpClientConnection object is not yet associated |
2209 // with the socket. | 2209 // with the socket. |
2210 socket.onError = (e) { | 2210 socket.onError = (e) { |
2211 proxyIndex++; | 2211 proxyIndex++; |
2212 if (proxyIndex < proxyConfiguration.proxies.length) { | 2212 if (proxyIndex < proxyConfiguration.proxies.length) { |
2213 // Try the next proxy in the list. | 2213 // Try the next proxy in the list. |
2214 _establishConnection(host, port, proxyConfiguration, proxyIndex); | 2214 _establishConnection(host, port, proxyConfiguration, proxyIndex); |
2215 } else { | 2215 } else { |
(...skipping 13 matching lines...) Expand all Loading... |
2229 _activeSockets.add(socketConn); | 2229 _activeSockets.add(socketConn); |
2230 _connectionOpened(socketConn, connection, !proxy.isDirect); | 2230 _connectionOpened(socketConn, connection, !proxy.isDirect); |
2231 }; | 2231 }; |
2232 } else { | 2232 } else { |
2233 _SocketConnection socketConn = socketConnections.removeFirst(); | 2233 _SocketConnection socketConn = socketConnections.removeFirst(); |
2234 _activeSockets.add(socketConn); | 2234 _activeSockets.add(socketConn); |
2235 new Timer(0, (ignored) => | 2235 new Timer(0, (ignored) => |
2236 _connectionOpened(socketConn, connection, !proxy.isDirect)); | 2236 _connectionOpened(socketConn, connection, !proxy.isDirect)); |
2237 | 2237 |
2238 // Get rid of eviction timer if there are no more active connections. | 2238 // Get rid of eviction timer if there are no more active connections. |
2239 if (socketConnections.isEmpty()) _openSockets.remove(key); | 2239 if (socketConnections.isEmpty) _openSockets.remove(key); |
2240 if (_openSockets.isEmpty()) _cancelEvictionTimer(); | 2240 if (_openSockets.isEmpty) _cancelEvictionTimer(); |
2241 } | 2241 } |
2242 } | 2242 } |
2243 | 2243 |
2244 // Find the TCP host and port. | 2244 // Find the TCP host and port. |
2245 String host = url.domain; | 2245 String host = url.domain; |
2246 int port = url.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : url.port; | 2246 int port = url.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : url.port; |
2247 | 2247 |
2248 // Create a new connection object if we are not re-using an existing one. | 2248 // Create a new connection object if we are not re-using an existing one. |
2249 if (connection == null) { | 2249 if (connection == null) { |
2250 connection = new _HttpClientConnection(this); | 2250 connection = new _HttpClientConnection(this); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2286 | 2286 |
2287 // If there is currently no eviction timer start one. | 2287 // If there is currently no eviction timer start one. |
2288 if (_evictionTimer == null) { | 2288 if (_evictionTimer == null) { |
2289 void _handleEviction(Timer timer) { | 2289 void _handleEviction(Timer timer) { |
2290 Date now = new Date.now(); | 2290 Date now = new Date.now(); |
2291 List<String> emptyKeys = new List<String>(); | 2291 List<String> emptyKeys = new List<String>(); |
2292 _openSockets.forEach( | 2292 _openSockets.forEach( |
2293 void _(String key, Queue<_SocketConnection> connections) { | 2293 void _(String key, Queue<_SocketConnection> connections) { |
2294 // As returned connections are added at the head of the | 2294 // As returned connections are added at the head of the |
2295 // list remove from the tail. | 2295 // list remove from the tail. |
2296 while (!connections.isEmpty()) { | 2296 while (!connections.isEmpty) { |
2297 _SocketConnection socketConn = connections.last(); | 2297 _SocketConnection socketConn = connections.last(); |
2298 if (socketConn._idleTime(now).inMilliseconds > | 2298 if (socketConn._idleTime(now).inMilliseconds > |
2299 DEFAULT_EVICTION_TIMEOUT) { | 2299 DEFAULT_EVICTION_TIMEOUT) { |
2300 connections.removeLast(); | 2300 connections.removeLast(); |
2301 socketConn._socket.close(); | 2301 socketConn._socket.close(); |
2302 if (connections.isEmpty()) emptyKeys.add(key); | 2302 if (connections.isEmpty) emptyKeys.add(key); |
2303 } else { | 2303 } else { |
2304 break; | 2304 break; |
2305 } | 2305 } |
2306 } | 2306 } |
2307 }); | 2307 }); |
2308 | 2308 |
2309 // Remove the keys for which here are no more open connections. | 2309 // Remove the keys for which here are no more open connections. |
2310 emptyKeys.forEach((String key) => _openSockets.remove(key)); | 2310 emptyKeys.forEach((String key) => _openSockets.remove(key)); |
2311 | 2311 |
2312 // If all connections where evicted cancel the eviction timer. | 2312 // If all connections where evicted cancel the eviction timer. |
2313 if (_openSockets.isEmpty()) _cancelEvictionTimer(); | 2313 if (_openSockets.isEmpty) _cancelEvictionTimer(); |
2314 } | 2314 } |
2315 _evictionTimer = new Timer.repeating(10000, _handleEviction); | 2315 _evictionTimer = new Timer.repeating(10000, _handleEviction); |
2316 } | 2316 } |
2317 | 2317 |
2318 // Return connection. | 2318 // Return connection. |
2319 _activeSockets.remove(socketConn); | 2319 _activeSockets.remove(socketConn); |
2320 sockets.addFirst(socketConn); | 2320 sockets.addFirst(socketConn); |
2321 } | 2321 } |
2322 | 2322 |
2323 Function _onOpen; | 2323 Function _onOpen; |
(...skipping 22 matching lines...) Expand all Loading... |
2346 | 2346 |
2347 | 2347 |
2348 class _RedirectInfo implements RedirectInfo { | 2348 class _RedirectInfo implements RedirectInfo { |
2349 const _RedirectInfo(int this.statusCode, | 2349 const _RedirectInfo(int this.statusCode, |
2350 String this.method, | 2350 String this.method, |
2351 Uri this.location); | 2351 Uri this.location); |
2352 final int statusCode; | 2352 final int statusCode; |
2353 final String method; | 2353 final String method; |
2354 final Uri location; | 2354 final Uri location; |
2355 } | 2355 } |
OLD | NEW |