Bug 72444: Option to bypass proxy server for local addresses. r=honzab

This commit is contained in:
Steve Workman 2011-09-21 15:13:45 -04:00
parent 9282c23db2
commit 309c5c36ae
3 changed files with 104 additions and 7 deletions

View File

@ -306,7 +306,8 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsProtocolProxyService,
nsIProtocolProxyService2)
nsProtocolProxyService::nsProtocolProxyService()
: mFilters(nsnull)
: mFilterLocalHosts(PR_FALSE)
, mFilters(nsnull)
, mProxyConfig(PROXYCONFIG_DIRECT)
, mHTTPProxyPort(-1)
, mFTPProxyPort(-1)
@ -543,6 +544,12 @@ nsProtocolProxyService::CanUseProxy(nsIURI *aURI, PRInt32 defaultPort)
}
}
// Don't use proxy for local hosts (plain hostname, no dots)
if (!is_ipaddr && mFilterLocalHosts && (kNotFound == host.FindChar('.'))) {
LOG(("Not using proxy for this local host [%s]!\n", host.get()));
return PR_FALSE; // don't allow proxying
}
PRInt32 index = -1;
while (++index < PRInt32(mHostFiltersArray.Length())) {
HostInfo *hinfo = mHostFiltersArray[index];
@ -849,8 +856,10 @@ nsProtocolProxyService::Resolve(nsIURI *uri, PRUint32 flags,
PRBool usePAC;
rv = Resolve_Internal(uri, info, flags, &usePAC, result);
if (NS_FAILED(rv))
if (NS_FAILED(rv)) {
LOG(("Resolve_Internal returned rv(0x%08x)\n", rv));
return rv;
}
if (usePAC && mPACMan) {
NS_ASSERTION(*result == nsnull, "we should not have a result yet");
@ -1069,6 +1078,8 @@ nsProtocolProxyService::LoadHostFilters(const char *filters)
// filter = ( host | domain | ipaddr ["/" mask] ) [":" port]
// filters = filter *( "," LWS filter)
//
// Reset mFilterLocalHosts - will be set to true if "<local>" is in pref string
mFilterLocalHosts = PR_FALSE;
while (*filters) {
// skip over spaces and ,
while (*filters && (*filters == ',' || IS_ASCII_SPACE(*filters)))
@ -1091,11 +1102,6 @@ nsProtocolProxyService::LoadHostFilters(const char *filters)
filters = endhost; // advance iterator up front
HostInfo *hinfo = new HostInfo();
if (!hinfo)
return; // fail silently
hinfo->port = portLocation ? atoi(portLocation + 1) : 0;
// locate end of host
const char *end = maskLocation ? maskLocation :
portLocation ? portLocation :
@ -1103,6 +1109,20 @@ nsProtocolProxyService::LoadHostFilters(const char *filters)
nsCAutoString str(starthost, end - starthost);
// If the current host filter is "<local>", then all local (i.e.
// no dots in the hostname) hosts should bypass the proxy
if (str.EqualsIgnoreCase("<local>")) {
mFilterLocalHosts = PR_TRUE;
LOG(("loaded filter for local hosts "
"(plain host names, no dots)\n"));
// Continue to next host filter;
continue;
}
// For all other host filters, create HostInfo object and add to list
HostInfo *hinfo = new HostInfo();
hinfo->port = portLocation ? atoi(portLocation + 1) : 0;
PRNetAddr addr;
if (PR_StringToNetAddr(str.get(), &addr) == PR_SUCCESS) {
hinfo->is_ipaddr = PR_TRUE;

View File

@ -353,6 +353,9 @@ protected:
~FilterLink() { if (next) delete next; }
};
// Indicates if local hosts (plain hostnames, no dots) should use the proxy
PRBool mFilterLocalHosts;
// Holds an array of HostInfo objects
nsTArray<nsAutoPtr<HostInfo> > mHostFiltersArray;

View File

@ -384,6 +384,79 @@ function run_pac_cancel_test() {
do_test_pending();
}
function check_host_filters(hostList, bShouldBeFiltered) {
var uri;
var proxy;
for (var i=0; i<hostList.length; i++) {
dump("*** uri=" + hostList[i] + " bShouldBeFiltered=" + bShouldBeFiltered + "\n");
uri = ios.newURI(hostList, null, null);
proxy = pps.resolve(uri, 0);
if (bShouldBeFiltered) {
do_check_eq(proxy, null);
} else {
do_check_neq(proxy, null);
// Just to be sure, let's check that the proxy is correct
// - this should match the proxy setup in the calling function
check_proxy(proxy, "http", "foopy", 8080, 0, -1, false);
}
}
}
// Verify that hists in the host filter list are not proxied
// refers to "network.proxy.no_proxies_on"
function run_proxy_host_filters_test() {
// Get prefs object from DOM
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
// Setup a basic HTTP proxy configuration
// - pps.resolve() needs this to return proxy info for non-filtered hosts
prefs.setIntPref("network.proxy.type", 1);
prefs.setCharPref("network.proxy.http", "foopy");
prefs.setIntPref("network.proxy.http_port", 8080);
// Setup host filter list string for "no_proxies_on"
var hostFilterList = "www.mozilla.org, www.google.com, www.apple.com, "
+ ".domain, .domain2.org"
prefs.setCharPref("network.proxy.no_proxies_on", hostFilterList);
do_check_eq(prefs.getCharPref("network.proxy.no_proxies_on"), hostFilterList);
var rv;
// Check the hosts that should be filtered out
var uriStrFilterList = [ "http://www.mozilla.org/",
"http://www.google.com/",
"http://www.apple.com/",
"http://somehost.domain/",
"http://someotherhost.domain/",
"http://somehost.domain2.org/",
"http://somehost.subdomain.domain2.org/" ];
check_host_filters(uriStrFilterList, true);
// Check the hosts that should be proxied
var uriStrUseProxyList = [ "http://www.mozilla.com/",
"http://mail.google.com/",
"http://somehost.domain.co.uk/",
"http://somelocalhost/" ];
check_host_filters(uriStrUseProxyList, false);
// Set no_proxies_on to include local hosts
prefs.setCharPref("network.proxy.no_proxies_on", hostFilterList + ", <local>");
do_check_eq(prefs.getCharPref("network.proxy.no_proxies_on"),
hostFilterList + ", <local>");
// Amend lists - move local domain to filtered list
uriStrFilterList.push(uriStrUseProxyList.pop());
check_host_filters(uriStrFilterList, true);
check_host_filters(uriStrUseProxyList, false);
// Cleanup
prefs.setCharPref("network.proxy.no_proxies_on", "");
do_check_eq(prefs.getCharPref("network.proxy.no_proxies_on"), "");
do_test_finished();
}
function run_test() {
register_test_protocol_handler();
run_filter_test();
@ -399,4 +472,5 @@ function run_test_continued() {
}
function run_test_continued_2() {
run_proxy_host_filters_test();
}