| 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 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1953 void shutdown() { | 1953 void shutdown() { |
| 1954 _openSockets.forEach((String key, Queue<_SocketConnection> connections) { | 1954 _openSockets.forEach((String key, Queue<_SocketConnection> connections) { |
| 1955 while (!connections.isEmpty()) { | 1955 while (!connections.isEmpty()) { |
| 1956 _SocketConnection socketConn = connections.removeFirst(); | 1956 _SocketConnection socketConn = connections.removeFirst(); |
| 1957 socketConn._socket.close(); | 1957 socketConn._socket.close(); |
| 1958 } | 1958 } |
| 1959 }); | 1959 }); |
| 1960 _activeSockets.forEach((_SocketConnection socketConn) { | 1960 _activeSockets.forEach((_SocketConnection socketConn) { |
| 1961 socketConn._socket.close(); | 1961 socketConn._socket.close(); |
| 1962 }); | 1962 }); |
| 1963 if (_evictionTimer != null) { | 1963 if (_evictionTimer != null) _cancelEvictionTimer(); |
| 1964 _evictionTimer.cancel(); | |
| 1965 } | |
| 1966 _shutdown = true; | 1964 _shutdown = true; |
| 1967 } | 1965 } |
| 1968 | 1966 |
| 1967 void _cancelEvictionTimer() { |
| 1968 _evictionTimer.cancel(); |
| 1969 _evictionTimer = null; |
| 1970 } |
| 1971 |
| 1969 String _connectionKey(String host, int port) { | 1972 String _connectionKey(String host, int port) { |
| 1970 return "$host:$port"; | 1973 return "$host:$port"; |
| 1971 } | 1974 } |
| 1972 | 1975 |
| 1973 HttpClientConnection _prepareHttpClientConnection( | 1976 HttpClientConnection _prepareHttpClientConnection( |
| 1974 String host, | 1977 String host, |
| 1975 int port, | 1978 int port, |
| 1976 String method, | 1979 String method, |
| 1977 String path, | 1980 String path, |
| 1978 [_HttpClientConnection connection]) { | 1981 [_HttpClientConnection connection]) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1991 } | 1994 } |
| 1992 | 1995 |
| 1993 // Create a new connection if we are not re-using an existing one. | 1996 // Create a new connection if we are not re-using an existing one. |
| 1994 if (connection == null) { | 1997 if (connection == null) { |
| 1995 connection = new _HttpClientConnection(this); | 1998 connection = new _HttpClientConnection(this); |
| 1996 } | 1999 } |
| 1997 connection.onDetach = () => _activeSockets.remove(connection._socketConn); | 2000 connection.onDetach = () => _activeSockets.remove(connection._socketConn); |
| 1998 | 2001 |
| 1999 // If there are active connections for this key get the first one | 2002 // If there are active connections for this key get the first one |
| 2000 // otherwise create a new one. | 2003 // otherwise create a new one. |
| 2001 Queue socketConnections = _openSockets[_connectionKey(host, port)]; | 2004 String key = _connectionKey(host, port); |
| 2005 Queue socketConnections = _openSockets[key]; |
| 2002 if (socketConnections == null || socketConnections.isEmpty()) { | 2006 if (socketConnections == null || socketConnections.isEmpty()) { |
| 2003 Socket socket = new Socket(host, port); | 2007 Socket socket = new Socket(host, port); |
| 2004 // Until the connection is established handle connection errors | 2008 // Until the connection is established handle connection errors |
| 2005 // here as the HttpClientConnection object is not yet associated | 2009 // here as the HttpClientConnection object is not yet associated |
| 2006 // with the socket. | 2010 // with the socket. |
| 2007 socket.onError = (e) { | 2011 socket.onError = (e) { |
| 2008 // Report the error through the HttpClientConnection object to | 2012 // Report the error through the HttpClientConnection object to |
| 2009 // the client. | 2013 // the client. |
| 2010 connection._onError(e); | 2014 connection._onError(e); |
| 2011 }; | 2015 }; |
| 2012 socket.onConnect = () { | 2016 socket.onConnect = () { |
| 2013 // When the connection is established, clear the error | 2017 // When the connection is established, clear the error |
| 2014 // callback as it will now be handled by the | 2018 // callback as it will now be handled by the |
| 2015 // HttpClientConnection object which will be associated with | 2019 // HttpClientConnection object which will be associated with |
| 2016 // the connected socket. | 2020 // the connected socket. |
| 2017 socket.onError = null; | 2021 socket.onError = null; |
| 2018 _SocketConnection socketConn = | 2022 _SocketConnection socketConn = |
| 2019 new _SocketConnection(host, port, socket); | 2023 new _SocketConnection(host, port, socket); |
| 2020 _activeSockets.add(socketConn); | 2024 _activeSockets.add(socketConn); |
| 2021 _connectionOpened(socketConn, connection); | 2025 _connectionOpened(socketConn, connection); |
| 2022 }; | 2026 }; |
| 2023 } else { | 2027 } else { |
| 2024 _SocketConnection socketConn = socketConnections.removeFirst(); | 2028 _SocketConnection socketConn = socketConnections.removeFirst(); |
| 2025 _activeSockets.add(socketConn); | 2029 _activeSockets.add(socketConn); |
| 2026 new Timer(0, (ignored) => _connectionOpened(socketConn, connection)); | 2030 new Timer(0, (ignored) => _connectionOpened(socketConn, connection)); |
| 2027 | 2031 |
| 2028 // Get rid of eviction timer if there are no more active connections. | 2032 // Get rid of eviction timer if there are no more active connections. |
| 2029 if (socketConnections.isEmpty()) { | 2033 if (socketConnections.isEmpty()) _openSockets.remove(key); |
| 2030 _evictionTimer.cancel(); | 2034 if (_openSockets.isEmpty()) _cancelEvictionTimer(); |
| 2031 _evictionTimer = null; | |
| 2032 } | |
| 2033 } | 2035 } |
| 2034 | 2036 |
| 2035 return connection; | 2037 return connection; |
| 2036 } | 2038 } |
| 2037 | 2039 |
| 2038 void _returnSocketConnection(_SocketConnection socketConn) { | 2040 void _returnSocketConnection(_SocketConnection socketConn) { |
| 2039 // Mark socket as returned to unregister from the old connection. | 2041 // Mark socket as returned to unregister from the old connection. |
| 2040 socketConn._markReturned(); | 2042 socketConn._markReturned(); |
| 2041 | 2043 |
| 2042 // If the HTTP client is beeing shutdown don't return the connection. | 2044 // If the HTTP client is beeing shutdown don't return the connection. |
| 2043 if (_shutdown) { | 2045 if (_shutdown) { |
| 2044 socketConn._socket.close(); | 2046 socketConn._socket.close(); |
| 2045 return; | 2047 return; |
| 2046 }; | 2048 }; |
| 2047 | 2049 |
| 2048 String key = _connectionKey(socketConn._host, socketConn._port); | 2050 String key = _connectionKey(socketConn._host, socketConn._port); |
| 2049 | 2051 |
| 2050 // Get or create the connection list for this key. | 2052 // Get or create the connection list for this key. |
| 2051 Queue sockets = _openSockets[key]; | 2053 Queue sockets = _openSockets[key]; |
| 2052 if (sockets == null) { | 2054 if (sockets == null) { |
| 2053 sockets = new Queue(); | 2055 sockets = new Queue(); |
| 2054 _openSockets[key] = sockets; | 2056 _openSockets[key] = sockets; |
| 2055 } | 2057 } |
| 2056 | 2058 |
| 2057 // If there is currently no eviction timer start one. | 2059 // If there is currently no eviction timer start one. |
| 2058 if (_evictionTimer == null) { | 2060 if (_evictionTimer == null) { |
| 2059 void _handleEviction(Timer timer) { | 2061 void _handleEviction(Timer timer) { |
| 2060 Date now = new Date.now(); | 2062 Date now = new Date.now(); |
| 2063 List<String> emptyKeys = new List<String>(); |
| 2061 _openSockets.forEach( | 2064 _openSockets.forEach( |
| 2062 void _(String key, Queue<_SocketConnection> connections) { | 2065 void _(String key, Queue<_SocketConnection> connections) { |
| 2063 // As returned connections are added at the head of the | 2066 // As returned connections are added at the head of the |
| 2064 // list remove from the tail. | 2067 // list remove from the tail. |
| 2065 while (!connections.isEmpty()) { | 2068 while (!connections.isEmpty()) { |
| 2066 _SocketConnection socketConn = connections.last(); | 2069 _SocketConnection socketConn = connections.last(); |
| 2067 if (socketConn._idleTime(now).inMilliseconds > | 2070 if (socketConn._idleTime(now).inMilliseconds > |
| 2068 DEFAULT_EVICTION_TIMEOUT) { | 2071 DEFAULT_EVICTION_TIMEOUT) { |
| 2069 connections.removeLast(); | 2072 connections.removeLast(); |
| 2070 socketConn._socket.close(); | 2073 socketConn._socket.close(); |
| 2074 if (connections.isEmpty()) emptyKeys.add(key); |
| 2071 } else { | 2075 } else { |
| 2072 break; | 2076 break; |
| 2073 } | 2077 } |
| 2074 } | 2078 } |
| 2075 }); | 2079 }); |
| 2080 |
| 2081 // Remove the keys for which here are no more open connections. |
| 2082 emptyKeys.forEach((String key) => _openSockets.remove(key)); |
| 2083 |
| 2084 // If all connections where evicted cancel the eviction timer. |
| 2085 if (_openSockets.isEmpty()) _cancelEvictionTimer(); |
| 2076 } | 2086 } |
| 2077 _evictionTimer = new Timer.repeating(10000, _handleEviction); | 2087 _evictionTimer = new Timer.repeating(10000, _handleEviction); |
| 2078 } | 2088 } |
| 2079 | 2089 |
| 2080 // Return connection. | 2090 // Return connection. |
| 2081 _activeSockets.remove(socketConn); | 2091 _activeSockets.remove(socketConn); |
| 2082 sockets.addFirst(socketConn); | 2092 sockets.addFirst(socketConn); |
| 2083 } | 2093 } |
| 2084 | 2094 |
| 2085 Function _onOpen; | 2095 Function _onOpen; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2100 | 2110 |
| 2101 | 2111 |
| 2102 class _RedirectInfo implements RedirectInfo { | 2112 class _RedirectInfo implements RedirectInfo { |
| 2103 const _RedirectInfo(int this.statusCode, | 2113 const _RedirectInfo(int this.statusCode, |
| 2104 String this.method, | 2114 String this.method, |
| 2105 Uri this.location); | 2115 Uri this.location); |
| 2106 final int statusCode; | 2116 final int statusCode; |
| 2107 final String method; | 2117 final String method; |
| 2108 final Uri location; | 2118 final Uri location; |
| 2109 } | 2119 } |
| OLD | NEW |