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

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

Issue 11411121: Generate an error for active connections when the HTTP client is shutdown (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed long line 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
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 1445 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 DetachedSocket detachSocket() { 1456 DetachedSocket detachSocket() {
1457 return _detachSocket(); 1457 return _detachSocket();
1458 } 1458 }
1459 1459
1460 void _onClosed() { 1460 void _onClosed() {
1461 _state |= _HttpConnectionBase.READ_CLOSED; 1461 _state |= _HttpConnectionBase.READ_CLOSED;
1462 _checkSocketDone(); 1462 _checkSocketDone();
1463 } 1463 }
1464 1464
1465 void _onError(e) { 1465 void _onError(e) {
1466 // Socket is closed either due to an error or due to normal socket close. 1466 if (_socketConn != null) {
1467 _client._closeSocketConnection(_socketConn);
1468 }
1467 if (_onErrorCallback != null) { 1469 if (_onErrorCallback != null) {
1468 _onErrorCallback(e); 1470 _onErrorCallback(e);
1469 } else { 1471 } else {
1470 throw e; 1472 throw e;
1471 } 1473 }
1472 // Propagate the error to the streams. 1474 // Propagate the error to the streams.
1473 if (_response != null && _response._streamErrorHandler != null) { 1475 if (_response != null && _response._streamErrorHandler != null) {
1474 _response._streamErrorHandler(e); 1476 _response._streamErrorHandler(e);
1475 } 1477 }
1476 if (_socketConn != null) {
1477 _client._closeSocketConnection(_socketConn);
1478 }
1479 } 1478 }
1480 1479
1481 void _onResponseReceived(int statusCode, 1480 void _onResponseReceived(int statusCode,
1482 String reasonPhrase, 1481 String reasonPhrase,
1483 String version, 1482 String version,
1484 _HttpHeaders headers) { 1483 _HttpHeaders headers) {
1485 _response._onResponseReceived(statusCode, reasonPhrase, version, headers); 1484 _response._onResponseReceived(statusCode, reasonPhrase, version, headers);
1486 } 1485 }
1487 1486
1488 void _onDataReceived(List<int> data) { 1487 void _onDataReceived(List<int> data) {
1489 _response._onDataReceived(data); 1488 _response._onDataReceived(data);
1490 } 1489 }
1491 1490
1492 void _onDataEnd(bool close) { 1491 void _onDataEnd(bool close) {
1492 _state |= _HttpConnectionBase.RESPONSE_DONE;
1493 _response._onDataEnd(); 1493 _response._onDataEnd();
1494 _state |= _HttpConnectionBase.RESPONSE_DONE;
1495 _checkSocketDone(); 1494 _checkSocketDone();
1496 } 1495 }
1497 1496
1497 void _onClientShutdown() {
1498 if (!_isResponseDone) {
1499 _onError(new HttpException("Client shutdown"));
1500 }
1501 }
1502
1498 void set onRequest(void handler(HttpClientRequest request)) { 1503 void set onRequest(void handler(HttpClientRequest request)) {
1499 _onRequest = handler; 1504 _onRequest = handler;
1500 } 1505 }
1501 1506
1502 void set onResponse(void handler(HttpClientResponse response)) { 1507 void set onResponse(void handler(HttpClientResponse response)) {
1503 _onResponse = handler; 1508 _onResponse = handler;
1504 } 1509 }
1505 1510
1506 void set onError(void callback(e)) { 1511 void set onError(void callback(e)) {
1507 _onErrorCallback = callback; 1512 _onErrorCallback = callback;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 } 1546 }
1542 1547
1543 void redirect([String method, Uri url]) { 1548 void redirect([String method, Uri url]) {
1544 if (method == null) method = _method; 1549 if (method == null) method = _method;
1545 if (url == null) { 1550 if (url == null) {
1546 url = new Uri.fromString(_response.headers.value(HttpHeaders.LOCATION)); 1551 url = new Uri.fromString(_response.headers.value(HttpHeaders.LOCATION));
1547 } 1552 }
1548 var redirect = new _RedirectInfo(_response.statusCode, method, url); 1553 var redirect = new _RedirectInfo(_response.statusCode, method, url);
1549 // The actual redirect is postponed until both response and 1554 // The actual redirect is postponed until both response and
1550 // request are done. 1555 // request are done.
1551 if (_isAllDone) { 1556 assert(_pendingRetry == null);
1552 _doRedirect(redirect); 1557 _pendingRedirect = redirect;
1553 } else {
1554 // Prepare for redirect.
1555 assert(_pendingRetry == null);
1556 _pendingRedirect = redirect;
1557 }
1558 } 1558 }
1559 1559
1560 List<RedirectInfo> get redirects => _redirects; 1560 List<RedirectInfo> get redirects => _redirects;
1561 1561
1562 Function _onRequest; 1562 Function _onRequest;
1563 Function _onResponse; 1563 Function _onResponse;
1564 Function _onErrorCallback; 1564 Function _onErrorCallback;
1565 1565
1566 _HttpClient _client; 1566 _HttpClient _client;
1567 _SocketConnection _socketConn; 1567 _SocketConnection _socketConn;
(...skipping 19 matching lines...) Expand all
1587 class _SocketConnection { 1587 class _SocketConnection {
1588 _SocketConnection(String this._host, 1588 _SocketConnection(String this._host,
1589 int this._port, 1589 int this._port,
1590 Socket this._socket); 1590 Socket this._socket);
1591 1591
1592 void _markReturned() { 1592 void _markReturned() {
1593 _socket.onData = null; 1593 _socket.onData = null;
1594 _socket.onClosed = null; 1594 _socket.onClosed = null;
1595 _socket.onError = null; 1595 _socket.onError = null;
1596 _returnTime = new Date.now(); 1596 _returnTime = new Date.now();
1597 _httpClientConnection = null;
1597 } 1598 }
1598 1599
1599 void _close() { 1600 void _close() {
1600 _socket.onData = null; 1601 _socket.onData = null;
1601 _socket.onClosed = null; 1602 _socket.onClosed = null;
1602 _socket.onError = null; 1603 _socket.onError = null;
1604 _httpClientConnection = null;
1603 _socket.close(); 1605 _socket.close();
1604 } 1606 }
1605 1607
1606 Duration _idleTime(Date now) => now.difference(_returnTime); 1608 Duration _idleTime(Date now) => now.difference(_returnTime);
1607 1609
1608 int get hashCode => _socket.hashCode; 1610 int get hashCode => _socket.hashCode;
1609 1611
1610 String _host; 1612 String _host;
1611 int _port; 1613 int _port;
1612 Socket _socket; 1614 Socket _socket;
1613 Date _returnTime; 1615 Date _returnTime;
1616 HttpClientConnection _httpClientConnection;
1614 } 1617 }
1615 1618
1616 class _ProxyConfiguration { 1619 class _ProxyConfiguration {
1617 static const String PROXY_PREFIX = "PROXY "; 1620 static const String PROXY_PREFIX = "PROXY ";
1618 static const String DIRECT_PREFIX = "DIRECT"; 1621 static const String DIRECT_PREFIX = "DIRECT";
1619 1622
1620 _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() { 1623 _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() {
1621 if (configuration == null) { 1624 if (configuration == null) {
1622 throw new HttpException("Invalid proxy configuration $configuration"); 1625 throw new HttpException("Invalid proxy configuration $configuration");
1623 } 1626 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 _authenticate = f; 1726 _authenticate = f;
1724 } 1727 }
1725 1728
1726 void addCredentials( 1729 void addCredentials(
1727 Uri url, String realm, HttpClientCredentials cr) { 1730 Uri url, String realm, HttpClientCredentials cr) {
1728 credentials.add(new _Credentials(url, realm, cr)); 1731 credentials.add(new _Credentials(url, realm, cr));
1729 } 1732 }
1730 1733
1731 set findProxy(String f(Uri uri)) => _findProxy = f; 1734 set findProxy(String f(Uri uri)) => _findProxy = f;
1732 1735
1733 void shutdown() { 1736 void shutdown({bool force: false}) {
1734 _closeQueue.shutdown(); 1737 if (force) _closeQueue.shutdown();
1735 _openSockets.forEach((String key, Queue<_SocketConnection> connections) { 1738 _openSockets.forEach((String key, Queue<_SocketConnection> connections) {
1736 while (!connections.isEmpty) { 1739 while (!connections.isEmpty) {
1737 _SocketConnection socketConn = connections.removeFirst(); 1740 _SocketConnection socketConn = connections.removeFirst();
1738 socketConn._socket.close(); 1741 socketConn._socket.close();
1739 } 1742 }
1740 }); 1743 });
1741 _activeSockets.forEach((_SocketConnection socketConn) { 1744 if (force) {
1742 socketConn._socket.close(); 1745 _activeSockets.forEach((_SocketConnection socketConn) {
1743 }); 1746 socketConn._socket.close();
1747 socketConn._httpClientConnection._onClientShutdown();
1748 });
1749 }
1744 if (_evictionTimer != null) _cancelEvictionTimer(); 1750 if (_evictionTimer != null) _cancelEvictionTimer();
1745 _shutdown = true; 1751 _shutdown = true;
1746 } 1752 }
1747 1753
1748 void _cancelEvictionTimer() { 1754 void _cancelEvictionTimer() {
1749 _evictionTimer.cancel(); 1755 _evictionTimer.cancel();
1750 _evictionTimer = null; 1756 _evictionTimer = null;
1751 } 1757 }
1752 1758
1753 String _connectionKey(String host, int port) { 1759 String _connectionKey(String host, int port) {
1754 return "$host:$port"; 1760 return "$host:$port";
1755 } 1761 }
1756 1762
1757 HttpClientConnection _prepareHttpClientConnection( 1763 HttpClientConnection _prepareHttpClientConnection(
1758 String method, 1764 String method,
1759 Uri url, 1765 Uri url,
1760 [_HttpClientConnection connection]) { 1766 [_HttpClientConnection connection]) {
1761 1767
1762 void _establishConnection(String host, 1768 void _establishConnection(String host,
1763 int port, 1769 int port,
1764 _ProxyConfiguration proxyConfiguration, 1770 _ProxyConfiguration proxyConfiguration,
1765 int proxyIndex, 1771 int proxyIndex,
1766 bool reusedConnection) { 1772 bool reusedConnection) {
1767 1773
1768 void _connectionOpened(_SocketConnection socketConn, 1774 void _connectionOpened(_SocketConnection socketConn,
1769 _HttpClientConnection connection, 1775 _HttpClientConnection connection,
1770 bool usingProxy) { 1776 bool usingProxy) {
1777 socketConn._httpClientConnection = connection;
1771 connection._usingProxy = usingProxy; 1778 connection._usingProxy = usingProxy;
1772 connection._connectionEstablished(socketConn); 1779 connection._connectionEstablished(socketConn);
1773 HttpClientRequest request = connection.open(method, url); 1780 HttpClientRequest request = connection.open(method, url);
1774 request.headers.host = host; 1781 request.headers.host = host;
1775 request.headers.port = port; 1782 request.headers.port = port;
1776 if (url.userInfo != null && !url.userInfo.isEmpty) { 1783 if (url.userInfo != null && !url.userInfo.isEmpty) {
1777 // If the URL contains user information use that for basic 1784 // If the URL contains user information use that for basic
1778 // authorization 1785 // authorization
1779 _UTF8Encoder encoder = new _UTF8Encoder(); 1786 _UTF8Encoder encoder = new _UTF8Encoder();
1780 String auth = 1787 String auth =
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 proxyConfiguration = new _ProxyConfiguration(_findProxy(url)); 1882 proxyConfiguration = new _ProxyConfiguration(_findProxy(url));
1876 } 1883 }
1877 1884
1878 // Establish the connection starting with the first proxy configured. 1885 // Establish the connection starting with the first proxy configured.
1879 _establishConnection(host, port, proxyConfiguration, 0, reusedConnection); 1886 _establishConnection(host, port, proxyConfiguration, 0, reusedConnection);
1880 1887
1881 return connection; 1888 return connection;
1882 } 1889 }
1883 1890
1884 void _returnSocketConnection(_SocketConnection socketConn) { 1891 void _returnSocketConnection(_SocketConnection socketConn) {
1892 // If the HTTP client is being shutdown don't return the connection.
1893 if (_shutdown) {
1894 socketConn._close();
1895 return;
1896 };
1897
1885 // Mark socket as returned to unregister from the old connection. 1898 // Mark socket as returned to unregister from the old connection.
1886 socketConn._markReturned(); 1899 socketConn._markReturned();
1887 1900
1888 // If the HTTP client is beeing shutdown don't return the connection.
1889 if (_shutdown) {
1890 socketConn._socket.close();
1891 return;
1892 };
1893
1894 String key = _connectionKey(socketConn._host, socketConn._port); 1901 String key = _connectionKey(socketConn._host, socketConn._port);
1895 1902
1896 // Get or create the connection list for this key. 1903 // Get or create the connection list for this key.
1897 Queue sockets = _openSockets[key]; 1904 Queue sockets = _openSockets[key];
1898 if (sockets == null) { 1905 if (sockets == null) {
1899 sockets = new Queue(); 1906 sockets = new Queue();
1900 _openSockets[key] = sockets; 1907 _openSockets[key] = sockets;
1901 } 1908 }
1902 1909
1903 // If there is currently no eviction timer start one. 1910 // If there is currently no eviction timer start one.
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2098 2105
2099 2106
2100 class _RedirectInfo implements RedirectInfo { 2107 class _RedirectInfo implements RedirectInfo {
2101 const _RedirectInfo(int this.statusCode, 2108 const _RedirectInfo(int this.statusCode,
2102 String this.method, 2109 String this.method,
2103 Uri this.location); 2110 Uri this.location);
2104 final int statusCode; 2111 final int statusCode;
2105 final String method; 2112 final String method;
2106 final Uri location; 2113 final Uri location;
2107 } 2114 }
OLDNEW
« sdk/lib/io/http.dart ('K') | « sdk/lib/io/http.dart ('k') | sdk/lib/io/http_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698