Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(515)

Side by Side Diff: sdk/lib/io/http_impl.dart

Issue 11453006: Fix a number of HTTP issues (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/io/http_parser.dart » ('j') | sdk/lib/io/secure_socket.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 740 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 _httpParser.streamData(buffer); 751 _httpParser.streamData(buffer);
752 } 752 }
753 }; 753 };
754 _socket.onClosed = _httpParser.streamDone; 754 _socket.onClosed = _httpParser.streamDone;
755 _socket.onError = _httpParser.streamError; 755 _socket.onError = _httpParser.streamError;
756 // Ignore errors in the socket output stream as this is getting 756 // Ignore errors in the socket output stream as this is getting
757 // the same errors as the socket itself. 757 // the same errors as the socket itself.
758 _socket.outputStream.onError = (e) => null; 758 _socket.outputStream.onError = (e) => null;
759 } 759 }
760 760
761 bool _write(List<int> data, [bool copyBuffer = false]) { 761 bool _write(List<int> data, [bool copyBuffer = false]);
762 return _socket.outputStream.write(data, copyBuffer); 762 bool _writeFrom(List<int> buffer, [int offset, int len]);
763 } 763 bool _flush();
764 764 bool _close();
765 bool _writeFrom(List<int> buffer, [int offset, int len]) { 765 bool _destroy();
766 return _socket.outputStream.writeFrom(buffer, offset, len); 766 DetachedSocket _detachSocket();
767 }
768
769 bool _flush() {
770 _socket.outputStream.flush();
771 }
772
773 bool _close() {
774 _socket.outputStream.close();
775 }
776
777 bool _destroy() {
778 _socket.close();
779 }
780
781 DetachedSocket _detachSocket() {
782 _socket.onData = null;
783 _socket.onClosed = null;
784 _socket.onError = null;
785 _socket.outputStream.onNoPendingWrites = null;
786 Socket socket = _socket;
787 _socket = null;
788 if (onDetach != null) onDetach();
789 return new _DetachedSocket(socket, _httpParser.readUnparsedData());
790 }
791 767
792 HttpConnectionInfo get connectionInfo { 768 HttpConnectionInfo get connectionInfo {
793 if (_socket == null) return null; 769 if (_socket == null) return null;
794 try { 770 try {
795 _HttpConnectionInfo info = new _HttpConnectionInfo(); 771 _HttpConnectionInfo info = new _HttpConnectionInfo();
796 info.remoteHost = _socket.remoteHost; 772 info.remoteHost = _socket.remoteHost;
797 info.remotePort = _socket.remotePort; 773 info.remotePort = _socket.remotePort;
798 info.localPort = _socket.port; 774 info.localPort = _socket.port;
799 return info; 775 return info;
800 } catch (e) { } 776 } catch (e) { }
(...skipping 27 matching lines...) Expand all
828 _httpParser.requestStart = _onRequestReceived; 804 _httpParser.requestStart = _onRequestReceived;
829 _httpParser.dataReceived = _onDataReceived; 805 _httpParser.dataReceived = _onDataReceived;
830 _httpParser.dataEnd = _onDataEnd; 806 _httpParser.dataEnd = _onDataEnd;
831 _httpParser.error = _onError; 807 _httpParser.error = _onError;
832 _httpParser.closed = _onClosed; 808 _httpParser.closed = _onClosed;
833 _httpParser.responseStart = (statusCode, reasonPhrase, version) { 809 _httpParser.responseStart = (statusCode, reasonPhrase, version) {
834 assert(false); 810 assert(false);
835 }; 811 };
836 } 812 }
837 813
814 void _bufferData(List<int> data, [bool copyBuffer = false]) {
815 if (_buffer == null) _buffer = new _BufferList();
816 if (copyBuffer) data = data.getRange(0, data.length);
817 _buffer.add(data);
818 }
819
820 void _releaseBuffer() {
Mads Ager (google) 2012/12/05 16:02:18 Maybe name this something like _writeBufferedRespo
Søren Gjesse 2012/12/06 17:23:08 Done.
821 if (_buffer != null) {
822 while (!_buffer.isEmpty) {
823 var data = _buffer.first;
824 _socket.outputStream.write(data, false);
825 _buffer.removeBytes(data.length);
826 }
827 _buffer = null;
828 }
829 }
830
831 bool _write(List<int> data, [bool copyBuffer = false]) {
832 if (_isRequestDone) {
833 return _socket.outputStream.write(data, copyBuffer);
834 } else {
835 _bufferData(data, copyBuffer);
836 return false;
837 }
838 }
839
840 bool _writeFrom(List<int> data, [int offset, int len]) {
841 if (_isRequestDone) {
842 return _socket.outputStream.writeFrom(data, offset, len);
843 } else {
844 if (offset == null) offset = 0;
845 if (len == null) len = buffer.length - offset;
846 _bufferData(data.getRange(offset, len), false);
847 return false;
848 }
849 }
850
851 bool _flush() {
852 _socket.outputStream.flush();
853 }
854
855 bool _close() {
856 _socket.outputStream.close();
857 }
858
859 bool _destroy() {
860 _socket.close();
861 }
862
838 void _onClosed() { 863 void _onClosed() {
839 _state |= _HttpConnectionBase.READ_CLOSED; 864 _state |= _HttpConnectionBase.READ_CLOSED;
840 _checkDone(); 865 _checkDone();
841 } 866 }
842 867
868 DetachedSocket _detachSocket() {
869 _socket.onData = null;
870 _socket.onClosed = null;
871 _socket.onError = null;
872 _socket.outputStream.onNoPendingWrites = null;
873 _releaseBuffer();
874 Socket socket = _socket;
875 _socket = null;
876 if (onDetach != null) onDetach();
877 return new _DetachedSocket(socket, _httpParser.readUnparsedData());
878 }
879
843 void _onError(e) { 880 void _onError(e) {
844 onError(e); 881 onError(e);
845 // Propagate the error to the streams. 882 // Propagate the error to the streams.
846 if (_request != null && _request._streamErrorHandler != null) { 883 if (_request != null && _request._streamErrorHandler != null) {
847 _request._streamErrorHandler(e); 884 _request._streamErrorHandler(e);
848 } 885 }
849 if (_response != null && _response._streamErrorHandler != null) { 886 if (_response != null && _response._streamErrorHandler != null) {
850 _response._streamErrorHandler(e); 887 _response._streamErrorHandler(e);
851 } 888 }
852 if (_socket != null) _socket.close(); 889 if (_socket != null) _socket.close();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 bool close = 923 bool close =
887 !_response.persistentConnection || 924 !_response.persistentConnection ||
888 (_response._protocolVersion == "1.0" && _response._contentLength < 0); 925 (_response._protocolVersion == "1.0" && _response._contentLength < 0);
889 _request = null; 926 _request = null;
890 _response = null; 927 _response = null;
891 if (close) { 928 if (close) {
892 _server._closeQueue.add(this); 929 _server._closeQueue.add(this);
893 } else { 930 } else {
894 _state = _HttpConnectionBase.IDLE; 931 _state = _HttpConnectionBase.IDLE;
895 } 932 }
933 } else if (_isResponseDone) {
934 // If the response is closed before the request is fully read
935 // close this connection. If there is buffered output
936 // (e.g. error response for invalid request where the server did
937 // not care to read the request body) this is send.
938 assert(!_isRequestDone);
939 _releaseBuffer();
940 _close();
941 _server._closeQueue.add(this);
896 } 942 }
897 } 943 }
898 944
899 void _onDataEnd(bool close) { 945 void _onDataEnd(bool close) {
946 // Start sending queued response if any.
947 _releaseBuffer();
948 _state |= _HttpConnectionBase.REQUEST_DONE;
900 _request._onDataEnd(); 949 _request._onDataEnd();
901 _state |= _HttpConnectionBase.REQUEST_DONE;
902 _checkDone();
903 } 950 }
904 951
905 void _responseClosed() { 952 void _responseClosed() {
906 _state |= _HttpConnectionBase.RESPONSE_DONE; 953 _state |= _HttpConnectionBase.RESPONSE_DONE;
907 _checkDone(); 954 _checkDone();
908 } 955 }
909 956
910 HttpServer _server; 957 HttpServer _server;
911 HttpRequest _request; 958 HttpRequest _request;
912 HttpResponse _response; 959 HttpResponse _response;
913 960
961 // Buffer for data written before full response have been processed.
Mads Ager (google) 2012/12/05 16:02:18 have -> has
Søren Gjesse 2012/12/06 17:23:08 Done.
962 _BufferList _buffer;
963
914 // Callbacks. 964 // Callbacks.
915 Function onRequestReceived; 965 Function onRequestReceived;
916 Function onError; 966 Function onError;
917 } 967 }
918 968
919 969
920 class _RequestHandlerRegistration { 970 class _RequestHandlerRegistration {
921 _RequestHandlerRegistration(Function this._matcher, Function this._handler); 971 _RequestHandlerRegistration(Function this._matcher, Function this._handler);
922 Function _matcher; 972 Function _matcher;
923 Function _handler; 973 Function _handler;
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 if (_done) throw new HttpException("Request closed"); 1164 if (_done) throw new HttpException("Request closed");
1115 if (_outputStream == null) { 1165 if (_outputStream == null) {
1116 _outputStream = new _HttpOutputStream(this); 1166 _outputStream = new _HttpOutputStream(this);
1117 } 1167 }
1118 return _outputStream; 1168 return _outputStream;
1119 } 1169 }
1120 1170
1121 // Delegate functions for the HttpOutputStream implementation. 1171 // Delegate functions for the HttpOutputStream implementation.
1122 bool _streamWrite(List<int> buffer, bool copyBuffer) { 1172 bool _streamWrite(List<int> buffer, bool copyBuffer) {
1123 if (_done) throw new HttpException("Request closed"); 1173 if (_done) throw new HttpException("Request closed");
1174 _emptyBody = false;
Mads Ager (google) 2012/12/05 16:02:18 Should this be _emptyBody = buffer.length != 0 |
Søren Gjesse 2012/12/06 17:23:08 Good point, however it should be _emptyBody = buf
1124 return _write(buffer, copyBuffer); 1175 return _write(buffer, copyBuffer);
1125 } 1176 }
1126 1177
1127 bool _streamWriteFrom(List<int> buffer, int offset, int len) { 1178 bool _streamWriteFrom(List<int> buffer, int offset, int len) {
1128 if (_done) throw new HttpException("Request closed"); 1179 if (_done) throw new HttpException("Request closed");
1180 _emptyBody = false;
Mads Ager (google) 2012/12/05 16:02:18 Ditto
Søren Gjesse 2012/12/06 17:23:08 Done.
1129 return _writeList(buffer, offset, len); 1181 return _writeList(buffer, offset, len);
1130 } 1182 }
1131 1183
1132 void _streamFlush() { 1184 void _streamFlush() {
1133 _httpConnection._flush(); 1185 _httpConnection._flush();
1134 } 1186 }
1135 1187
1136 void _streamClose() { 1188 void _streamClose() {
1137 _ensureHeadersSent(); 1189 _ensureHeadersSent();
1138 _state = _HttpRequestResponseBase.DONE; 1190 _state = _HttpRequestResponseBase.DONE;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 // Write headers. 1261 // Write headers.
1210 _writeHeaders(); 1262 _writeHeaders();
1211 _state = _HttpRequestResponseBase.HEADER_SENT; 1263 _state = _HttpRequestResponseBase.HEADER_SENT;
1212 } 1264 }
1213 1265
1214 String _method; 1266 String _method;
1215 Uri _uri; 1267 Uri _uri;
1216 _HttpClientConnection _connection; 1268 _HttpClientConnection _connection;
1217 _HttpOutputStream _outputStream; 1269 _HttpOutputStream _outputStream;
1218 Function _streamErrorHandler; 1270 Function _streamErrorHandler;
1271 bool _emptyBody = true;
1219 } 1272 }
1220 1273
1221 1274
1222 class _HttpClientResponse 1275 class _HttpClientResponse
1223 extends _HttpRequestResponseBase implements HttpClientResponse { 1276 extends _HttpRequestResponseBase implements HttpClientResponse {
1224 _HttpClientResponse(_HttpClientConnection connection) 1277 _HttpClientResponse(_HttpClientConnection connection)
1225 : super(connection) { 1278 : super(connection) {
1226 _connection = connection; 1279 _connection = connection;
1227 } 1280 }
1228 1281
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 } 1470 }
1418 1471
1419 1472
1420 class _HttpClientConnection 1473 class _HttpClientConnection
1421 extends _HttpConnectionBase implements HttpClientConnection { 1474 extends _HttpConnectionBase implements HttpClientConnection {
1422 1475
1423 _HttpClientConnection(_HttpClient this._client) { 1476 _HttpClientConnection(_HttpClient this._client) {
1424 _httpParser = new _HttpParser.responseParser(); 1477 _httpParser = new _HttpParser.responseParser();
1425 } 1478 }
1426 1479
1480 bool _write(List<int> data, [bool copyBuffer = false]) {
1481 return _socket.outputStream.write(data, copyBuffer);
1482 }
1483
1484 bool _writeFrom(List<int> data, [int offset, int len]) {
1485 return _socket.outputStream.writeFrom(data, offset, len);
1486 }
1487
1488 bool _flush() {
1489 _socket.outputStream.flush();
1490 }
1491
1492 bool _close() {
1493 _socket.outputStream.close();
1494 }
1495
1496 bool _destroy() {
1497 _socket.close();
1498 }
1499
1500 DetachedSocket _detachSocket() {
1501 _socket.onData = null;
1502 _socket.onClosed = null;
1503 _socket.onError = null;
1504 _socket.outputStream.onNoPendingWrites = null;
1505 Socket socket = _socket;
1506 _socket = null;
1507 if (onDetach != null) onDetach();
1508 return new _DetachedSocket(socket, _httpParser.readUnparsedData());
1509 }
1510
1427 void _connectionEstablished(_SocketConnection socketConn) { 1511 void _connectionEstablished(_SocketConnection socketConn) {
1428 super._connectionEstablished(socketConn._socket); 1512 super._connectionEstablished(socketConn._socket);
1429 _socketConn = socketConn; 1513 _socketConn = socketConn;
1430 // Register HTTP parser callbacks. 1514 // Register HTTP parser callbacks.
1431 _httpParser.responseStart = _onResponseReceived; 1515 _httpParser.responseStart = _onResponseReceived;
1432 _httpParser.dataReceived = _onDataReceived; 1516 _httpParser.dataReceived = _onDataReceived;
1433 _httpParser.dataEnd = _onDataEnd; 1517 _httpParser.dataEnd = _onDataEnd;
1434 _httpParser.error = _onError; 1518 _httpParser.error = _onError;
1435 _httpParser.closed = _onClosed; 1519 _httpParser.closed = _onClosed;
1436 _httpParser.requestStart = (method, uri, version) { assert(false); }; 1520 _httpParser.requestStart = (method, uri, version) { assert(false); };
(...skipping 28 matching lines...) Expand all
1465 1549
1466 void _requestClosed() { 1550 void _requestClosed() {
1467 _state |= _HttpConnectionBase.REQUEST_DONE; 1551 _state |= _HttpConnectionBase.REQUEST_DONE;
1468 _checkSocketDone(); 1552 _checkSocketDone();
1469 } 1553 }
1470 1554
1471 HttpClientRequest open(String method, Uri uri) { 1555 HttpClientRequest open(String method, Uri uri) {
1472 _method = method; 1556 _method = method;
1473 // Tell the HTTP parser the method it is expecting a response to. 1557 // Tell the HTTP parser the method it is expecting a response to.
1474 _httpParser.responseToMethod = method; 1558 _httpParser.responseToMethod = method;
1475 _request = new _HttpClientRequest(method, uri, this); 1559 // If the connection already have a request this is a retry of a
Mads Ager (google) 2012/12/05 16:02:18 have -> has
Søren Gjesse 2012/12/06 17:23:08 Done.
1560 // request. In this case the request object is reused to ensure
1561 // that the same headers are send.
1562 if (_request != null) {
1563 _request._method = method;
1564 _request._uri = uri;
1565 _request._headers._mutable = true;
1566 _request._state = _HttpRequestResponseBase.START;
1567 } else {
1568 _request = new _HttpClientRequest(method, uri, this);
1569 }
1476 _response = new _HttpClientResponse(this); 1570 _response = new _HttpClientResponse(this);
1477 return _request; 1571 return _request;
1478 } 1572 }
1479 1573
1480 DetachedSocket detachSocket() { 1574 DetachedSocket detachSocket() {
1481 return _detachSocket(); 1575 return _detachSocket();
1482 } 1576 }
1483 1577
1484 void _onClosed() { 1578 void _onClosed() {
1485 _state |= _HttpConnectionBase.READ_CLOSED; 1579 _state |= _HttpConnectionBase.READ_CLOSED;
1486 _checkSocketDone(); 1580 _checkSocketDone();
1487 } 1581 }
1488 1582
1489 void _onError(e) { 1583 void _onError(e) {
1490 // Cancel any pending data in the HTTP parser. 1584 // Cancel any pending data in the HTTP parser.
1491 _httpParser.cancel(); 1585 _httpParser.cancel();
1492 if (_socketConn != null) { 1586 if (_socketConn != null) {
1493 _client._closeSocketConnection(_socketConn); 1587 _client._closeSocketConnection(_socketConn);
1494 } 1588 }
1495 // Report the error. 1589
1496 if (_response != null && _response._streamErrorHandler != null) { 1590 // If it looks as if we got a bad connection from the connection
1497 _response._streamErrorHandler(e); 1591 // pool and the request can be retried do a retry.
1498 } else if (_onErrorCallback != null) { 1592 if (_socketConn != null && _socketConn._fromPool && _request._emptyBody) {
1499 _onErrorCallback(e); 1593 String method = _request._method;
1594 Uri uri = _request._uri;
1595 _socketConn = null;
1596
1597 // Retry the URL using the same connection instance.
1598 _httpParser.restart();
1599 _client._openUrl(method, uri, this);
1500 } else { 1600 } else {
1501 throw e; 1601 // Report the error.
1602 if (_response != null && _response._streamErrorHandler != null) {
1603 _response._streamErrorHandler(e);
1604 } else if (_onErrorCallback != null) {
1605 _onErrorCallback(e);
1606 } else {
1607 throw e;
1608 }
1502 } 1609 }
1503 } 1610 }
1504 1611
1505 void _onResponseReceived(int statusCode, 1612 void _onResponseReceived(int statusCode,
1506 String reasonPhrase, 1613 String reasonPhrase,
1507 String version, 1614 String version,
1508 _HttpHeaders headers) { 1615 _HttpHeaders headers) {
1509 _response._onResponseReceived(statusCode, reasonPhrase, version, headers); 1616 _response._onResponseReceived(statusCode, reasonPhrase, version, headers);
1510 } 1617 }
1511 1618
(...skipping 20 matching lines...) Expand all
1532 void set onResponse(void handler(HttpClientResponse response)) { 1639 void set onResponse(void handler(HttpClientResponse response)) {
1533 _onResponse = handler; 1640 _onResponse = handler;
1534 } 1641 }
1535 1642
1536 void set onError(void callback(e)) { 1643 void set onError(void callback(e)) {
1537 _onErrorCallback = callback; 1644 _onErrorCallback = callback;
1538 } 1645 }
1539 1646
1540 void _doRetry(_RedirectInfo retry) { 1647 void _doRetry(_RedirectInfo retry) {
1541 assert(_socketConn == null); 1648 assert(_socketConn == null);
1542 _request = null;
1543 _response = null;
1544 1649
1545 // Retry the URL using the same connection instance. 1650 // Retry the URL using the same connection instance.
1546 _state = _HttpConnectionBase.IDLE; 1651 _state = _HttpConnectionBase.IDLE;
1547 _client._openUrl(retry.method, retry.location, this); 1652 _client._openUrl(retry.method, retry.location, this);
1548 } 1653 }
1549 1654
1550 void _retry() { 1655 void _retry() {
1551 var retry = new _RedirectInfo(_response.statusCode, _method, _request._uri); 1656 var retry = new _RedirectInfo(_response.statusCode, _method, _request._uri);
1552 // The actual retry is postponed until both response and request 1657 // The actual retry is postponed until both response and request
1553 // are done. 1658 // are done.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 1713
1609 1714
1610 // Class for holding keep-alive sockets in the cache for the HTTP 1715 // Class for holding keep-alive sockets in the cache for the HTTP
1611 // client together with the connection information. 1716 // client together with the connection information.
1612 class _SocketConnection { 1717 class _SocketConnection {
1613 _SocketConnection(String this._host, 1718 _SocketConnection(String this._host,
1614 int this._port, 1719 int this._port,
1615 Socket this._socket); 1720 Socket this._socket);
1616 1721
1617 void _markReturned() { 1722 void _markReturned() {
1618 _socket.onData = null; 1723 // Any activity on the socket while waiting in the pool will
1619 _socket.onClosed = null; 1724 // invalidate the connection os that it is not reused.
Mads Ager (google) 2012/12/05 16:02:18 os -> so
Søren Gjesse 2012/12/06 17:23:08 Done.
1620 _socket.onError = null; 1725 _socket.onData = _invalidate;
1726 _socket.onClosed = _invalidate;
1727 _socket.onError = (_) => _invalidate();
1621 _returnTime = new Date.now(); 1728 _returnTime = new Date.now();
1622 _httpClientConnection = null; 1729 _httpClientConnection = null;
1623 } 1730 }
1624 1731
1732 void _markRetreived() {
Mads Ager (google) 2012/12/05 16:02:18 _markRetrieved
Søren Gjesse 2012/12/06 17:23:08 Done.
1733 _socket.onData = null;
1734 _socket.onClosed = null;
1735 _socket.onError = null;
1736 _httpClientConnection = null;
1737 }
1738
1625 void _close() { 1739 void _close() {
1626 _socket.onData = null; 1740 _socket.onData = null;
1627 _socket.onClosed = null; 1741 _socket.onClosed = null;
1628 _socket.onError = null; 1742 _socket.onError = null;
1629 _httpClientConnection = null; 1743 _httpClientConnection = null;
1630 _socket.close(); 1744 _socket.close();
1631 } 1745 }
1632 1746
1633 Duration _idleTime(Date now) => now.difference(_returnTime); 1747 Duration _idleTime(Date now) => now.difference(_returnTime);
1634 1748
1749 bool get _fromPool => _returnTime != null;
1750
1751 void _invalidate() {
1752 _valid = false;
1753 _close();
1754 }
1755
1635 int get hashCode => _socket.hashCode; 1756 int get hashCode => _socket.hashCode;
1636 1757
1637 String _host; 1758 String _host;
1638 int _port; 1759 int _port;
1639 Socket _socket; 1760 Socket _socket;
1640 Date _returnTime; 1761 Date _returnTime;
1762 bool _valid = true;
1641 HttpClientConnection _httpClientConnection; 1763 HttpClientConnection _httpClientConnection;
1642 } 1764 }
1643 1765
1644 class _ProxyConfiguration { 1766 class _ProxyConfiguration {
1645 static const String PROXY_PREFIX = "PROXY "; 1767 static const String PROXY_PREFIX = "PROXY ";
1646 static const String DIRECT_PREFIX = "DIRECT"; 1768 static const String DIRECT_PREFIX = "DIRECT";
1647 1769
1648 _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() { 1770 _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() {
1649 if (configuration == null) { 1771 if (configuration == null) {
1650 throw new HttpException("Invalid proxy configuration $configuration"); 1772 throw new HttpException("Invalid proxy configuration $configuration");
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 connectPort = port; 1962 connectPort = port;
1841 } else { 1963 } else {
1842 connectHost = proxy.host; 1964 connectHost = proxy.host;
1843 connectPort = proxy.port; 1965 connectPort = proxy.port;
1844 } 1966 }
1845 1967
1846 // If there are active connections for this key get the first one 1968 // If there are active connections for this key get the first one
1847 // otherwise create a new one. 1969 // otherwise create a new one.
1848 String key = _connectionKey(connectHost, connectPort); 1970 String key = _connectionKey(connectHost, connectPort);
1849 Queue socketConnections = _openSockets[key]; 1971 Queue socketConnections = _openSockets[key];
1850 // Remove active connections that are of the wrong type (HTTP or HTTPS). 1972 // Remove active connections that are not valid any more or of
1973 // the wrong type (HTTP or HTTPS).
1851 while (socketConnections != null && 1974 while (socketConnections != null &&
1852 !socketConnections.isEmpty && 1975 !socketConnections.isEmpty &&
1853 secure != (socketConnections.first._socket is SecureSocket)) { 1976 (!socketConnections.first._valid ||
1854 socketConnection.removeFirst()._close(); 1977 secure != (socketConnections.first._socket is SecureSocket))) {
1978 socketConnections.removeFirst()._close();
1855 } 1979 }
1856 if (socketConnections == null || socketConnections.isEmpty) { 1980 if (socketConnections == null || socketConnections.isEmpty) {
1857 Socket socket = secure ? new SecureSocket(connectHost, connectPort) : 1981 Socket socket = secure ? new SecureSocket(connectHost, connectPort) :
1858 new Socket(connectHost, connectPort); 1982 new Socket(connectHost, connectPort);
1859 // Until the connection is established handle connection errors 1983 // Until the connection is established handle connection errors
1860 // here as the HttpClientConnection object is not yet associated 1984 // here as the HttpClientConnection object is not yet associated
1861 // with the socket. 1985 // with the socket.
1862 socket.onError = (e) { 1986 socket.onError = (e) {
1863 proxyIndex++; 1987 proxyIndex++;
1864 if (proxyIndex < proxyConfiguration.proxies.length) { 1988 if (proxyIndex < proxyConfiguration.proxies.length) {
(...skipping 12 matching lines...) Expand all
1877 // HttpClientConnection object which will be associated with 2001 // HttpClientConnection object which will be associated with
1878 // the connected socket. 2002 // the connected socket.
1879 socket.onError = null; 2003 socket.onError = null;
1880 _SocketConnection socketConn = 2004 _SocketConnection socketConn =
1881 new _SocketConnection(connectHost, connectPort, socket); 2005 new _SocketConnection(connectHost, connectPort, socket);
1882 _activeSockets.add(socketConn); 2006 _activeSockets.add(socketConn);
1883 _connectionOpened(socketConn, connection, !proxy.isDirect); 2007 _connectionOpened(socketConn, connection, !proxy.isDirect);
1884 }; 2008 };
1885 } else { 2009 } else {
1886 _SocketConnection socketConn = socketConnections.removeFirst(); 2010 _SocketConnection socketConn = socketConnections.removeFirst();
2011 socketConn._markRetreived();
1887 _activeSockets.add(socketConn); 2012 _activeSockets.add(socketConn);
1888 new Timer(0, (ignored) => 2013 new Timer(0, (ignored) =>
1889 _connectionOpened(socketConn, connection, !proxy.isDirect)); 2014 _connectionOpened(socketConn, connection, !proxy.isDirect));
1890 2015
1891 // Get rid of eviction timer if there are no more active connections. 2016 // Get rid of eviction timer if there are no more active connections.
1892 if (socketConnections.isEmpty) _openSockets.remove(key); 2017 if (socketConnections.isEmpty) _openSockets.remove(key);
1893 if (_openSockets.isEmpty) _cancelEvictionTimer(); 2018 if (_openSockets.isEmpty) _cancelEvictionTimer();
1894 } 2019 }
1895 } 2020 }
1896 2021
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2150 2275
2151 2276
2152 class _RedirectInfo implements RedirectInfo { 2277 class _RedirectInfo implements RedirectInfo {
2153 const _RedirectInfo(int this.statusCode, 2278 const _RedirectInfo(int this.statusCode,
2154 String this.method, 2279 String this.method,
2155 Uri this.location); 2280 Uri this.location);
2156 final int statusCode; 2281 final int statusCode;
2157 final String method; 2282 final String method;
2158 final Uri location; 2283 final Uri location;
2159 } 2284 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/io/http_parser.dart » ('j') | sdk/lib/io/secure_socket.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698