| 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 cancelOnError: cancelOnError); | 122 cancelOnError: cancelOnError); |
| 123 } | 123 } |
| 124 | 124 |
| 125 Uri get uri => _incoming.uri; | 125 Uri get uri => _incoming.uri; |
| 126 | 126 |
| 127 Uri get requestedUri { | 127 Uri get requestedUri { |
| 128 if (_requestedUri == null) { | 128 if (_requestedUri == null) { |
| 129 var proto = headers['x-forwarded-proto']; | 129 var proto = headers['x-forwarded-proto']; |
| 130 var scheme = proto != null ? proto.first : | 130 var scheme = proto != null ? proto.first : |
| 131 _httpConnection._socket is SecureSocket ? "https" : "http"; | 131 _httpConnection._socket is SecureSocket ? "https" : "http"; |
| 132 var host = headers['x-forwarded-host']; | 132 var hostList = headers['x-forwarded-host']; |
| 133 if (host != null) { | 133 String host; |
| 134 host = host.first; | 134 if (hostList != null) { |
| 135 host = hostList.first; |
| 135 } else { | 136 } else { |
| 136 host = headers['host']; | 137 hostList = headers['host']; |
| 137 if (host != null) { | 138 if (hostList != null) { |
| 138 host = host.first; | 139 host = hostList.first; |
| 139 } else { | 140 } else { |
| 140 host = "${_httpServer.address.host}:${_httpServer.port}"; | 141 host = "${_httpServer.address.host}:${_httpServer.port}"; |
| 141 } | 142 } |
| 142 } | 143 } |
| 143 _requestedUri = Uri.parse("$scheme://$host$uri"); | 144 _requestedUri = Uri.parse("$scheme://$host$uri"); |
| 144 } | 145 } |
| 145 return _requestedUri; | 146 return _requestedUri; |
| 146 } | 147 } |
| 147 | 148 |
| 148 String get method => _incoming.method; | 149 String get method => _incoming.method; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 175 class _HttpClientResponse | 176 class _HttpClientResponse |
| 176 extends _HttpInboundMessage implements HttpClientResponse { | 177 extends _HttpInboundMessage implements HttpClientResponse { |
| 177 List<RedirectInfo> get redirects => _httpRequest._responseRedirects; | 178 List<RedirectInfo> get redirects => _httpRequest._responseRedirects; |
| 178 | 179 |
| 179 // The HttpClient this response belongs to. | 180 // The HttpClient this response belongs to. |
| 180 final _HttpClient _httpClient; | 181 final _HttpClient _httpClient; |
| 181 | 182 |
| 182 // The HttpClientRequest of this response. | 183 // The HttpClientRequest of this response. |
| 183 final _HttpClientRequest _httpRequest; | 184 final _HttpClientRequest _httpRequest; |
| 184 | 185 |
| 185 List<Cookie> _cookies; | |
| 186 | |
| 187 _HttpClientResponse(_HttpIncoming _incoming, this._httpRequest, | 186 _HttpClientResponse(_HttpIncoming _incoming, this._httpRequest, |
| 188 this._httpClient) : super(_incoming) { | 187 this._httpClient) : super(_incoming) { |
| 189 // Set uri for potential exceptions. | 188 // Set uri for potential exceptions. |
| 190 _incoming.uri = _httpRequest.uri; | 189 _incoming.uri = _httpRequest.uri; |
| 191 } | 190 } |
| 192 | 191 |
| 193 int get statusCode => _incoming.statusCode; | 192 int get statusCode => _incoming.statusCode; |
| 194 String get reasonPhrase => _incoming.reasonPhrase; | 193 String get reasonPhrase => _incoming.reasonPhrase; |
| 195 | 194 |
| 196 X509Certificate get certificate { | 195 X509Certificate get certificate { |
| 197 // The peerCertificate isn't on a plain socket, so cast to dynamic. | |
| 198 var socket = _httpRequest._httpClientConnection._socket; | 196 var socket = _httpRequest._httpClientConnection._socket; |
| 199 return socket.peerCertificate; | 197 if (socket is SecureSocket) return socket.peerCertificate; |
| 198 throw new UnsupportedError("Socket is not a SecureSocket"); |
| 200 } | 199 } |
| 201 | 200 |
| 202 List<Cookie> get cookies { | 201 List<Cookie> get cookies { |
| 203 if (_cookies != null) return _cookies; | 202 if (_cookies != null) return _cookies; |
| 204 _cookies = new List<Cookie>(); | 203 _cookies = new List<Cookie>(); |
| 205 List<String> values = headers[HttpHeaders.SET_COOKIE]; | 204 List<String> values = headers[HttpHeaders.SET_COOKIE]; |
| 206 if (values != null) { | 205 if (values != null) { |
| 207 values.forEach((value) { | 206 values.forEach((value) { |
| 208 _cookies.add(new Cookie.fromSetCookieValue(value)); | 207 _cookies.add(new Cookie.fromSetCookieValue(value)); |
| 209 }); | 208 }); |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 // Used by _HttpOutgoing as a target of a chunked converter for gzip | 861 // Used by _HttpOutgoing as a target of a chunked converter for gzip |
| 863 // compression. | 862 // compression. |
| 864 class _HttpGZipSink extends ByteConversionSink { | 863 class _HttpGZipSink extends ByteConversionSink { |
| 865 final Function _consume; | 864 final Function _consume; |
| 866 _HttpGZipSink(this._consume); | 865 _HttpGZipSink(this._consume); |
| 867 | 866 |
| 868 void add(List<int> chunk) { | 867 void add(List<int> chunk) { |
| 869 _consume(chunk); | 868 _consume(chunk); |
| 870 } | 869 } |
| 871 | 870 |
| 872 void addSlice(Uint8List chunk, int start, int end, bool isLast) { | 871 void addSlice(List<int> chunk, int start, int end, bool isLast) { |
| 873 _consume(new Uint8List.view(chunk.buffer, start, end - start)); | 872 if (chunk is Uint8List) { |
| 873 _consume(new Uint8List.view(chunk.buffer, start, end - start)); |
| 874 } else { |
| 875 _consume(chunk.sublist(start, end - start)); |
| 876 } |
| 874 } | 877 } |
| 875 | 878 |
| 876 void close() {} | 879 void close() {} |
| 877 } | 880 } |
| 878 | 881 |
| 879 | 882 |
| 880 // The _HttpOutgoing handles all of the following: | 883 // The _HttpOutgoing handles all of the following: |
| 881 // - Buffering | 884 // - Buffering |
| 882 // - GZip compressionm | 885 // - GZip compressionm |
| 883 // - Content-Length validation. | 886 // - Content-Length validation. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 Future writeHeaders({bool drainRequest: true, bool setOutgoing: true}) { | 932 Future writeHeaders({bool drainRequest: true, bool setOutgoing: true}) { |
| 930 Future write() { | 933 Future write() { |
| 931 try { | 934 try { |
| 932 outbound._writeHeader(); | 935 outbound._writeHeader(); |
| 933 } catch (_) { | 936 } catch (_) { |
| 934 // Headers too large. | 937 // Headers too large. |
| 935 return new Future.error(new HttpException( | 938 return new Future.error(new HttpException( |
| 936 "Headers size exceeded the of '$_OUTGOING_BUFFER_SIZE'" | 939 "Headers size exceeded the of '$_OUTGOING_BUFFER_SIZE'" |
| 937 " bytes")); | 940 " bytes")); |
| 938 } | 941 } |
| 942 return null; |
| 939 } | 943 } |
| 944 |
| 940 if (headersWritten) return null; | 945 if (headersWritten) return null; |
| 941 headersWritten = true; | 946 headersWritten = true; |
| 942 Future drainFuture; | 947 Future drainFuture; |
| 943 bool isServerSide = outbound is _HttpResponse; | |
| 944 bool gzip = false; | 948 bool gzip = false; |
| 945 if (isServerSide) { | 949 if (outbound is _HttpResponse) { |
| 946 var response = outbound; | 950 // Server side. |
| 951 _HttpResponse response = outbound; |
| 947 if (response._httpRequest._httpServer.autoCompress && | 952 if (response._httpRequest._httpServer.autoCompress && |
| 948 outbound.bufferOutput && | 953 outbound.bufferOutput && |
| 949 outbound.headers.chunkedTransferEncoding) { | 954 outbound.headers.chunkedTransferEncoding) { |
| 950 List acceptEncodings = | 955 List acceptEncodings = |
| 951 response._httpRequest.headers[HttpHeaders.ACCEPT_ENCODING]; | 956 response._httpRequest.headers[HttpHeaders.ACCEPT_ENCODING]; |
| 952 List contentEncoding = outbound.headers[HttpHeaders.CONTENT_ENCODING]; | 957 List contentEncoding = outbound.headers[HttpHeaders.CONTENT_ENCODING]; |
| 953 if (acceptEncodings != null && | 958 if (acceptEncodings != null && |
| 954 acceptEncodings | 959 acceptEncodings |
| 955 .expand((list) => list.split(",")) | 960 .expand((list) => list.split(",")) |
| 956 .any((encoding) => encoding.trim().toLowerCase() == "gzip") && | 961 .any((encoding) => encoding.trim().toLowerCase() == "gzip") && |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1488 String auth = _CryptoUtils.bytesToBase64( | 1493 String auth = _CryptoUtils.bytesToBase64( |
| 1489 UTF8.encode("${proxy.username}:${proxy.password}")); | 1494 UTF8.encode("${proxy.username}:${proxy.password}")); |
| 1490 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth"); | 1495 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth"); |
| 1491 } | 1496 } |
| 1492 return request.close() | 1497 return request.close() |
| 1493 .then((response) { | 1498 .then((response) { |
| 1494 if (response.statusCode != HttpStatus.OK) { | 1499 if (response.statusCode != HttpStatus.OK) { |
| 1495 throw "Proxy failed to establish tunnel " | 1500 throw "Proxy failed to establish tunnel " |
| 1496 "(${response.statusCode} ${response.reasonPhrase})"; | 1501 "(${response.statusCode} ${response.reasonPhrase})"; |
| 1497 } | 1502 } |
| 1498 var socket = response._httpRequest._httpClientConnection._socket; | 1503 var socket = (response as _HttpClientResponse)._httpRequest |
| 1504 ._httpClientConnection._socket; |
| 1499 return SecureSocket.secure( | 1505 return SecureSocket.secure( |
| 1500 socket, | 1506 socket, |
| 1501 host: host, | 1507 host: host, |
| 1502 context: _context, | 1508 context: _context, |
| 1503 onBadCertificate: callback); | 1509 onBadCertificate: callback); |
| 1504 }) | 1510 }) |
| 1505 .then((secureSocket) { | 1511 .then((secureSocket) { |
| 1506 String key = _HttpClientConnection.makeKey(true, host, port); | 1512 String key = _HttpClientConnection.makeKey(true, host, port); |
| 1507 return new _HttpClientConnection( | 1513 return new _HttpClientConnection( |
| 1508 key, secureSocket, request._httpClient, true); | 1514 key, secureSocket, request._httpClient, true); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1622 if (client.maxConnectionsPerHost != null && | 1628 if (client.maxConnectionsPerHost != null && |
| 1623 _active.length + _connecting >= client.maxConnectionsPerHost) { | 1629 _active.length + _connecting >= client.maxConnectionsPerHost) { |
| 1624 var completer = new Completer(); | 1630 var completer = new Completer(); |
| 1625 _pending.add(() { | 1631 _pending.add(() { |
| 1626 connect(uriHost, uriPort, proxy, client) | 1632 connect(uriHost, uriPort, proxy, client) |
| 1627 .then(completer.complete, onError: completer.completeError); | 1633 .then(completer.complete, onError: completer.completeError); |
| 1628 }); | 1634 }); |
| 1629 return completer.future; | 1635 return completer.future; |
| 1630 } | 1636 } |
| 1631 var currentBadCertificateCallback = client._badCertificateCallback; | 1637 var currentBadCertificateCallback = client._badCertificateCallback; |
| 1632 callback(X509Certificate certificate) => | 1638 |
| 1633 currentBadCertificateCallback == null ? false : | 1639 bool callback(X509Certificate certificate) { |
| 1634 currentBadCertificateCallback(certificate, uriHost, uriPort); | 1640 if (currentBadCertificateCallback == null) return false; |
| 1641 return currentBadCertificateCallback(certificate, uriHost, uriPort); |
| 1642 } |
| 1643 |
| 1635 Future socketFuture = (isSecure && proxy.isDirect | 1644 Future socketFuture = (isSecure && proxy.isDirect |
| 1636 ? SecureSocket.connect(host, | 1645 ? SecureSocket.connect(host, |
| 1637 port, | 1646 port, |
| 1638 context: context, | 1647 context: context, |
| 1639 onBadCertificate: callback) | 1648 onBadCertificate: callback) |
| 1640 : Socket.connect(host, port)); | 1649 : Socket.connect(host, port)); |
| 1641 _connecting++; | 1650 _connecting++; |
| 1642 return socketFuture.then((socket) { | 1651 return socketFuture.then((socket) { |
| 1643 _connecting--; | 1652 _connecting--; |
| 1644 socket.setOption(SocketOption.TCP_NODELAY, true); | 1653 socket.setOption(SocketOption.TCP_NODELAY, true); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1657 return new _ConnectionInfo(connection, proxy); | 1666 return new _ConnectionInfo(connection, proxy); |
| 1658 } | 1667 } |
| 1659 }, onError: (error) { | 1668 }, onError: (error) { |
| 1660 _connecting--; | 1669 _connecting--; |
| 1661 _checkPending(); | 1670 _checkPending(); |
| 1662 throw error; | 1671 throw error; |
| 1663 }); | 1672 }); |
| 1664 } | 1673 } |
| 1665 } | 1674 } |
| 1666 | 1675 |
| 1676 typedef bool BadCertificateCallback(X509Certificate cr, String host, int port); |
| 1667 | 1677 |
| 1668 class _HttpClient implements HttpClient { | 1678 class _HttpClient implements HttpClient { |
| 1669 bool _closing = false; | 1679 bool _closing = false; |
| 1670 bool _closingForcefully = false; | 1680 bool _closingForcefully = false; |
| 1671 final Map<String, _ConnectionTarget> _connectionTargets | 1681 final Map<String, _ConnectionTarget> _connectionTargets |
| 1672 = new HashMap<String, _ConnectionTarget>(); | 1682 = new HashMap<String, _ConnectionTarget>(); |
| 1673 final List<_Credentials> _credentials = []; | 1683 final List<_Credentials> _credentials = []; |
| 1674 final List<_ProxyCredentials> _proxyCredentials = []; | 1684 final List<_ProxyCredentials> _proxyCredentials = []; |
| 1675 final SecurityContext _context; | 1685 final SecurityContext _context; |
| 1676 Function _authenticate; | 1686 Function _authenticate; |
| 1677 Function _authenticateProxy; | 1687 Function _authenticateProxy; |
| 1678 Function _findProxy = HttpClient.findProxyFromEnvironment; | 1688 Function _findProxy = HttpClient.findProxyFromEnvironment; |
| 1679 Duration _idleTimeout = const Duration(seconds: 15); | 1689 Duration _idleTimeout = const Duration(seconds: 15); |
| 1680 Function _badCertificateCallback; | 1690 BadCertificateCallback _badCertificateCallback; |
| 1681 | 1691 |
| 1682 Duration get idleTimeout => _idleTimeout; | 1692 Duration get idleTimeout => _idleTimeout; |
| 1683 | 1693 |
| 1684 int maxConnectionsPerHost; | 1694 int maxConnectionsPerHost; |
| 1685 | 1695 |
| 1686 bool autoUncompress = true; | 1696 bool autoUncompress = true; |
| 1687 | 1697 |
| 1688 String userAgent = _getHttpVersion(); | 1698 String userAgent = _getHttpVersion(); |
| 1689 | 1699 |
| 1690 _HttpClient(SecurityContext this._context); | 1700 _HttpClient(SecurityContext this._context); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 String query = null; | 1737 String query = null; |
| 1728 if (queryStart < fragmentStart) { | 1738 if (queryStart < fragmentStart) { |
| 1729 query = path.substring(queryStart + 1, fragmentStart); | 1739 query = path.substring(queryStart + 1, fragmentStart); |
| 1730 path = path.substring(0, queryStart); | 1740 path = path.substring(0, queryStart); |
| 1731 } | 1741 } |
| 1732 Uri uri = new Uri(scheme: "http", host: host, port: port, | 1742 Uri uri = new Uri(scheme: "http", host: host, port: port, |
| 1733 path: path, query: query); | 1743 path: path, query: query); |
| 1734 return _openUrl(method, uri); | 1744 return _openUrl(method, uri); |
| 1735 } | 1745 } |
| 1736 | 1746 |
| 1737 Future<HttpClientRequest> openUrl(String method, Uri url) { | 1747 Future<HttpClientRequest> openUrl(String method, Uri url) |
| 1738 return _openUrl(method, url); | 1748 => _openUrl(method, url); |
| 1739 } | |
| 1740 | 1749 |
| 1741 Future<HttpClientRequest> get(String host, int port, String path) | 1750 Future<HttpClientRequest> get(String host, int port, String path) |
| 1742 => open("get", host, port, path); | 1751 => open("get", host, port, path); |
| 1743 | 1752 |
| 1744 Future<HttpClientRequest> getUrl(Uri url) => _openUrl("get", url); | 1753 Future<HttpClientRequest> getUrl(Uri url) => _openUrl("get", url); |
| 1745 | 1754 |
| 1746 Future<HttpClientRequest> post(String host, int port, String path) | 1755 Future<HttpClientRequest> post(String host, int port, String path) |
| 1747 => open("post", host, port, path); | 1756 => open("post", host, port, path); |
| 1748 | 1757 |
| 1749 Future<HttpClientRequest> postUrl(Uri url) => _openUrl("post", url); | 1758 Future<HttpClientRequest> postUrl(Uri url) => _openUrl("post", url); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1792 | 1801 |
| 1793 void addProxyCredentials(String host, | 1802 void addProxyCredentials(String host, |
| 1794 int port, | 1803 int port, |
| 1795 String realm, | 1804 String realm, |
| 1796 HttpClientCredentials cr) { | 1805 HttpClientCredentials cr) { |
| 1797 _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr)); | 1806 _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr)); |
| 1798 } | 1807 } |
| 1799 | 1808 |
| 1800 set findProxy(String f(Uri uri)) => _findProxy = f; | 1809 set findProxy(String f(Uri uri)) => _findProxy = f; |
| 1801 | 1810 |
| 1802 Future<HttpClientRequest> _openUrl(String method, Uri uri) { | 1811 Future<_HttpClientRequest> _openUrl(String method, Uri uri) { |
| 1803 // Ignore any fragments on the request URI. | 1812 // Ignore any fragments on the request URI. |
| 1804 uri = uri.removeFragment(); | 1813 uri = uri.removeFragment(); |
| 1805 | 1814 |
| 1806 if (method == null) { | 1815 if (method == null) { |
| 1807 throw new ArgumentError(method); | 1816 throw new ArgumentError(method); |
| 1808 } | 1817 } |
| 1809 if (method != "CONNECT") { | 1818 if (method != "CONNECT") { |
| 1810 if (uri.host.isEmpty) { | 1819 if (uri.host.isEmpty) { |
| 1811 throw new ArgumentError("No host specified in URI $uri"); | 1820 throw new ArgumentError("No host specified in URI $uri"); |
| 1812 } else if (uri.scheme != "http" && uri.scheme != "https") { | 1821 } else if (uri.scheme != "http" && uri.scheme != "https") { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1827 if (_findProxy != null) { | 1836 if (_findProxy != null) { |
| 1828 // TODO(sgjesse): Keep a map of these as normally only a few | 1837 // TODO(sgjesse): Keep a map of these as normally only a few |
| 1829 // configuration strings will be used. | 1838 // configuration strings will be used. |
| 1830 try { | 1839 try { |
| 1831 proxyConf = new _ProxyConfiguration(_findProxy(uri)); | 1840 proxyConf = new _ProxyConfiguration(_findProxy(uri)); |
| 1832 } catch (error, stackTrace) { | 1841 } catch (error, stackTrace) { |
| 1833 return new Future.error(error, stackTrace); | 1842 return new Future.error(error, stackTrace); |
| 1834 } | 1843 } |
| 1835 } | 1844 } |
| 1836 return _getConnection(uri.host, port, proxyConf, isSecure) | 1845 return _getConnection(uri.host, port, proxyConf, isSecure) |
| 1837 .then((info) { | 1846 .then((_ConnectionInfo info) { |
| 1838 send(info) { | 1847 |
| 1848 _HttpClientRequest send(_ConnectionInfo info) { |
| 1839 return info.connection.send(uri, | 1849 return info.connection.send(uri, |
| 1840 port, | 1850 port, |
| 1841 method.toUpperCase(), | 1851 method.toUpperCase(), |
| 1842 info.proxy); | 1852 info.proxy); |
| 1843 } | 1853 } |
| 1854 |
| 1844 // If the connection was closed before the request was sent, create | 1855 // If the connection was closed before the request was sent, create |
| 1845 // and use another connection. | 1856 // and use another connection. |
| 1846 if (info.connection.closed) { | 1857 if (info.connection.closed) { |
| 1847 return _getConnection(uri.host, port, proxyConf, isSecure) | 1858 return _getConnection(uri.host, port, proxyConf, isSecure) |
| 1848 .then(send); | 1859 .then(send); |
| 1849 } | 1860 } |
| 1850 return send(info); | 1861 return send(info); |
| 1851 }); | 1862 }); |
| 1852 } | 1863 } |
| 1853 | 1864 |
| 1854 Future<HttpClientRequest> _openUrlFromRequest(String method, | 1865 Future<_HttpClientRequest> _openUrlFromRequest(String method, |
| 1855 Uri uri, | 1866 Uri uri, |
| 1856 _HttpClientRequest previous) { | 1867 _HttpClientRequest previous) { |
| 1857 // If the new URI is relative (to either '/' or some sub-path), | 1868 // If the new URI is relative (to either '/' or some sub-path), |
| 1858 // construct a full URI from the previous one. | 1869 // construct a full URI from the previous one. |
| 1859 Uri resolved = previous.uri.resolveUri(uri); | 1870 Uri resolved = previous.uri.resolveUri(uri); |
| 1860 return openUrl(method, resolved).then((_HttpClientRequest request) { | 1871 return _openUrl(method, resolved).then((_HttpClientRequest request) { |
| 1861 | 1872 |
| 1862 request | 1873 request |
| 1863 // Only follow redirects if initial request did. | 1874 // Only follow redirects if initial request did. |
| 1864 ..followRedirects = previous.followRedirects | 1875 ..followRedirects = previous.followRedirects |
| 1865 // Allow same number of redirects. | 1876 // Allow same number of redirects. |
| 1866 ..maxRedirects = previous.maxRedirects; | 1877 ..maxRedirects = previous.maxRedirects; |
| 1867 // Copy headers. | 1878 // Copy headers. |
| 1868 for (var header in previous.headers._headers.keys) { | 1879 for (var header in previous.headers._headers.keys) { |
| 1869 if (request.headers[header] == null) { | 1880 if (request.headers[header] == null) { |
| 1870 request.headers.set(header, previous.headers[header]); | 1881 request.headers.set(header, previous.headers[header]); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1934 // Make sure we go through the event loop before taking a | 1945 // Make sure we go through the event loop before taking a |
| 1935 // connection from the pool. For long-running synchronous code the | 1946 // connection from the pool. For long-running synchronous code the |
| 1936 // server might have closed the connection, so this lowers the | 1947 // server might have closed the connection, so this lowers the |
| 1937 // probability of getting a connection that was already closed. | 1948 // probability of getting a connection that was already closed. |
| 1938 return new Future(() => connect(new HttpException("No proxies given"))); | 1949 return new Future(() => connect(new HttpException("No proxies given"))); |
| 1939 } | 1950 } |
| 1940 | 1951 |
| 1941 _SiteCredentials _findCredentials(Uri url, [_AuthenticationScheme scheme]) { | 1952 _SiteCredentials _findCredentials(Uri url, [_AuthenticationScheme scheme]) { |
| 1942 // Look for credentials. | 1953 // Look for credentials. |
| 1943 _SiteCredentials cr = | 1954 _SiteCredentials cr = |
| 1944 _credentials.fold(null, (prev, value) { | 1955 _credentials.fold(null, (_SiteCredentials prev, value) { |
| 1945 if (value.applies(url, scheme)) { | 1956 var siteCredentials = value as _SiteCredentials; |
| 1957 if (siteCredentials.applies(url, scheme)) { |
| 1946 if (prev == null) return value; | 1958 if (prev == null) return value; |
| 1947 return value.uri.path.length > prev.uri.path.length ? value : prev; | 1959 return siteCredentials.uri.path.length > prev.uri.path.length |
| 1960 ? siteCredentials |
| 1961 : prev; |
| 1948 } else { | 1962 } else { |
| 1949 return prev; | 1963 return prev; |
| 1950 } | 1964 } |
| 1951 }); | 1965 }); |
| 1952 return cr; | 1966 return cr; |
| 1953 } | 1967 } |
| 1954 | 1968 |
| 1955 _ProxyCredentials _findProxyCredentials(_Proxy proxy, | 1969 _ProxyCredentials _findProxyCredentials(_Proxy proxy, |
| 1956 [_AuthenticationScheme scheme]) { | 1970 [_AuthenticationScheme scheme]) { |
| 1957 // Look for credentials. | 1971 // Look for credentials. |
| 1958 var it = _proxyCredentials.iterator; | 1972 var it = _proxyCredentials.iterator; |
| 1959 while (it.moveNext()) { | 1973 while (it.moveNext()) { |
| 1960 if (it.current.applies(proxy, scheme)) { | 1974 if (it.current.applies(proxy, scheme)) { |
| 1961 return it.current; | 1975 return it.current; |
| 1962 } | 1976 } |
| 1963 } | 1977 } |
| 1978 return null; |
| 1964 } | 1979 } |
| 1965 | 1980 |
| 1966 void _removeCredentials(_Credentials cr) { | 1981 void _removeCredentials(_Credentials cr) { |
| 1967 int index = _credentials.indexOf(cr); | 1982 int index = _credentials.indexOf(cr); |
| 1968 if (index != -1) { | 1983 if (index != -1) { |
| 1969 _credentials.removeAt(index); | 1984 _credentials.removeAt(index); |
| 1970 } | 1985 } |
| 1971 } | 1986 } |
| 1972 | 1987 |
| 1973 void _removeProxyCredentials(_Credentials cr) { | 1988 void _removeProxyCredentials(_Credentials cr) { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2159 bool get _isIdle => _state == _IDLE; | 2174 bool get _isIdle => _state == _IDLE; |
| 2160 bool get _isClosing => _state == _CLOSING; | 2175 bool get _isClosing => _state == _CLOSING; |
| 2161 bool get _isDetached => _state == _DETACHED; | 2176 bool get _isDetached => _state == _DETACHED; |
| 2162 | 2177 |
| 2163 String get _serviceTypePath => 'io/http/serverconnections'; | 2178 String get _serviceTypePath => 'io/http/serverconnections'; |
| 2164 String get _serviceTypeName => 'HttpServerConnection'; | 2179 String get _serviceTypeName => 'HttpServerConnection'; |
| 2165 | 2180 |
| 2166 Map _toJSON(bool ref) { | 2181 Map _toJSON(bool ref) { |
| 2167 var name = "${_socket.address.host}:${_socket.port} <-> " | 2182 var name = "${_socket.address.host}:${_socket.port} <-> " |
| 2168 "${_socket.remoteAddress.host}:${_socket.remotePort}"; | 2183 "${_socket.remoteAddress.host}:${_socket.remotePort}"; |
| 2169 var r = { | 2184 var r = <String, dynamic>{ |
| 2170 'id': _servicePath, | 2185 'id': _servicePath, |
| 2171 'type': _serviceType(ref), | 2186 'type': _serviceType(ref), |
| 2172 'name': name, | 2187 'name': name, |
| 2173 'user_name': name, | 2188 'user_name': name, |
| 2174 }; | 2189 }; |
| 2175 if (ref) { | 2190 if (ref) { |
| 2176 return r; | 2191 return r; |
| 2177 } | 2192 } |
| 2178 r['server'] = _httpServer._toJSON(true); | 2193 r['server'] = _httpServer._toJSON(true); |
| 2179 try { | 2194 try { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2405 _idleConnections.forEach((_HttpConnection conn) { | 2420 _idleConnections.forEach((_HttpConnection conn) { |
| 2406 result.idle++; | 2421 result.idle++; |
| 2407 assert(conn._isIdle); | 2422 assert(conn._isIdle); |
| 2408 }); | 2423 }); |
| 2409 return result; | 2424 return result; |
| 2410 } | 2425 } |
| 2411 | 2426 |
| 2412 String get _serviceTypePath => 'io/http/servers'; | 2427 String get _serviceTypePath => 'io/http/servers'; |
| 2413 String get _serviceTypeName => 'HttpServer'; | 2428 String get _serviceTypeName => 'HttpServer'; |
| 2414 | 2429 |
| 2415 Map _toJSON(bool ref) { | 2430 Map<String, dynamic> _toJSON(bool ref) { |
| 2416 var r = { | 2431 var r = <String, dynamic>{ |
| 2417 'id': _servicePath, | 2432 'id': _servicePath, |
| 2418 'type': _serviceType(ref), | 2433 'type': _serviceType(ref), |
| 2419 'name': '${address.host}:$port', | 2434 'name': '${address.host}:$port', |
| 2420 'user_name': '${address.host}:$port', | 2435 'user_name': '${address.host}:$port', |
| 2421 }; | 2436 }; |
| 2422 if (ref) { | 2437 if (ref) { |
| 2423 return r; | 2438 return r; |
| 2424 } | 2439 } |
| 2425 try { | 2440 try { |
| 2426 r['socket'] = _serverSocket._toJSON(true); | 2441 r['socket'] = _serverSocket._toJSON(true); |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2866 const _RedirectInfo(this.statusCode, this.method, this.location); | 2881 const _RedirectInfo(this.statusCode, this.method, this.location); |
| 2867 } | 2882 } |
| 2868 | 2883 |
| 2869 String _getHttpVersion() { | 2884 String _getHttpVersion() { |
| 2870 var version = Platform.version; | 2885 var version = Platform.version; |
| 2871 // Only include major and minor version numbers. | 2886 // Only include major and minor version numbers. |
| 2872 int index = version.indexOf('.', version.indexOf('.') + 1); | 2887 int index = version.indexOf('.', version.indexOf('.') + 1); |
| 2873 version = version.substring(0, index); | 2888 version = version.substring(0, index); |
| 2874 return 'Dart/$version (dart:io)'; | 2889 return 'Dart/$version (dart:io)'; |
| 2875 } | 2890 } |
| OLD | NEW |