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 class _HttpIncoming extends Stream<List<int>> { | 7 class _HttpIncoming extends Stream<List<int>> { |
8 final int _transferLength; | 8 final int _transferLength; |
9 final Completer _dataCompleter = new Completer(); | 9 final Completer _dataCompleter = new Completer(); |
10 Stream<List<int>> _stream; | 10 Stream<List<int>> _stream; |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
937 return result; | 937 return result; |
938 } | 938 } |
939 | 939 |
940 if (_proxy.isDirect) { | 940 if (_proxy.isDirect) { |
941 return uriStartingFromPath(); | 941 return uriStartingFromPath(); |
942 } else { | 942 } else { |
943 if (method == "CONNECT") { | 943 if (method == "CONNECT") { |
944 // For the connect method the request URI is the host:port of | 944 // For the connect method the request URI is the host:port of |
945 // the requested destination of the tunnel (see RFC 2817 | 945 // the requested destination of the tunnel (see RFC 2817 |
946 // section 5.2) | 946 // section 5.2) |
947 return "${uri.domain}:${uri.port}"; | 947 return "${uri.host}:${uri.port}"; |
948 } else { | 948 } else { |
949 if (_httpClientConnection._proxyTunnel) { | 949 if (_httpClientConnection._proxyTunnel) { |
950 return uriStartingFromPath(); | 950 return uriStartingFromPath(); |
951 } else { | 951 } else { |
952 return uri.toString(); | 952 return uri.toString(); |
953 } | 953 } |
954 } | 954 } |
955 } | 955 } |
956 } | 956 } |
957 | 957 |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1146 _ProxyCredentials proxyCreds; // Credentials used to authorize proxy. | 1146 _ProxyCredentials proxyCreds; // Credentials used to authorize proxy. |
1147 _SiteCredentials creds; // Credentials used to authorize this request. | 1147 _SiteCredentials creds; // Credentials used to authorize this request. |
1148 var outgoing = new _HttpOutgoing(_socket); | 1148 var outgoing = new _HttpOutgoing(_socket); |
1149 // Create new request object, wrapping the outgoing connection. | 1149 // Create new request object, wrapping the outgoing connection. |
1150 var request = new _HttpClientRequest(outgoing, | 1150 var request = new _HttpClientRequest(outgoing, |
1151 uri, | 1151 uri, |
1152 method, | 1152 method, |
1153 proxy, | 1153 proxy, |
1154 _httpClient, | 1154 _httpClient, |
1155 this); | 1155 this); |
1156 request.headers.host = uri.domain; | 1156 request.headers.host = uri.host; |
1157 request.headers.port = port; | 1157 request.headers.port = port; |
1158 request.headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip"); | 1158 request.headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip"); |
1159 if (proxy.isAuthenticated) { | 1159 if (proxy.isAuthenticated) { |
1160 // If the proxy configuration contains user information use that | 1160 // If the proxy configuration contains user information use that |
1161 // for proxy basic authorization. | 1161 // for proxy basic authorization. |
1162 String auth = CryptoUtils.bytesToBase64( | 1162 String auth = CryptoUtils.bytesToBase64( |
1163 _encodeString("${proxy.username}:${proxy.password}")); | 1163 _encodeString("${proxy.username}:${proxy.password}")); |
1164 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth"); | 1164 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth"); |
1165 } else if (!proxy.isDirect && _httpClient._proxyCredentials.length > 0) { | 1165 } else if (!proxy.isDirect && _httpClient._proxyCredentials.length > 0) { |
1166 proxyCreds = _httpClient._findProxyCredentials(proxy); | 1166 proxyCreds = _httpClient._findProxyCredentials(proxy); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1269 void close() { | 1269 void close() { |
1270 closed = true; | 1270 closed = true; |
1271 _httpClient._connectionClosed(this); | 1271 _httpClient._connectionClosed(this); |
1272 _streamFuture | 1272 _streamFuture |
1273 // TODO(ajohnsen): Add timeout. | 1273 // TODO(ajohnsen): Add timeout. |
1274 .then((_) => _socket.destroy()); | 1274 .then((_) => _socket.destroy()); |
1275 } | 1275 } |
1276 | 1276 |
1277 Future<_HttpClientConnection> createProxyTunnel(host, port, proxy) { | 1277 Future<_HttpClientConnection> createProxyTunnel(host, port, proxy) { |
1278 _HttpClientRequest request = | 1278 _HttpClientRequest request = |
1279 send(new Uri.fromComponents(domain: host, port: port), | 1279 send(new Uri(host: host, port: port), |
1280 port, | 1280 port, |
1281 "CONNECT", | 1281 "CONNECT", |
1282 proxy); | 1282 proxy); |
1283 if (proxy.isAuthenticated) { | 1283 if (proxy.isAuthenticated) { |
1284 // If the proxy configuration contains user information use that | 1284 // If the proxy configuration contains user information use that |
1285 // for proxy basic authorization. | 1285 // for proxy basic authorization. |
1286 String auth = CryptoUtils.bytesToBase64( | 1286 String auth = CryptoUtils.bytesToBase64( |
1287 _encodeString("${proxy.username}:${proxy.password}")); | 1287 _encodeString("${proxy.username}:${proxy.password}")); |
1288 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth"); | 1288 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth"); |
1289 } | 1289 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1362 c.startTimer(); | 1362 c.startTimer(); |
1363 })); | 1363 })); |
1364 } | 1364 } |
1365 | 1365 |
1366 Future<HttpClientRequest> open(String method, | 1366 Future<HttpClientRequest> open(String method, |
1367 String host, | 1367 String host, |
1368 int port, | 1368 int port, |
1369 String path) { | 1369 String path) { |
1370 // TODO(sgjesse): The path set here can contain both query and | 1370 // TODO(sgjesse): The path set here can contain both query and |
1371 // fragment. They should be cracked and set correctly. | 1371 // fragment. They should be cracked and set correctly. |
1372 return _openUrl(method, new Uri.fromComponents( | 1372 return _openUrl(method, new Uri( |
1373 scheme: "http", domain: host, port: port, path: path)); | 1373 scheme: "http", host: host, port: port, path: path)); |
1374 } | 1374 } |
1375 | 1375 |
1376 Future<HttpClientRequest> openUrl(String method, Uri url) { | 1376 Future<HttpClientRequest> openUrl(String method, Uri url) { |
1377 return _openUrl(method, url); | 1377 return _openUrl(method, url); |
1378 } | 1378 } |
1379 | 1379 |
1380 Future<HttpClientRequest> get(String host, | 1380 Future<HttpClientRequest> get(String host, |
1381 int port, | 1381 int port, |
1382 String path) { | 1382 String path) { |
1383 return open("get", host, port, path); | 1383 return open("get", host, port, path); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1440 _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr)); | 1440 _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr)); |
1441 } | 1441 } |
1442 | 1442 |
1443 set findProxy(String f(Uri uri)) => _findProxy = f; | 1443 set findProxy(String f(Uri uri)) => _findProxy = f; |
1444 | 1444 |
1445 Future<HttpClientRequest> _openUrl(String method, Uri uri) { | 1445 Future<HttpClientRequest> _openUrl(String method, Uri uri) { |
1446 if (method == null) { | 1446 if (method == null) { |
1447 throw new ArgumentError(method); | 1447 throw new ArgumentError(method); |
1448 } | 1448 } |
1449 if (method != "CONNECT") { | 1449 if (method != "CONNECT") { |
1450 if (uri.domain.isEmpty || | 1450 if (uri.host.isEmpty || |
1451 (uri.scheme != "http" && uri.scheme != "https")) { | 1451 (uri.scheme != "http" && uri.scheme != "https")) { |
1452 throw new ArgumentError("Unsupported scheme '${uri.scheme}' in $uri"); | 1452 throw new ArgumentError("Unsupported scheme '${uri.scheme}' in $uri"); |
1453 } | 1453 } |
1454 } | 1454 } |
1455 | 1455 |
1456 bool isSecure = (uri.scheme == "https"); | 1456 bool isSecure = (uri.scheme == "https"); |
1457 int port = uri.port; | 1457 int port = uri.port; |
1458 if (port == 0) { | 1458 if (port == 0) { |
1459 port = isSecure ? | 1459 port = isSecure ? |
1460 HttpClient.DEFAULT_HTTPS_PORT : | 1460 HttpClient.DEFAULT_HTTPS_PORT : |
1461 HttpClient.DEFAULT_HTTP_PORT; | 1461 HttpClient.DEFAULT_HTTP_PORT; |
1462 } | 1462 } |
1463 // Check to see if a proxy server should be used for this connection. | 1463 // Check to see if a proxy server should be used for this connection. |
1464 var proxyConf = const _ProxyConfiguration.direct(); | 1464 var proxyConf = const _ProxyConfiguration.direct(); |
1465 if (_findProxy != null) { | 1465 if (_findProxy != null) { |
1466 // TODO(sgjesse): Keep a map of these as normally only a few | 1466 // TODO(sgjesse): Keep a map of these as normally only a few |
1467 // configuration strings will be used. | 1467 // configuration strings will be used. |
1468 try { | 1468 try { |
1469 proxyConf = new _ProxyConfiguration(_findProxy(uri)); | 1469 proxyConf = new _ProxyConfiguration(_findProxy(uri)); |
1470 } catch (error, stackTrace) { | 1470 } catch (error, stackTrace) { |
1471 return new Future.error(error, stackTrace); | 1471 return new Future.error(error, stackTrace); |
1472 } | 1472 } |
1473 } | 1473 } |
1474 return _getConnection(uri.domain, port, proxyConf, isSecure) | 1474 return _getConnection(uri.host, port, proxyConf, isSecure) |
1475 .then((info) { | 1475 .then((info) { |
1476 send(info) { | 1476 send(info) { |
1477 return info.connection.send(uri, | 1477 return info.connection.send(uri, |
1478 port, | 1478 port, |
1479 method.toUpperCase(), | 1479 method.toUpperCase(), |
1480 info.proxy); | 1480 info.proxy); |
1481 } | 1481 } |
1482 // If the connection was closed before the request was sent, create | 1482 // If the connection was closed before the request was sent, create |
1483 // and use another connection. | 1483 // and use another connection. |
1484 if (info.connection.closed) { | 1484 if (info.connection.closed) { |
1485 return _getConnection(uri.domain, port, proxyConf, isSecure) | 1485 return _getConnection(uri.host, port, proxyConf, isSecure) |
1486 .then(send); | 1486 .then(send); |
1487 } | 1487 } |
1488 return send(info); | 1488 return send(info); |
1489 }); | 1489 }); |
1490 } | 1490 } |
1491 | 1491 |
1492 Future<HttpClientRequest> _openUrlFromRequest(String method, | 1492 Future<HttpClientRequest> _openUrlFromRequest(String method, |
1493 Uri uri, | 1493 Uri uri, |
1494 _HttpClientRequest previous) { | 1494 _HttpClientRequest previous) { |
1495 // If the new URI is relative (to either '/' or some sub-path), | 1495 // If the new URI is relative (to either '/' or some sub-path), |
1496 // construct a full URI from the previous one. | 1496 // construct a full URI from the previous one. |
1497 // See http://tools.ietf.org/html/rfc3986#section-4.2 | 1497 // See http://tools.ietf.org/html/rfc3986#section-4.2 |
1498 replaceComponents({scheme, domain, port, path}) { | 1498 replaceComponents({scheme, host, port, path}) { |
1499 uri = new Uri.fromComponents( | 1499 uri = new Uri( |
1500 scheme: scheme != null ? scheme : uri.scheme, | 1500 scheme: scheme != null ? scheme : uri.scheme, |
Lasse Reichstein Nielsen
2013/05/28 08:45:33
What if domain is "", will it break anything?
Søren Gjesse
2013/05/28 13:33:26
I don't think so - nothing changed here.
| |
1501 domain: domain != null ? domain : uri.domain, | 1501 host: host != null ? host : uri.host, |
1502 port: port != null ? port : uri.port, | 1502 port: port != null ? port : uri.port, |
1503 path: path != null ? path : uri.path, | 1503 path: path != null ? path : uri.path, |
1504 query: uri.query, | 1504 query: uri.query, |
1505 fragment: uri.fragment); | 1505 fragment: uri.fragment); |
1506 } | 1506 } |
1507 if (uri.domain == '') { | 1507 if (uri.host.isEmpty) { |
1508 replaceComponents(domain: previous.uri.domain, port: previous.uri.port); | 1508 replaceComponents(host: previous.uri.host, port: previous.uri.port); |
1509 } | 1509 } |
1510 if (uri.scheme == '') { | 1510 if (uri.scheme.isEmpty) { |
1511 replaceComponents(scheme: previous.uri.scheme); | 1511 replaceComponents(scheme: previous.uri.scheme); |
1512 } | 1512 } |
1513 if (!uri.path.startsWith('/') && previous.uri.path.startsWith('/')) { | 1513 if (!uri.path.startsWith('/') && previous.uri.path.startsWith('/')) { |
1514 var absolute = new Path.raw(previous.uri.path).directoryPath; | 1514 var absolute = new Path.raw(previous.uri.path).directoryPath; |
1515 absolute = absolute.join(new Path.raw(uri.path)); | 1515 absolute = absolute.join(new Path.raw(uri.path)); |
1516 replaceComponents(path: absolute.canonicalize().toString()); | 1516 replaceComponents(path: absolute.canonicalize().toString()); |
1517 } | 1517 } |
1518 return openUrl(method, uri).then((_HttpClientRequest request) { | 1518 return openUrl(method, uri).then((_HttpClientRequest request) { |
1519 // Only follow redirects if initial request did. | 1519 // Only follow redirects if initial request did. |
1520 request.followRedirects = previous.followRedirects; | 1520 request.followRedirects = previous.followRedirects; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1667 _proxyCredentials.removeAt(index); | 1667 _proxyCredentials.removeAt(index); |
1668 } | 1668 } |
1669 } | 1669 } |
1670 | 1670 |
1671 static String _findProxyFromEnvironment(Uri url, | 1671 static String _findProxyFromEnvironment(Uri url, |
1672 Map<String, String> environment) { | 1672 Map<String, String> environment) { |
1673 checkNoProxy(String option) { | 1673 checkNoProxy(String option) { |
1674 if (option == null) return null; | 1674 if (option == null) return null; |
1675 Iterator<String> names = option.split(",").map((s) => s.trim()).iterator; | 1675 Iterator<String> names = option.split(",").map((s) => s.trim()).iterator; |
1676 while (names.moveNext()) { | 1676 while (names.moveNext()) { |
1677 if (url.domain.endsWith(names.current)) { | 1677 if (url.host.endsWith(names.current)) { |
1678 return "DIRECT"; | 1678 return "DIRECT"; |
1679 } | 1679 } |
1680 } | 1680 } |
1681 return null; | 1681 return null; |
1682 } | 1682 } |
1683 | 1683 |
1684 checkProxy(String option) { | 1684 checkProxy(String option) { |
1685 if (option == null) return null; | 1685 if (option == null) return null; |
1686 int pos = option.indexOf("://"); | 1686 int pos = option.indexOf("://"); |
1687 if (pos >= 0) { | 1687 if (pos >= 0) { |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2163 } | 2163 } |
2164 | 2164 |
2165 class _SiteCredentials extends _Credentials { | 2165 class _SiteCredentials extends _Credentials { |
2166 Uri uri; | 2166 Uri uri; |
2167 | 2167 |
2168 _SiteCredentials(this.uri, realm, _HttpClientCredentials creds) | 2168 _SiteCredentials(this.uri, realm, _HttpClientCredentials creds) |
2169 : super(creds, realm); | 2169 : super(creds, realm); |
2170 | 2170 |
2171 bool applies(Uri uri, _AuthenticationScheme scheme) { | 2171 bool applies(Uri uri, _AuthenticationScheme scheme) { |
2172 if (scheme != null && credentials.scheme != scheme) return false; | 2172 if (scheme != null && credentials.scheme != scheme) return false; |
2173 if (uri.domain != this.uri.domain) return false; | 2173 if (uri.host != this.uri.host) return false; |
2174 int thisPort = | 2174 int thisPort = |
2175 this.uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : this.uri.port; | 2175 this.uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : this.uri.port; |
2176 int otherPort = uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : uri.port; | 2176 int otherPort = uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : uri.port; |
2177 if (otherPort != thisPort) return false; | 2177 if (otherPort != thisPort) return false; |
2178 return uri.path.startsWith(this.uri.path); | 2178 return uri.path.startsWith(this.uri.path); |
2179 } | 2179 } |
2180 | 2180 |
2181 void authorize(HttpClientRequest request) { | 2181 void authorize(HttpClientRequest request) { |
2182 // Digest credentials cannot be used without a nonce from the | 2182 // Digest credentials cannot be used without a nonce from the |
2183 // server. | 2183 // server. |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2336 | 2336 |
2337 | 2337 |
2338 class _RedirectInfo implements RedirectInfo { | 2338 class _RedirectInfo implements RedirectInfo { |
2339 const _RedirectInfo(int this.statusCode, | 2339 const _RedirectInfo(int this.statusCode, |
2340 String this.method, | 2340 String this.method, |
2341 Uri this.location); | 2341 Uri this.location); |
2342 final int statusCode; | 2342 final int statusCode; |
2343 final String method; | 2343 final String method; |
2344 final Uri location; | 2344 final Uri location; |
2345 } | 2345 } |
OLD | NEW |