| Index: sdk/lib/io/http_impl.dart
|
| diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
|
| index b586f0974463c417c159ace7a534484078e05322..42b8d6f80b16130378023831ef41427c87eaa0f6 100644
|
| --- a/sdk/lib/io/http_impl.dart
|
| +++ b/sdk/lib/io/http_impl.dart
|
| @@ -538,11 +538,11 @@ abstract class _HttpOutboundMessage<T> implements IOSink {
|
| headers.chunkedTransferEncoding = false;
|
| headers.contentLength = 0;
|
| } else if (!_ignoreBody && headers.contentLength > 0) {
|
| - _headersSink.close().catchError((_) {});
|
| - return new Future.error(new HttpException(
|
| + _headersSink.addError(new HttpException(
|
| "No content while contentLength was specified to be greater "
|
| - " than 0: ${headers.contentLength}.",
|
| + "than 0: ${headers.contentLength}.",
|
| uri: _uri));
|
| + return _headersSink.done;
|
| }
|
| }
|
| return _writeHeaders().then((_) => _headersSink.close());
|
| @@ -620,11 +620,9 @@ class _HttpOutboundConsumer implements StreamConsumer {
|
| }
|
| _completer = new Completer();
|
| _subscription = stream.listen(
|
| - (data) {
|
| - _controller.add(data);
|
| - },
|
| + (data) => _controller.add(data),
|
| onDone: _done,
|
| - onError: _done,
|
| + onError: (e, s) => _controller.addError(e, s),
|
| cancelOnError: true);
|
| // Pause the first request.
|
| if (_controller == null) _subscription.pause();
|
| @@ -1878,7 +1876,9 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> {
|
| if (_state == _DETACHED) return;
|
| if (response.persistentConnection &&
|
| request.persistentConnection &&
|
| - incoming.fullBodyRead) {
|
| + incoming.fullBodyRead &&
|
| + !_httpParser.upgrade &&
|
| + !_httpServer.closed) {
|
| _state = _IDLE;
|
| _startTimeout();
|
| // Resume the subscription for incoming requests as the
|
| @@ -2007,7 +2007,7 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
|
| cancelOnError: cancelOnError);
|
| }
|
|
|
| - Future close() {
|
| + Future close({bool force: false}) {
|
| closed = true;
|
| Future result;
|
| if (_serverSocket != null && _closeServer) {
|
| @@ -2015,15 +2015,27 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
|
| } else {
|
| result = new Future.value();
|
| }
|
| - if (_sessionManagerInstance != null) {
|
| + if (force) {
|
| + for (var c in _connections.toList()) {
|
| + c.destroy();
|
| + }
|
| + assert(_connections.isEmpty);
|
| + } else {
|
| + for (var c in _connections.where((c) => c._isIdle).toList()) {
|
| + c.destroy();
|
| + }
|
| + }
|
| + _maybeCloseSessionManager();
|
| + return result;
|
| + }
|
| +
|
| + void _maybeCloseSessionManager() {
|
| + if (closed &&
|
| + _connections.isEmpty &&
|
| + _sessionManagerInstance != null) {
|
| _sessionManagerInstance.close();
|
| _sessionManagerInstance = null;
|
| }
|
| - for (_HttpConnection connection in _connections.toList()) {
|
| - connection.destroy();
|
| - }
|
| - _connections.clear();
|
| - return result;
|
| }
|
|
|
| int get port {
|
| @@ -2050,6 +2062,7 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
|
|
|
| void _connectionClosed(_HttpConnection connection) {
|
| _connections.remove(connection);
|
| + _maybeCloseSessionManager();
|
| }
|
|
|
| _HttpSessionManager get _sessionManager {
|
| @@ -2176,7 +2189,7 @@ class _HttpConnectionInfo implements HttpConnectionInfo {
|
| static _HttpConnectionInfo create(Socket socket) {
|
| if (socket == null) return null;
|
| try {
|
| - _HttpConnectionInfo info = new _HttpConnectionInfo._();
|
| + _HttpConnectionInfo info = new _HttpConnectionInfo();
|
| info.remoteHost = socket.remoteHost;
|
| info.remotePort = socket.remotePort;
|
| info.localPort = socket.port;
|
| @@ -2185,8 +2198,6 @@ class _HttpConnectionInfo implements HttpConnectionInfo {
|
| return null;
|
| }
|
|
|
| - _HttpConnectionInfo._();
|
| -
|
| String remoteHost;
|
| int remotePort;
|
| int localPort;
|
|
|