author | Steve Workman <sjhworkman@gmail.com> |
Wed, 21 Sep 2011 15:13:45 -0400 | |
changeset 78606 | 1d490722d3331e6bdfc17a40beab470410dec36a |
parent 78605 | 682459dc5a1c613782fba559b2566c85f1c61e36 |
child 78607 | 4495e1f795c218d562205f3364ac1f84aecee220 |
push id | 78 |
push user | clegnitto@mozilla.com |
push date | Fri, 16 Dec 2011 17:32:24 +0000 |
treeherder | mozilla-release@79d24e644fdd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | honzab |
bugs | 72444 |
milestone | 9.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/netwerk/base/src/nsProtocolProxyService.cpp +++ b/netwerk/base/src/nsProtocolProxyService.cpp @@ -301,17 +301,18 @@ NS_IMPL_QUERY_INTERFACE3_CI(nsProtocolPr nsIProtocolProxyService, nsIProtocolProxyService2, nsIObserver) NS_IMPL_CI_INTERFACE_GETTER2(nsProtocolProxyService, nsIProtocolProxyService, nsIProtocolProxyService2) nsProtocolProxyService::nsProtocolProxyService() - : mFilters(nsnull) + : mFilterLocalHosts(PR_FALSE) + , mFilters(nsnull) , mProxyConfig(PROXYCONFIG_DIRECT) , mHTTPProxyPort(-1) , mFTPProxyPort(-1) , mHTTPSProxyPort(-1) , mSOCKSProxyPort(-1) , mSOCKSProxyVersion(4) , mSOCKSProxyRemoteDNS(PR_FALSE) , mPACMan(nsnull) @@ -538,16 +539,22 @@ nsProtocolProxyService::CanUseProxy(nsIU memcpy(&ipv6, &addr.ipv6.ip, sizeof(PRIPv6Addr)); } else { NS_WARNING("unknown address family"); return PR_TRUE; // allow proxying } } + // 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]; if (is_ipaddr != hinfo->is_ipaddr) continue; if (hinfo->port && hinfo->port != port) continue; @@ -844,18 +851,20 @@ nsProtocolProxyService::Resolve(nsIURI * { nsProtocolInfo info; nsresult rv = GetProtocolInfo(uri, &info); if (NS_FAILED(rv)) return rv; 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"); // If the caller didn't want us to invoke PAC, then error out. if (flags & RESOLVE_NON_BLOCKING) return NS_BASE_STREAM_WOULD_BLOCK; @@ -1064,16 +1073,18 @@ nsProtocolProxyService::LoadHostFilters( if (!filters) return; // fail silently... // // 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))) filters++; const char *starthost = filters; const char *endhost = filters + 1; // at least that... const char *portLocation = 0; @@ -1086,28 +1097,37 @@ nsProtocolProxyService::LoadHostFilters( maskLocation = endhost; else if (*endhost == ']') // IPv6 address literals portLocation = 0; endhost++; } 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 : endhost; 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; hinfo->ip.family = PR_AF_INET6; // we always store address as IPv6 hinfo->ip.mask_len = maskLocation ? atoi(maskLocation + 1) : 128; if (hinfo->ip.mask_len == 0) { NS_WARNING("invalid mask");
--- a/netwerk/base/src/nsProtocolProxyService.h +++ b/netwerk/base/src/nsProtocolProxyService.h @@ -348,16 +348,19 @@ protected: FilterLink(PRUint32 p, nsIProtocolProxyFilter *f) : next(nsnull), position(p), filter(f) {} // Chain deletion to simplify cleaning up the filter links ~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; // Points to the start of a sorted by position, singly linked list // of FilterLink objects. FilterLink *mFilters; PRUint32 mProxyConfig;
--- a/netwerk/test/unit/test_protocolproxyservice.js +++ b/netwerk/test/unit/test_protocolproxyservice.js @@ -379,24 +379,98 @@ function run_pac_cancel_test() { prefs.setIntPref("network.proxy.type", 2); prefs.setCharPref("network.proxy.autoconfig_url", pac); var req = pps.asyncResolve(uri, 0, new TestResolveCancelationCallback()); req.cancel(Components.results.NS_ERROR_ABORT); 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(); run_filter_test2(); run_pref_test(); run_pac_test(); // additional tests may be added to run_test_continued } function run_test_continued() { run_pac_cancel_test(); // additional tests may be added to run_test_continued_2 } function run_test_continued_2() { + run_proxy_host_filters_test(); }