OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 const int _OUTGOING_BUFFER_SIZE = 8 * 1024; | 7 const int _OUTGOING_BUFFER_SIZE = 8 * 1024; |
8 | 8 |
9 class _HttpIncoming extends Stream<List<int>> { | 9 class _HttpIncoming extends Stream<List<int>> { |
10 final int _transferLength; | 10 final int _transferLength; |
(...skipping 2017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2028 HttpConnectionInfo get connectionInfo => _HttpConnectionInfo.create(_socket); | 2028 HttpConnectionInfo get connectionInfo => _HttpConnectionInfo.create(_socket); |
2029 | 2029 |
2030 bool get _isActive => _state == _ACTIVE; | 2030 bool get _isActive => _state == _ACTIVE; |
2031 bool get _isIdle => _state == _IDLE; | 2031 bool get _isIdle => _state == _IDLE; |
2032 bool get _isClosing => _state == _CLOSING; | 2032 bool get _isClosing => _state == _CLOSING; |
2033 bool get _isDetached => _state == _DETACHED; | 2033 bool get _isDetached => _state == _DETACHED; |
2034 } | 2034 } |
2035 | 2035 |
2036 | 2036 |
2037 // HTTP server waiting for socket connections. | 2037 // HTTP server waiting for socket connections. |
2038 class _HttpServer extends Stream<HttpRequest> implements HttpServer { | 2038 class _HttpServer |
| 2039 extends Stream<HttpRequest> with _ServiceObject |
| 2040 implements HttpServer { |
| 2041 // Use default Map so we keep order. |
| 2042 static Map<int, _HttpServer> _servers = new Map<int, _HttpServer>(); |
| 2043 |
| 2044 final String _serviceTypePath = 'io/http/servers'; |
| 2045 final String _serviceTypeName = 'HttpServer'; |
| 2046 |
2039 String serverHeader; | 2047 String serverHeader; |
2040 | 2048 |
2041 Duration _idleTimeout; | 2049 Duration _idleTimeout; |
2042 Timer _idleTimer; | 2050 Timer _idleTimer; |
2043 | 2051 |
2044 static Future<HttpServer> bind(address, int port, int backlog) { | 2052 static Future<HttpServer> bind(address, int port, int backlog) { |
2045 return ServerSocket.bind(address, port, backlog: backlog).then((socket) { | 2053 return ServerSocket.bind(address, port, backlog: backlog).then((socket) { |
2046 return new _HttpServer._(socket, true); | 2054 return new _HttpServer._(socket, true); |
2047 }); | 2055 }); |
2048 } | 2056 } |
(...skipping 11 matching lines...) Expand all Loading... |
2060 requestClientCertificate: requestClientCertificate) | 2068 requestClientCertificate: requestClientCertificate) |
2061 .then((socket) { | 2069 .then((socket) { |
2062 return new _HttpServer._(socket, true); | 2070 return new _HttpServer._(socket, true); |
2063 }); | 2071 }); |
2064 } | 2072 } |
2065 | 2073 |
2066 _HttpServer._(this._serverSocket, this._closeServer) { | 2074 _HttpServer._(this._serverSocket, this._closeServer) { |
2067 _controller = new StreamController<HttpRequest>(sync: true, | 2075 _controller = new StreamController<HttpRequest>(sync: true, |
2068 onCancel: close); | 2076 onCancel: close); |
2069 idleTimeout = const Duration(seconds: 120); | 2077 idleTimeout = const Duration(seconds: 120); |
| 2078 _servers[_serviceId] = this; |
2070 } | 2079 } |
2071 | 2080 |
2072 _HttpServer.listenOn(this._serverSocket) : _closeServer = false { | 2081 _HttpServer.listenOn(this._serverSocket) : _closeServer = false { |
2073 _controller = new StreamController<HttpRequest>(sync: true, | 2082 _controller = new StreamController<HttpRequest>(sync: true, |
2074 onCancel: close); | 2083 onCancel: close); |
2075 idleTimeout = const Duration(seconds: 120); | 2084 idleTimeout = const Duration(seconds: 120); |
| 2085 _servers[_serviceId] = this; |
2076 } | 2086 } |
2077 | 2087 |
2078 Duration get idleTimeout => _idleTimeout; | 2088 Duration get idleTimeout => _idleTimeout; |
2079 | 2089 |
2080 void set idleTimeout(Duration duration) { | 2090 void set idleTimeout(Duration duration) { |
2081 if (_idleTimer != null) { | 2091 if (_idleTimer != null) { |
2082 _idleTimer.cancel(); | 2092 _idleTimer.cancel(); |
2083 _idleTimer = null; | 2093 _idleTimer = null; |
2084 } | 2094 } |
2085 _idleTimeout = duration; | 2095 _idleTimeout = duration; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2132 idleTimeout = null; | 2142 idleTimeout = null; |
2133 if (force) { | 2143 if (force) { |
2134 for (var c in _activeConnections.toList()) { | 2144 for (var c in _activeConnections.toList()) { |
2135 c.destroy(); | 2145 c.destroy(); |
2136 } | 2146 } |
2137 assert(_activeConnections.isEmpty); | 2147 assert(_activeConnections.isEmpty); |
2138 } | 2148 } |
2139 for (var c in _idleConnections.toList()) { | 2149 for (var c in _idleConnections.toList()) { |
2140 c.destroy(); | 2150 c.destroy(); |
2141 } | 2151 } |
2142 _maybeCloseSessionManager(); | 2152 _maybePerformCleanup(); |
2143 return result; | 2153 return result; |
2144 } | 2154 } |
2145 | 2155 |
2146 void _maybeCloseSessionManager() { | 2156 void _maybePerformCleanup() { |
2147 if (closed && | 2157 if (closed && |
2148 _idleConnections.isEmpty && | 2158 _idleConnections.isEmpty && |
2149 _activeConnections.isEmpty && | 2159 _activeConnections.isEmpty && |
2150 _sessionManagerInstance != null) { | 2160 _sessionManagerInstance != null) { |
2151 _sessionManagerInstance.close(); | 2161 _sessionManagerInstance.close(); |
2152 _sessionManagerInstance = null; | 2162 _sessionManagerInstance = null; |
| 2163 _servers.remove(_serviceId); |
2153 } | 2164 } |
2154 } | 2165 } |
2155 | 2166 |
2156 int get port { | 2167 int get port { |
2157 if (closed) throw new HttpException("HttpServer is not bound to a socket"); | 2168 if (closed) throw new HttpException("HttpServer is not bound to a socket"); |
2158 return _serverSocket.port; | 2169 return _serverSocket.port; |
2159 } | 2170 } |
2160 | 2171 |
2161 InternetAddress get address { | 2172 InternetAddress get address { |
2162 if (closed) throw new HttpException("HttpServer is not bound to a socket"); | 2173 if (closed) throw new HttpException("HttpServer is not bound to a socket"); |
2163 return _serverSocket.address; | 2174 return _serverSocket.address; |
2164 } | 2175 } |
2165 | 2176 |
2166 set sessionTimeout(int timeout) { | 2177 set sessionTimeout(int timeout) { |
2167 _sessionManager.sessionTimeout = timeout; | 2178 _sessionManager.sessionTimeout = timeout; |
2168 } | 2179 } |
2169 | 2180 |
2170 void _handleRequest(HttpRequest request) => _controller.add(request); | 2181 void _handleRequest(HttpRequest request) => _controller.add(request); |
2171 | 2182 |
2172 void _handleError(error) { | 2183 void _handleError(error) { |
2173 if (!closed) _controller.addError(error); | 2184 if (!closed) _controller.addError(error); |
2174 } | 2185 } |
2175 | 2186 |
2176 void _connectionClosed(_HttpConnection connection) { | 2187 void _connectionClosed(_HttpConnection connection) { |
2177 // Remove itself from either idle or active connections. | 2188 // Remove itself from either idle or active connections. |
2178 connection.unlink(); | 2189 connection.unlink(); |
2179 _maybeCloseSessionManager(); | 2190 _maybePerformCleanup(); |
2180 } | 2191 } |
2181 | 2192 |
2182 void _markIdle(_HttpConnection connection) { | 2193 void _markIdle(_HttpConnection connection) { |
2183 _activeConnections.remove(connection); | 2194 _activeConnections.remove(connection); |
2184 _idleConnections.add(connection); | 2195 _idleConnections.add(connection); |
2185 } | 2196 } |
2186 | 2197 |
2187 void _markActive(_HttpConnection connection) { | 2198 void _markActive(_HttpConnection connection) { |
2188 _idleConnections.remove(connection); | 2199 _idleConnections.remove(connection); |
2189 _activeConnections.add(connection); | 2200 _activeConnections.add(connection); |
(...skipping 18 matching lines...) Expand all Loading... |
2208 result.closing++; | 2219 result.closing++; |
2209 } | 2220 } |
2210 }); | 2221 }); |
2211 _idleConnections.forEach((_HttpConnection conn) { | 2222 _idleConnections.forEach((_HttpConnection conn) { |
2212 result.idle++; | 2223 result.idle++; |
2213 assert(conn._isIdle); | 2224 assert(conn._isIdle); |
2214 }); | 2225 }); |
2215 return result; | 2226 return result; |
2216 } | 2227 } |
2217 | 2228 |
| 2229 Map _toJSON(bool ref) { |
| 2230 var r = { |
| 2231 'id': _servicePath, |
| 2232 'type': _serviceType(ref), |
| 2233 'name': '${address.host}:$port', |
| 2234 'user_name': '${address.host}:$port', |
| 2235 }; |
| 2236 if (ref) { |
| 2237 return r; |
| 2238 } |
| 2239 r['port'] = port; |
| 2240 r['address'] = address.host; |
| 2241 r['active'] = _activeConnections.length; |
| 2242 r['idle'] = _idleConnections.length; |
| 2243 r['closed'] = closed; |
| 2244 return r; |
| 2245 } |
| 2246 |
2218 _HttpSessionManager _sessionManagerInstance; | 2247 _HttpSessionManager _sessionManagerInstance; |
2219 | 2248 |
2220 // Indicated if the http server has been closed. | 2249 // Indicated if the http server has been closed. |
2221 bool closed = false; | 2250 bool closed = false; |
2222 | 2251 |
2223 // The server listen socket. Untyped as it can be both ServerSocket and | 2252 // The server listen socket. Untyped as it can be both ServerSocket and |
2224 // SecureServerSocket. | 2253 // SecureServerSocket. |
2225 final _serverSocket; | 2254 final _serverSocket; |
2226 final bool _closeServer; | 2255 final bool _closeServer; |
2227 | 2256 |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2636 const _RedirectInfo(this.statusCode, this.method, this.location); | 2665 const _RedirectInfo(this.statusCode, this.method, this.location); |
2637 } | 2666 } |
2638 | 2667 |
2639 String _getHttpVersion() { | 2668 String _getHttpVersion() { |
2640 var version = Platform.version; | 2669 var version = Platform.version; |
2641 // Only include major and minor version numbers. | 2670 // Only include major and minor version numbers. |
2642 int index = version.indexOf('.', version.indexOf('.') + 1); | 2671 int index = version.indexOf('.', version.indexOf('.') + 1); |
2643 version = version.substring(0, index); | 2672 version = version.substring(0, index); |
2644 return 'Dart/$version (dart:io)'; | 2673 return 'Dart/$version (dart:io)'; |
2645 } | 2674 } |
OLD | NEW |