| 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 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 } | 460 } |
| 461 | 461 |
| 462 OutputStream get outputStream() { | 462 OutputStream get outputStream() { |
| 463 if (_state >= DONE) throw new HttpException("Response closed"); | 463 if (_state >= DONE) throw new HttpException("Response closed"); |
| 464 if (_outputStream == null) { | 464 if (_outputStream == null) { |
| 465 _outputStream = new _HttpOutputStream(this); | 465 _outputStream = new _HttpOutputStream(this); |
| 466 } | 466 } |
| 467 return _outputStream; | 467 return _outputStream; |
| 468 } | 468 } |
| 469 | 469 |
| 470 Socket detachSocket() { | 470 DetachedSocket detachSocket() { |
| 471 if (_state >= DONE) throw new HttpException("Response closed"); | 471 if (_state >= DONE) throw new HttpException("Response closed"); |
| 472 // Ensure that headers are written. | 472 // Ensure that headers are written. |
| 473 if (_state == START) { | 473 if (_state == START) { |
| 474 _writeHeader(); | 474 _writeHeader(); |
| 475 } | 475 } |
| 476 _state = UPGRADED; | 476 _state = UPGRADED; |
| 477 // Ensure that any trailing data is written. | 477 // Ensure that any trailing data is written. |
| 478 _writeDone(); | 478 _writeDone(); |
| 479 // Indicate to the connection that the response handling is done. | 479 // Indicate to the connection that the response handling is done. |
| 480 return _httpConnection._detachSocket(); | 480 return _httpConnection._detachSocket(); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 // Determine the value of the "Connection" header. | 595 // Determine the value of the "Connection" header. |
| 596 if (_protocolVersion == "1.1" && !_persistentConnection) { | 596 if (_protocolVersion == "1.1" && !_persistentConnection) { |
| 597 _headers.set("Connection", "close"); | 597 _headers.set("Connection", "close"); |
| 598 } else if (_protocolVersion == "1.0" && _persistentConnection) { | 598 } else if (_protocolVersion == "1.0" && _persistentConnection) { |
| 599 _headers.set("Connection", "keep-alive"); | 599 _headers.set("Connection", "keep-alive"); |
| 600 } | 600 } |
| 601 // Determine the value of the "Transfer-Encoding" header based on | 601 // Determine the value of the "Transfer-Encoding" header based on |
| 602 // whether the content length is known. | 602 // whether the content length is known. |
| 603 if (_contentLength > 0) { | 603 if (_contentLength > 0) { |
| 604 _headers.set("Content-Length", _contentLength.toString()); | 604 _headers.set("Content-Length", _contentLength.toString()); |
| 605 } else { | 605 } else if (_contentLength < 0) { |
| 606 _headers.set("Transfer-Encoding", "chunked"); | 606 _headers.set("Transfer-Encoding", "chunked"); |
| 607 } | 607 } |
| 608 | 608 |
| 609 // Write headers. | 609 // Write headers. |
| 610 bool allWritten = _writeHeaders(); | 610 bool allWritten = _writeHeaders(); |
| 611 _state = HEADER_SENT; | 611 _state = HEADER_SENT; |
| 612 return allWritten; | 612 return allWritten; |
| 613 } | 613 } |
| 614 | 614 |
| 615 // Response status code. | 615 // Response status code. |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 if (available == 0) { | 738 if (available == 0) { |
| 739 return; | 739 return; |
| 740 } | 740 } |
| 741 | 741 |
| 742 ByteArray buffer = new ByteArray(available); | 742 ByteArray buffer = new ByteArray(available); |
| 743 int bytesRead = _socket.readList(buffer, 0, available); | 743 int bytesRead = _socket.readList(buffer, 0, available); |
| 744 if (bytesRead > 0) { | 744 if (bytesRead > 0) { |
| 745 int parsed = _httpParser.writeList(buffer, 0, bytesRead); | 745 int parsed = _httpParser.writeList(buffer, 0, bytesRead); |
| 746 if (!_httpParser.upgrade) { | 746 if (!_httpParser.upgrade) { |
| 747 if (parsed != bytesRead) { | 747 if (parsed != bytesRead) { |
| 748 // TODO(sgjesse): Error handling. | 748 if (_socket != null) { |
| 749 _close(); | 749 // TODO(sgjesse): Error handling. |
| 750 _close(); |
| 751 } |
| 750 } | 752 } |
| 751 } | 753 } |
| 752 } | 754 } |
| 753 } | 755 } |
| 754 | 756 |
| 755 void _onClosed() { | 757 void _onClosed() { |
| 756 _closing = true; | 758 _closing = true; |
| 757 _onConnectionClosed(null); | 759 _onConnectionClosed(null); |
| 758 } | 760 } |
| 759 | 761 |
| 760 void _onError(e) { | 762 void _onError(e) { |
| 761 // If an error occurs, make sure to close the socket if one is associated. | 763 // If an error occurs, make sure to close the socket if one is associated. |
| 762 _error = true; | 764 _error = true; |
| 763 if (_socket != null) { | 765 if (_socket != null) { |
| 764 _socket.close(); | 766 _socket.close(); |
| 765 } | 767 } |
| 766 _onConnectionClosed(e); | 768 _onConnectionClosed(e); |
| 767 } | 769 } |
| 768 | 770 |
| 769 Socket _detachSocket() { | 771 DetachedSocket _detachSocket() { |
| 770 _socket.onData = null; | 772 _socket.onData = null; |
| 771 // TODO(sgjesse): Handle getting the write handler when using output stream. | |
| 772 //_socket.onWrite = null; | |
| 773 _socket.onClosed = null; | 773 _socket.onClosed = null; |
| 774 _socket.onError = null; | 774 _socket.onError = null; |
| 775 _socket.outputStream.onNoPendingWrites = null; |
| 775 Socket socket = _socket; | 776 Socket socket = _socket; |
| 776 _socket = null; | 777 _socket = null; |
| 777 if (onDetach) onDetach(); | 778 if (onDetach != null) onDetach(); |
| 778 return socket; | 779 return new _DetachedSocket(socket, _httpParser.unparsedData); |
| 779 } | 780 } |
| 780 | 781 |
| 781 abstract void _onConnectionClosed(e); | 782 abstract void _onConnectionClosed(e); |
| 782 abstract void _responseDone(); | 783 abstract void _responseDone(); |
| 783 | 784 |
| 784 void set _onNoPendingWrites(void callback()) { | 785 void set _onNoPendingWrites(void callback()) { |
| 785 if (!_error) { | 786 if (!_error) { |
| 786 _socket.outputStream.onNoPendingWrites = callback; | 787 _socket.outputStream.onNoPendingWrites = callback; |
| 787 } | 788 } |
| 788 } | 789 } |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1224 _socketConn = null; | 1225 _socketConn = null; |
| 1225 } | 1226 } |
| 1226 | 1227 |
| 1227 HttpClientRequest open(String method, String uri) { | 1228 HttpClientRequest open(String method, String uri) { |
| 1228 _method = method; | 1229 _method = method; |
| 1229 _request = new _HttpClientRequest(method, uri, this); | 1230 _request = new _HttpClientRequest(method, uri, this); |
| 1230 _response = new _HttpClientResponse(this); | 1231 _response = new _HttpClientResponse(this); |
| 1231 return _request; | 1232 return _request; |
| 1232 } | 1233 } |
| 1233 | 1234 |
| 1235 DetachedSocket detachSocket() { |
| 1236 return _detachSocket(); |
| 1237 } |
| 1238 |
| 1234 void _onConnectionClosed(e) { | 1239 void _onConnectionClosed(e) { |
| 1235 // Socket is closed either due to an error or due to normal socket close. | 1240 // Socket is closed either due to an error or due to normal socket close. |
| 1236 if (e != null) { | 1241 if (e != null) { |
| 1237 if (_onErrorCallback != null) { | 1242 if (_onErrorCallback != null) { |
| 1238 _onErrorCallback(e); | 1243 _onErrorCallback(e); |
| 1239 } | 1244 } |
| 1240 } | 1245 } |
| 1241 _closing = true; | 1246 _closing = true; |
| 1242 if (e != null) { | 1247 if (e != null) { |
| 1243 // Propagate the error to the streams. | 1248 // Propagate the error to the streams. |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 _activeSockets.remove(socketConn); | 1504 _activeSockets.remove(socketConn); |
| 1500 sockets.addFirst(socketConn); | 1505 sockets.addFirst(socketConn); |
| 1501 } | 1506 } |
| 1502 | 1507 |
| 1503 Function _onOpen; | 1508 Function _onOpen; |
| 1504 Map<String, Queue<_SocketConnection>> _openSockets; | 1509 Map<String, Queue<_SocketConnection>> _openSockets; |
| 1505 Set<_SocketConnection> _activeSockets; | 1510 Set<_SocketConnection> _activeSockets; |
| 1506 Timer _evictionTimer; | 1511 Timer _evictionTimer; |
| 1507 bool _shutdown; // Has this HTTP client been shutdown? | 1512 bool _shutdown; // Has this HTTP client been shutdown? |
| 1508 } | 1513 } |
| 1514 |
| 1515 |
| 1516 class _DetachedSocket implements DetachedSocket { |
| 1517 _DetachedSocket(this._socket, this._unparsedData); |
| 1518 Socket get socket() => _socket; |
| 1519 List<int> get unparsedData() => _unparsedData; |
| 1520 Socket _socket; |
| 1521 List<int> _unparsedData; |
| 1522 } |
| OLD | NEW |