mirror of
https://github.com/dart-lang/sdk
synced 2024-09-23 00:23:57 +00:00
Add a function for finding the HTTP proxy server from environment variables
R=ager@google.com BUG=https://code.google.com/p/dart/issues/detail?id=5468 Review URL: https://codereview.chromium.org//12866005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@20202 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
076fa4c0ba
commit
484a94834b
|
@ -866,9 +866,63 @@ abstract class HttpClient {
|
|||
* separated by semicolons, e.g.
|
||||
*
|
||||
* "PROXY host:port; PROXY host2:port2; DIRECT"
|
||||
*
|
||||
* The static function [findProxyFromEnvironment] on this class can
|
||||
* be used to implement proxy server resolving based on environment
|
||||
* variables.
|
||||
*/
|
||||
set findProxy(String f(Uri url));
|
||||
|
||||
/**
|
||||
* Function for resolving the proxy server to be used for a HTTP
|
||||
* connection from the proxy configuration specified through
|
||||
* environment variables.
|
||||
*
|
||||
* The following environment variables are taken into account:
|
||||
*
|
||||
* * http_proxy
|
||||
* * https_proxy
|
||||
* * no_proxy
|
||||
* * HTTP_PROXY
|
||||
* * HTTPS_PROXY
|
||||
* * NO_PROXY
|
||||
*
|
||||
* [:http_proxy:] and [:HTTP_PROXY:] specify the proxy server to use for
|
||||
* http:// urls. Use the format [:hostname:port:]. If no port is used a
|
||||
* default of 1080 will be used. If both are set the lower case one takes
|
||||
* precedence.
|
||||
*
|
||||
* [:https_proxy:] and [:HTTPS_PROXY:] specify the proxy server to use for
|
||||
* https:// urls. Use the format [:hostname:port:]. If no port is used a
|
||||
* default of 1080 will be used. If both are set the lower case one takes
|
||||
* precedence.
|
||||
*
|
||||
* [:no_proxy:] and [:NO_PROXY:] specify a comma separated list of
|
||||
* postfixes of hostnames for which not to use the proxy
|
||||
* server. E.g. the value "localhost,127.0.0.1" will make requests
|
||||
* to both "localhost" and "127.0.0.1" not use a proxy. If both are set
|
||||
* the lower case one takes precedence.
|
||||
*
|
||||
* To activate this way of resolving proxies assign this function to
|
||||
* the [findProxy] property on the [HttpClient].
|
||||
*
|
||||
* HttpClient client = new HttpClient();
|
||||
* client.findProxy = HttpClient.findProxyFromEnvironment;
|
||||
*
|
||||
* If you don't want to use the system environment you can use a
|
||||
* different one by wrapping the function.
|
||||
*
|
||||
* HttpClient client = new HttpClient();
|
||||
* client.findProxy = (url) {
|
||||
* return HttpClient.findProxyFromEnvironment(
|
||||
* url, {"http_proxy": ..., "no_proxy": ...});
|
||||
* }
|
||||
*/
|
||||
static String findProxyFromEnvironment(Uri url,
|
||||
{Map<String, String> environment}) {
|
||||
return _HttpClient._findProxyFromEnvironment(url, environment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the HTTP client. If [force] is [:false:] (the default)
|
||||
* the [:HttpClient:] will be kept alive until all active
|
||||
|
|
|
@ -1258,6 +1258,56 @@ class _HttpClient implements HttpClient {
|
|||
_credentials.removeAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
static String _findProxyFromEnvironment(Uri url,
|
||||
Map<String, String> environment) {
|
||||
checkNoProxy(String option) {
|
||||
if (option == null) return null;
|
||||
Iterator<String> names = option.split(",").map((s) => s.trim()).iterator;
|
||||
while (names.moveNext()) {
|
||||
if (url.domain.endsWith(names.current)) {
|
||||
return "DIRECT";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
checkProxy(String option) {
|
||||
if (option == null) return null;
|
||||
int pos = option.indexOf("://");
|
||||
if (pos >= 0) {
|
||||
option = option.substring(pos + 3);
|
||||
}
|
||||
if (option.indexOf(":") == -1) option = "$option:1080";
|
||||
return "PROXY $option";
|
||||
}
|
||||
|
||||
// Default to using the process current environment.
|
||||
if (environment == null) environment = Platform.environment;
|
||||
|
||||
String proxyCfg;
|
||||
|
||||
String noProxy = environment["no_proxy"];
|
||||
if (noProxy == null) noProxy = environment["NO_PROXY"];
|
||||
if ((proxyCfg = checkNoProxy(noProxy)) != null) {
|
||||
return proxyCfg;
|
||||
}
|
||||
|
||||
if (url.scheme == "http") {
|
||||
String proxy = environment["http_proxy"];
|
||||
if (proxy == null) proxy = environment["HTTP_PROXY"];
|
||||
if ((proxyCfg = checkProxy(proxy)) != null) {
|
||||
return proxyCfg;
|
||||
}
|
||||
} else if (url.scheme == "https") {
|
||||
String proxy = environment["https_proxy"];
|
||||
if (proxy == null) proxy = environment["HTTPS_PROXY"];
|
||||
if ((proxyCfg = checkProxy(proxy)) != null) {
|
||||
return proxyCfg;
|
||||
}
|
||||
}
|
||||
return "DIRECT";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
59
tests/standalone/io/http_proxy_configuration_test.dart
Normal file
59
tests/standalone/io/http_proxy_configuration_test.dart
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "dart:uri";
|
||||
|
||||
expect(expected, String uri, environment) {
|
||||
Expect.equals(expected,
|
||||
HttpClient.findProxyFromEnvironment(Uri.parse(uri),
|
||||
environment: environment));
|
||||
}
|
||||
|
||||
expectDirect(String uri, environment) {
|
||||
Expect.equals("DIRECT",
|
||||
HttpClient.findProxyFromEnvironment(Uri.parse(uri),
|
||||
environment: environment));
|
||||
}
|
||||
|
||||
main() {
|
||||
expectDirect("http://www.google.com", {});
|
||||
expect("PROXY www.proxy.com:1080",
|
||||
"http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com"});
|
||||
expect("PROXY www.proxys.com:1080",
|
||||
"https://www.google.com",
|
||||
{"https_proxy": "www.proxys.com"});
|
||||
expect("PROXY www.proxy.com:8080",
|
||||
"http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080"});
|
||||
expect("PROXY www.proxys.com:8080",
|
||||
"https://www.google.com",
|
||||
{"https_proxy": "www.proxys.com:8080"});
|
||||
expect("PROXY www.proxy.com:8080",
|
||||
"http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080",
|
||||
"https_proxy": "www.proxy.com:8080"});
|
||||
expect("PROXY www.proxys.com:8080",
|
||||
"https://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080",
|
||||
"https_proxy": "www.proxys.com:8080"});
|
||||
expectDirect("http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": "www.google.com"});
|
||||
expectDirect("http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": "google.com"});
|
||||
expectDirect("http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ".com"});
|
||||
expectDirect("http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ",, , www.google.edu,,.com "});
|
||||
expectDirect("http://www.google.edu",
|
||||
{"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ",, , www.google.edu,,.com "});
|
||||
expectDirect("http://www.google.com",
|
||||
{"https_proxy": "www.proxy.com:8080"});
|
||||
}
|
|
@ -232,6 +232,7 @@ void testProxy() {
|
|||
testProxyDoneCount++;
|
||||
if (testProxyDoneCount == proxy.length * 2) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
Expect.equals(proxy.length, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
|
@ -311,6 +312,56 @@ void testProxyChain() {
|
|||
});
|
||||
}
|
||||
|
||||
int testProxyFromEnviromentDoneCount = 0;
|
||||
void testProxyFromEnviroment() {
|
||||
setupProxyServer().then((proxyServer) {
|
||||
setupServer(1).then((server) {
|
||||
setupServer(1, secure: true).then((secureServer) {
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
client.findProxy = (Uri uri) {
|
||||
return HttpClient.findProxyFromEnvironment(
|
||||
uri,
|
||||
environment: {"http_proxy": "localhost:${proxyServer.port}",
|
||||
"https_proxy": "localhost:${proxyServer.port}"});
|
||||
};
|
||||
|
||||
const int loopCount = 5;
|
||||
for (int i = 0; i < loopCount; i++) {
|
||||
test(bool secure) {
|
||||
String url = secure
|
||||
? "https://localhost:${secureServer.port}/$i"
|
||||
: "http://127.0.0.1:${server.port}/$i";
|
||||
|
||||
client.postUrl(Uri.parse(url))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
testProxyFromEnviromentDoneCount++;
|
||||
if (testProxyFromEnviromentDoneCount == loopCount * 2) {
|
||||
Expect.equals(loopCount, server.requestCount);
|
||||
Expect.equals(loopCount, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
test(false);
|
||||
test(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
int testRealProxyDoneCount = 0;
|
||||
void testRealProxy() {
|
||||
setupServer(1).then((server) {
|
||||
|
@ -363,6 +414,7 @@ main() {
|
|||
testDirectProxy();
|
||||
testProxy();
|
||||
testProxyChain();
|
||||
testProxyFromEnviroment();
|
||||
// This test is not normally run. It can be used for locally testing
|
||||
// with a real proxy server (e.g. Apache).
|
||||
//testRealProxy();
|
||||
|
|
Loading…
Reference in a new issue