| OLD | NEW | 
|---|
| 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.io; | 5 part of dart.io; | 
| 6 | 6 | 
| 7 const int _OUTGOING_BUFFER_SIZE = 8 * 1024; | 7 const int _OUTGOING_BUFFER_SIZE = 8 * 1024; | 
| 8 | 8 | 
| 9 class _HttpIncoming extends Stream<List<int>> { | 9 class _HttpIncoming extends Stream<List<int>> { | 
| 10   final int _transferLength; | 10   final int _transferLength; | 
| (...skipping 1476 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1487     assert(_idleTimer == null); | 1487     assert(_idleTimer == null); | 
| 1488     _idleTimer = new Timer( | 1488     _idleTimer = new Timer( | 
| 1489         _httpClient.idleTimeout, | 1489         _httpClient.idleTimeout, | 
| 1490         () { | 1490         () { | 
| 1491           _idleTimer = null; | 1491           _idleTimer = null; | 
| 1492           close(); | 1492           close(); | 
| 1493         }); | 1493         }); | 
| 1494   } | 1494   } | 
| 1495 } | 1495 } | 
| 1496 | 1496 | 
| 1497 class _ConnnectionInfo { | 1497 class _ConnectionInfo { | 
| 1498   final _HttpClientConnection connection; | 1498   final _HttpClientConnection connection; | 
| 1499   final _Proxy proxy; | 1499   final _Proxy proxy; | 
| 1500 | 1500 | 
| 1501   _ConnnectionInfo(this.connection, this.proxy); | 1501   _ConnectionInfo(this.connection, this.proxy); | 
| 1502 } | 1502 } | 
| 1503 | 1503 | 
| 1504 | 1504 | 
| 1505 class _ConnectionTarget { | 1505 class _ConnectionTarget { | 
| 1506   // Unique key for this connection target. | 1506   // Unique key for this connection target. | 
| 1507   final String key; | 1507   final String key; | 
|  | 1508   final String host; | 
|  | 1509   final int port; | 
|  | 1510   final bool isSecure; | 
| 1508   final Set<_HttpClientConnection> _idle = new HashSet(); | 1511   final Set<_HttpClientConnection> _idle = new HashSet(); | 
| 1509   final Set<_HttpClientConnection> _active = new HashSet(); | 1512   final Set<_HttpClientConnection> _active = new HashSet(); | 
|  | 1513   int _connecting = 0; | 
| 1510 | 1514 | 
| 1511   _ConnectionTarget(this.key); | 1515   _ConnectionTarget(this.key, this.host, this.port, this.isSecure); | 
| 1512 | 1516 | 
| 1513   bool get isEmpty => _idle.isEmpty && _active.isEmpty; | 1517   bool get isEmpty => _idle.isEmpty && _active.isEmpty && _connecting == 0; | 
| 1514 | 1518 | 
| 1515   bool get hasIdle => _idle.isNotEmpty; | 1519   bool get hasIdle => _idle.isNotEmpty; | 
| 1516 | 1520 | 
| 1517   bool get hasActive => _active.isNotEmpty; | 1521   bool get hasActive => _active.isNotEmpty && _connecting > 0; | 
| 1518 | 1522 | 
| 1519   _HttpClientConnection takeIdle() { | 1523   _HttpClientConnection takeIdle() { | 
| 1520     assert(hasIdle); | 1524     assert(hasIdle); | 
| 1521     _HttpClientConnection connection = _idle.first; | 1525     _HttpClientConnection connection = _idle.first; | 
| 1522     _idle.remove(connection); | 1526     _idle.remove(connection); | 
| 1523     connection.stopTimer(); | 1527     connection.stopTimer(); | 
| 1524     _active.add(connection); | 1528     _active.add(connection); | 
| 1525     return connection; | 1529     return connection; | 
| 1526   } | 1530   } | 
| 1527 | 1531 | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 1544   void close(bool force) { | 1548   void close(bool force) { | 
| 1545     for (var c in _idle.toList()) { | 1549     for (var c in _idle.toList()) { | 
| 1546       c.close(); | 1550       c.close(); | 
| 1547     } | 1551     } | 
| 1548     if (force) { | 1552     if (force) { | 
| 1549       for (var c in _active.toList()) { | 1553       for (var c in _active.toList()) { | 
| 1550         c.destroy(); | 1554         c.destroy(); | 
| 1551       } | 1555       } | 
| 1552     } | 1556     } | 
| 1553   } | 1557   } | 
|  | 1558 | 
|  | 1559   Future<_ConnectionInfo> connect(String uriHost, | 
|  | 1560                                    int uriPort, | 
|  | 1561                                    _Proxy proxy, | 
|  | 1562                                    _HttpClient client) { | 
|  | 1563     if (hasIdle) { | 
|  | 1564       var connection = takeIdle(); | 
|  | 1565       client._updateTimers(); | 
|  | 1566       return new Future.value(new _ConnectionInfo(connection, proxy)); | 
|  | 1567     } | 
|  | 1568     var currentBadCertificateCallback = client._badCertificateCallback; | 
|  | 1569     bool callback(X509Certificate certificate) => | 
|  | 1570         currentBadCertificateCallback == null ? false : | 
|  | 1571         currentBadCertificateCallback(certificate, uriHost, uriPort); | 
|  | 1572     Future socketFuture = (isSecure && proxy.isDirect | 
|  | 1573         ? SecureSocket.connect(host, | 
|  | 1574                                port, | 
|  | 1575                                sendClientCertificate: true, | 
|  | 1576                                onBadCertificate: callback) | 
|  | 1577         : Socket.connect(host, port)); | 
|  | 1578     _connecting++; | 
|  | 1579     return socketFuture.then((socket) { | 
|  | 1580         _connecting--; | 
|  | 1581         socket.setOption(SocketOption.TCP_NODELAY, true); | 
|  | 1582         var connection = new _HttpClientConnection(key, socket, client); | 
|  | 1583         if (isSecure && !proxy.isDirect) { | 
|  | 1584           connection._dispose = true; | 
|  | 1585           return connection.createProxyTunnel(uriHost, uriPort, proxy, callback) | 
|  | 1586               .then((tunnel) { | 
|  | 1587                 client._getConnectionTarget(uriHost, uriPort, true) | 
|  | 1588                     .addNewActive(tunnel); | 
|  | 1589                 return new _ConnectionInfo(tunnel, proxy); | 
|  | 1590               }); | 
|  | 1591         } else { | 
|  | 1592           addNewActive(connection); | 
|  | 1593           return new _ConnectionInfo(connection, proxy); | 
|  | 1594         } | 
|  | 1595       }); | 
|  | 1596   } | 
| 1554 } | 1597 } | 
| 1555 | 1598 | 
| 1556 | 1599 | 
| 1557 class _HttpClient implements HttpClient { | 1600 class _HttpClient implements HttpClient { | 
| 1558   bool _closing = false; | 1601   bool _closing = false; | 
| 1559   final Map<String, _ConnectionTarget> _connectionTargets | 1602   final Map<String, _ConnectionTarget> _connectionTargets | 
| 1560       = new HashMap<String, _ConnectionTarget>(); | 1603       = new HashMap<String, _ConnectionTarget>(); | 
| 1561   final List<_Credentials> _credentials = []; | 1604   final List<_Credentials> _credentials = []; | 
| 1562   final List<_ProxyCredentials> _proxyCredentials = []; | 1605   final List<_ProxyCredentials> _proxyCredentials = []; | 
| 1563   Function _authenticate; | 1606   Function _authenticate; | 
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1769             _closing = false; | 1812             _closing = false; | 
| 1770           } | 1813           } | 
| 1771         }); | 1814         }); | 
| 1772       } | 1815       } | 
| 1773     } else if (_noActiveTimer != null) { | 1816     } else if (_noActiveTimer != null) { | 
| 1774       _noActiveTimer.cancel(); | 1817       _noActiveTimer.cancel(); | 
| 1775       _noActiveTimer = null; | 1818       _noActiveTimer = null; | 
| 1776     } | 1819     } | 
| 1777   } | 1820   } | 
| 1778 | 1821 | 
| 1779   // Get a new _HttpClientConnection, either from the idle pool or created from | 1822   _ConnectionTarget _getConnectionTarget(String host, int port, bool isSecure) { | 
| 1780   // a new Socket. | 1823     String key = _HttpClientConnection.makeKey(isSecure, host, port); | 
| 1781   Future<_ConnnectionInfo> _getConnection(String uriHost, | 1824     return _connectionTargets.putIfAbsent( | 
|  | 1825         key, () => new _ConnectionTarget(key, host, port, isSecure)); | 
|  | 1826   } | 
|  | 1827 | 
|  | 1828   // Get a new _HttpClientConnection, from the matching _ConnectionTarget. | 
|  | 1829   Future<_ConnectionInfo> _getConnection(String uriHost, | 
| 1782                                           int uriPort, | 1830                                           int uriPort, | 
| 1783                                           _ProxyConfiguration proxyConf, | 1831                                           _ProxyConfiguration proxyConf, | 
| 1784                                           bool isSecure) { | 1832                                           bool isSecure) { | 
| 1785     Iterator<_Proxy> proxies = proxyConf.proxies.iterator; | 1833     Iterator<_Proxy> proxies = proxyConf.proxies.iterator; | 
| 1786 | 1834 | 
| 1787     Future<_ConnnectionInfo> connect(error) { | 1835     Future<_ConnectionInfo> connect(error) { | 
| 1788       if (!proxies.moveNext()) return new Future.error(error); | 1836       if (!proxies.moveNext()) return new Future.error(error); | 
| 1789       _Proxy proxy = proxies.current; | 1837       _Proxy proxy = proxies.current; | 
| 1790       String host = proxy.isDirect ? uriHost: proxy.host; | 1838       String host = proxy.isDirect ? uriHost: proxy.host; | 
| 1791       int port = proxy.isDirect ? uriPort: proxy.port; | 1839       int port = proxy.isDirect ? uriPort: proxy.port; | 
| 1792       String key = _HttpClientConnection.makeKey(isSecure, host, port); | 1840       return _getConnectionTarget(host, port, isSecure) | 
| 1793       var connectionTarget = _connectionTargets[key]; | 1841           .connect(uriHost, uriPort, proxy, this) | 
| 1794       if (connectionTarget != null && connectionTarget.hasIdle) { | 1842           // On error, continue with next proxy. | 
| 1795         var connection = connectionTarget.takeIdle(); | 1843           .catchError(connect); | 
| 1796         _updateTimers(); |  | 
| 1797         return new Future.value(new _ConnnectionInfo(connection, proxy)); |  | 
| 1798       } |  | 
| 1799       var currentBadCertificateCallback = _badCertificateCallback; |  | 
| 1800       bool callback(X509Certificate certificate) => |  | 
| 1801           currentBadCertificateCallback == null ? false : |  | 
| 1802           currentBadCertificateCallback(certificate, uriHost, uriPort); |  | 
| 1803       Future socketFuture = (isSecure && proxy.isDirect |  | 
| 1804           ? SecureSocket.connect(host, |  | 
| 1805                                  port, |  | 
| 1806                                  sendClientCertificate: true, |  | 
| 1807                                  onBadCertificate: callback) |  | 
| 1808           : Socket.connect(host, port)); |  | 
| 1809       return socketFuture.then((socket) { |  | 
| 1810           socket.setOption(SocketOption.TCP_NODELAY, true); |  | 
| 1811           var connection = new _HttpClientConnection(key, socket, this); |  | 
| 1812           if (isSecure && !proxy.isDirect) { |  | 
| 1813             connection._dispose = true; |  | 
| 1814             return connection.createProxyTunnel( |  | 
| 1815                 uriHost, uriPort, proxy, callback) |  | 
| 1816                 .then((tunnel) { |  | 
| 1817                   var connectionTarget = _connectionTargets |  | 
| 1818                       .putIfAbsent(tunnel.key, |  | 
| 1819                                    () => new _ConnectionTarget(tunnel.key)); |  | 
| 1820                   connectionTarget.addNewActive(tunnel); |  | 
| 1821                   return new _ConnnectionInfo(tunnel, proxy); |  | 
| 1822                 }); |  | 
| 1823           } else { |  | 
| 1824             var connectionTarget = _connectionTargets |  | 
| 1825                 .putIfAbsent(key, () => new _ConnectionTarget(key)); |  | 
| 1826             connectionTarget.addNewActive(connection); |  | 
| 1827             return new _ConnnectionInfo(connection, proxy); |  | 
| 1828           } |  | 
| 1829         }, onError: (error) { |  | 
| 1830           // Continue with next proxy. |  | 
| 1831           return connect(error); |  | 
| 1832         }); |  | 
| 1833     } | 1844     } | 
| 1834     return connect(new HttpException("No proxies given")); | 1845     return connect(new HttpException("No proxies given")); | 
| 1835   } | 1846   } | 
| 1836 | 1847 | 
| 1837   _SiteCredentials _findCredentials(Uri url, [_AuthenticationScheme scheme]) { | 1848   _SiteCredentials _findCredentials(Uri url, [_AuthenticationScheme scheme]) { | 
| 1838     // Look for credentials. | 1849     // Look for credentials. | 
| 1839     _SiteCredentials cr = | 1850     _SiteCredentials cr = | 
| 1840         _credentials.fold(null, (prev, value) { | 1851         _credentials.fold(null, (prev, value) { | 
| 1841           if (value.applies(url, scheme)) { | 1852           if (value.applies(url, scheme)) { | 
| 1842             if (prev == null) return value; | 1853             if (prev == null) return value; | 
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2705   const _RedirectInfo(this.statusCode, this.method, this.location); | 2716   const _RedirectInfo(this.statusCode, this.method, this.location); | 
| 2706 } | 2717 } | 
| 2707 | 2718 | 
| 2708 String _getHttpVersion() { | 2719 String _getHttpVersion() { | 
| 2709   var version = Platform.version; | 2720   var version = Platform.version; | 
| 2710   // Only include major and minor version numbers. | 2721   // Only include major and minor version numbers. | 
| 2711   int index = version.indexOf('.', version.indexOf('.') + 1); | 2722   int index = version.indexOf('.', version.indexOf('.') + 1); | 
| 2712   version = version.substring(0, index); | 2723   version = version.substring(0, index); | 
| 2713   return 'Dart/$version (dart:io)'; | 2724   return 'Dart/$version (dart:io)'; | 
| 2714 } | 2725 } | 
| OLD | NEW | 
|---|