| 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 // The close queue handles graceful closing of HTTP connections. When | 5 // The close queue handles graceful closing of HTTP connections. When |
| 6 // a connection is added to the queue it will enter a wait state | 6 // a connection is added to the queue it will enter a wait state |
| 7 // waiting for all data written and possibly socket shutdown from | 7 // waiting for all data written and possibly socket shutdown from |
| 8 // peer. | 8 // peer. |
| 9 class _CloseQueue { | 9 class _CloseQueue { |
| 10 _CloseQueue() : _q = new Set<_HttpConnectionBase>(); | 10 _CloseQueue() : _q = new Set<_HttpConnectionBase>(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 // the queue. | 25 // the queue. |
| 26 if (connection._isFullyClosed) { | 26 if (connection._isFullyClosed) { |
| 27 connection._socket.close(); | 27 connection._socket.close(); |
| 28 if (connection.onClosed != null) connection.onClosed(); | 28 if (connection.onClosed != null) connection.onClosed(); |
| 29 return; | 29 return; |
| 30 } | 30 } |
| 31 | 31 |
| 32 connection._state |= _HttpConnectionBase.CLOSING; | 32 connection._state |= _HttpConnectionBase.CLOSING; |
| 33 _q.add(connection); | 33 _q.add(connection); |
| 34 | 34 |
| 35 // If output stream is not closed for writing close it now and | 35 // If the output stream is not closed for writing, close it now and |
| 36 // wait for callback when closed. | 36 // wait for callback when closed. |
| 37 if (!connection._isWriteClosed) { | 37 if (!connection._isWriteClosed) { |
| 38 connection._socket.outputStream.close(); | 38 connection._socket.outputStream.close(); |
| 39 connection._socket.outputStream.onClosed = () { | 39 connection._socket.outputStream.onClosed = () { |
| 40 connection._state |= _HttpConnectionBase.WRITE_CLOSED; | 40 connection._state |= _HttpConnectionBase.WRITE_CLOSED; |
| 41 closeIfDone(); | 41 closeIfDone(); |
| 42 }; | 42 }; |
| 43 } else { | 43 } else { |
| 44 connection._socket.outputStream.onClosed = () { assert(false); }; | 44 connection._socket.outputStream.onClosed = () { assert(false); }; |
| 45 } | 45 } |
| 46 | 46 |
| 47 // If socket is not closed for reading wait for callback. | 47 // If the request is not already fully read wait for the socket to close. |
| 48 // As the _isReadClosed state from the HTTP request processing indicate |
| 49 // that the response has been parsed this does not necesarily mean tha |
| 50 // the socket is closed. |
| 48 if (!connection._isReadClosed) { | 51 if (!connection._isReadClosed) { |
| 49 connection._socket.onClosed = () { | 52 connection._socket.onClosed = () { |
| 50 connection._state |= _HttpConnectionBase.READ_CLOSED; | 53 connection._state |= _HttpConnectionBase.READ_CLOSED; |
| 51 closeIfDone(); | 54 closeIfDone(); |
| 52 }; | 55 }; |
| 53 } else { | |
| 54 connection._socket.onClosed = () { assert(false); }; | |
| 55 } | 56 } |
| 56 | 57 |
| 57 // Ignore any data on a socket in the close queue. | 58 // Ignore any data on a socket in the close queue. |
| 58 connection._socket.onData = connection._socket.read; | 59 connection._socket.onData = connection._socket.read; |
| 59 | 60 |
| 60 // If an error occurs immediately close the socket. | 61 // If an error occurs immediately close the socket. |
| 61 connection._socket.onError = (e) { | 62 connection._socket.onError = (e) { |
| 62 connection._state |= _HttpConnectionBase.READ_CLOSED; | 63 connection._state |= _HttpConnectionBase.READ_CLOSED; |
| 63 connection._state |= _HttpConnectionBase.WRITE_CLOSED; | 64 connection._state |= _HttpConnectionBase.WRITE_CLOSED; |
| 64 closeIfDone(); | 65 closeIfDone(); |
| (...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 // If we are done writing the response, and the connection is | 932 // If we are done writing the response, and the connection is |
| 932 // not persistent, we must close. Also if using HTTP 1.0 and the | 933 // not persistent, we must close. Also if using HTTP 1.0 and the |
| 933 // content length was not known we must close to indicate end of | 934 // content length was not known we must close to indicate end of |
| 934 // body. | 935 // body. |
| 935 bool close = | 936 bool close = |
| 936 !_response.persistentConnection || | 937 !_response.persistentConnection || |
| 937 (_response._protocolVersion == "1.0" && _response._contentLength < 0); | 938 (_response._protocolVersion == "1.0" && _response._contentLength < 0); |
| 938 _request = null; | 939 _request = null; |
| 939 _response = null; | 940 _response = null; |
| 940 if (close) { | 941 if (close) { |
| 942 _httpParser.cancel(); |
| 941 _server._closeQueue.add(this); | 943 _server._closeQueue.add(this); |
| 942 } else { | 944 } else { |
| 943 _state = _HttpConnectionBase.IDLE; | 945 _state = _HttpConnectionBase.IDLE; |
| 944 } | 946 } |
| 945 } else if (_isResponseDone && _hasBody) { | 947 } else if (_isResponseDone && _hasBody) { |
| 946 // If the response is closed before the request is fully read | 948 // If the response is closed before the request is fully read |
| 947 // close this connection. If there is buffered output | 949 // close this connection. If there is buffered output |
| 948 // (e.g. error response for invalid request where the server did | 950 // (e.g. error response for invalid request where the server did |
| 949 // not care to read the request body) this is send. | 951 // not care to read the request body) this is send. |
| 950 assert(!_isRequestDone); | 952 assert(!_isRequestDone); |
| 951 _writeBufferedResponse(); | 953 _writeBufferedResponse(); |
| 952 _close(); | 954 _httpParser.cancel(); |
| 953 _server._closeQueue.add(this); | 955 _server._closeQueue.add(this); |
| 954 } | 956 } |
| 955 } | 957 } |
| 956 | 958 |
| 957 void _onDataEnd(bool close) { | 959 void _onDataEnd(bool close) { |
| 958 // Start sending queued response if any. | 960 // Start sending queued response if any. |
| 959 _state |= _HttpConnectionBase.REQUEST_DONE; | 961 _state |= _HttpConnectionBase.REQUEST_DONE; |
| 960 _writeBufferedResponse(); | 962 _writeBufferedResponse(); |
| 961 _request._onDataEnd(); | 963 _request._onDataEnd(); |
| 962 _checkDone(); | 964 _checkDone(); |
| (...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 | 2326 |
| 2325 | 2327 |
| 2326 class _RedirectInfo implements RedirectInfo { | 2328 class _RedirectInfo implements RedirectInfo { |
| 2327 const _RedirectInfo(int this.statusCode, | 2329 const _RedirectInfo(int this.statusCode, |
| 2328 String this.method, | 2330 String this.method, |
| 2329 Uri this.location); | 2331 Uri this.location); |
| 2330 final int statusCode; | 2332 final int statusCode; |
| 2331 final String method; | 2333 final String method; |
| 2332 final Uri location; | 2334 final Uri location; |
| 2333 } | 2335 } |
| OLD | NEW |