From 4ded8a4e2a387441bc7f07af6f2beff07b4e0e4e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 10 Nov 2015 15:27:45 +0100 Subject: [PATCH] Bug 1207798 - add pref to toggle proxy behavior when inaccessible. r=mcmanus --- modules/libpref/init/all.js | 7 +++ netwerk/base/nsProtocolProxyService.cpp | 72 +++++++++++++++++-------- netwerk/base/nsProtocolProxyService.h | 3 ++ 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index cd3ae642ff3..82635d6ad49 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1822,6 +1822,13 @@ pref("network.proxy.socks_remote_dns", false); pref("network.proxy.proxy_over_tls", true); pref("network.proxy.no_proxies_on", "localhost, 127.0.0.1"); pref("network.proxy.failover_timeout", 1800); // 30 minutes + +// If this value is 'true' and a PAC or all given proxies are inaccessible or +// failing, Firefox will attempt to connect to the server DIRECTly. Meaning +// without a proxy. If set 'false', Firefox will not try to access without +// proxy. +pref("network.proxy.use_direct_on_fail", true); + pref("network.online", true); //online/offline pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse, 3-limitForeign #ifdef ANDROID diff --git a/netwerk/base/nsProtocolProxyService.cpp b/netwerk/base/nsProtocolProxyService.cpp index 558f99963dc..65384bb171e 100644 --- a/netwerk/base/nsProtocolProxyService.cpp +++ b/netwerk/base/nsProtocolProxyService.cpp @@ -647,6 +647,12 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch, mProxyOverTLS); } + // when proxies fail, try DIRECT + if (!pref || !strcmp(pref, PROXY_PREF("use_direct_on_fail"))) { + proxy_GetBoolPref(prefBranch, PROXY_PREF("use_direct_on_fail"), + mFailoverToDirect); + } + if (!pref || !strcmp(pref, PROXY_PREF("failover_timeout"))) proxy_GetIntPref(prefBranch, PROXY_PREF("failover_timeout"), mFailedProxyTimeout); @@ -1405,8 +1411,18 @@ nsProtocolProxyService::GetFailoverForProxy(nsIProxyInfo *aProxy, nsresult aStatus, nsIProxyInfo **aResult) { - if (mProxyConfig == PROXYCONFIG_DIRECT) { - return NS_ERROR_NOT_AVAILABLE; + if (mFailoverToDirect) { + if (mProxyConfig == PROXYCONFIG_DIRECT) { + return NS_ERROR_NOT_AVAILABLE; + } + } else { + // We only support failover when a PAC file is configured, either + // directly or via system settings + if (mProxyConfig != PROXYCONFIG_PAC && + mProxyConfig != PROXYCONFIG_WPAD && + mProxyConfig != PROXYCONFIG_SYSTEM) { + return NS_ERROR_NOT_AVAILABLE; + } } // Verify that |aProxy| is one of our nsProxyInfo objects. @@ -2009,32 +2025,46 @@ nsProtocolProxyService::PruneProxyInfo(const nsProtocolInfo &info, bool allDisabled = true; nsProxyInfo *iter; - // remove any disabled proxies. - nsProxyInfo *last = nullptr; - for (iter = head; iter; ) { - if (IsProxyDisabled(iter)) { - // reject! - nsProxyInfo *reject = iter; + if (!mFailoverToDirect) { + for (iter = head; iter; iter = iter->mNext) { + if (!IsProxyDisabled(iter)) { + allDisabled = false; + break; + } + } + } - iter = iter->mNext; - if (last) - last->mNext = iter; + if (!mFailoverToDirect && allDisabled) { + LOG(("All proxies are disabled, so trying all again")); + } else { + // remove any disabled proxies. + nsProxyInfo *last = nullptr; + for (iter = head; iter; ) { + if (IsProxyDisabled(iter)) { + // reject! + nsProxyInfo *reject = iter; + + iter = iter->mNext; + if (last) { + last->mNext = iter; + } else head = iter; - reject->mNext = nullptr; - NS_RELEASE(reject); - continue; + reject->mNext = nullptr; + NS_RELEASE(reject); + continue; + } + + allDisabled = false; + EnableProxy(iter); + + last = iter; + iter = iter->mNext; } - - allDisabled = false; - EnableProxy(iter); - - last = iter; - iter = iter->mNext; } - if (allDisabled) { + if (mFailoverToDirect && allDisabled) { LOG(("All proxies are disabled, try a DIRECT rule!")); *list = nullptr; return; diff --git a/netwerk/base/nsProtocolProxyService.h b/netwerk/base/nsProtocolProxyService.h index 7a2229d8e96..75b75be694f 100644 --- a/netwerk/base/nsProtocolProxyService.h +++ b/netwerk/base/nsProtocolProxyService.h @@ -390,6 +390,9 @@ protected: nsFailedProxyTable mFailedProxies; int32_t mFailedProxyTimeout; + // 'true' means try DIRECT when the proxies fail + bool mFailoverToDirect; + private: nsresult AsyncResolveInternal(nsIChannel *channel, uint32_t flags, nsIProtocolProxyCallback *callback,