fixes bug 243277 "Offline: PAC: fails to load at startup when offline, then never tries again" r=biesi sr=bzbarsky

This commit is contained in:
darin%meer.net 2006-06-13 01:14:20 +00:00
parent 2b2d7ed502
commit 03fdfa5587
3 changed files with 103 additions and 5 deletions

View File

@ -713,7 +713,6 @@ pref("network.ntlm.send-lm-response", false);
pref("network.hosts.nntp_server", "news.mozilla.org");
pref("permissions.default.image", 1); // 1-Accept, 2-Deny, 3-dontAcceptForeign
pref("network.proxy.autoconfig_url", "");
pref("network.proxy.type", 0);
pref("network.proxy.ftp", "");
pref("network.proxy.ftp_port", 0);
@ -737,6 +736,14 @@ pref("network.cookie.alwaysAcceptSessionCookies", false);
pref("network.cookie.prefsMigrated", false);
pref("network.cookie.lifetime.days", 90);
// The PAC file to load. Ignored unless network.proxy.type is 2.
pref("network.proxy.autoconfig_url", "");
// If we cannot load the PAC file, then try again (doubling from interval_min
// until we reach interval_max or the PAC file is successfully loaded).
pref("network.proxy.autoconfig_retry_interval_min", 5); // 5 seconds
pref("network.proxy.autoconfig_retry_interval_max", 300); // 5 minutes
// The following default value is for p3p medium mode.
// See xpfe/components/permissions/content/cookieP3P.xul for the definitions of low/medium/hi
pref("network.cookie.p3p", "ffffaaaa");

View File

@ -41,15 +41,37 @@
#include "nsIDNSService.h"
#include "nsIDNSListener.h"
#include "nsICancelable.h"
#include "nsIAuthPrompt.h"
#include "nsIHttpChannel.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsNetUtil.h"
#include "nsAutoLock.h"
#include "nsAutoPtr.h"
#include "nsIAuthPrompt.h"
#include "nsCRT.h"
#include "prmon.h"
//-----------------------------------------------------------------------------
// Check to see if the underlying request was not an error page in the case of
// a HTTP request. For other types of channels, just return true.
static PRBool
HttpRequestSucceeded(nsIStreamLoader *loader)
{
nsCOMPtr<nsIRequest> request;
loader->GetRequest(getter_AddRefs(request));
PRBool result = PR_TRUE; // default to assuming success
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
if (httpChannel)
httpChannel->GetRequestSucceeded(&result);
return result;
}
//-----------------------------------------------------------------------------
// These objects are stored in nsPACMan::mPendingQ
class PendingPACQuery : public PRCList, public nsIDNSListener
@ -150,6 +172,8 @@ PendingPACQuery::OnLookupComplete(nsICancelable *request,
nsPACMan::nsPACMan()
: mLoadPending(PR_FALSE)
, mShutdown(PR_FALSE)
, mScheduledReload(LL_MAXINT)
, mLoadFailureCount(0)
{
PR_INIT_CLIST(&mPendingQ);
}
@ -181,6 +205,8 @@ nsPACMan::GetProxyForURI(nsIURI *uri, nsACString &result)
return NS_OK;
}
MaybeReloadPAC();
if (IsLoading())
return NS_ERROR_IN_PROGRESS;
if (!mPAC)
@ -198,6 +224,8 @@ nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback)
{
NS_ENSURE_STATE(!mShutdown);
MaybeReloadPAC();
PendingPACQuery *query = new PendingPACQuery(this, uri, callback);
if (!query)
return NS_ERROR_OUT_OF_MEMORY;
@ -226,6 +254,7 @@ nsresult
nsPACMan::LoadPACFromURI(nsIURI *pacURI)
{
NS_ENSURE_STATE(!mShutdown);
NS_ENSURE_ARG(pacURI || mPACURI);
nsCOMPtr<nsIStreamLoader> loader =
do_CreateInstance(NS_STREAMLOADER_CONTRACTID);
@ -249,7 +278,11 @@ nsPACMan::LoadPACFromURI(nsIURI *pacURI)
CancelExistingLoad();
mLoader = loader;
mPACURI = pacURI;
if (pacURI) {
mPACURI = pacURI;
mLoadFailureCount = 0; // reset
}
mScheduledReload = LL_MAXINT;
mPAC = nsnull;
return NS_OK;
}
@ -285,6 +318,43 @@ nsPACMan::StartLoading()
ProcessPendingQ(NS_ERROR_UNEXPECTED);
}
void
nsPACMan::MaybeReloadPAC()
{
if (!mPACURI)
return;
if (PR_Now() > mScheduledReload) {
printf("\n>>> reloading PAC <<<\n\n");
LoadPACFromURI(nsnull);
}
}
void
nsPACMan::OnLoadFailure()
{
PRInt32 minInterval = 5; // 5 seconds
PRInt32 maxInterval = 300; // 5 minutes
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefs) {
prefs->GetIntPref("network.proxy.autoconfig_retry_interval_min",
&minInterval);
prefs->GetIntPref("network.proxy.autoconfig_retry_interval_max",
&maxInterval);
}
PRInt32 interval = minInterval << mLoadFailureCount++; // seconds
if (!interval || interval > maxInterval)
interval = maxInterval;
#ifdef DEBUG
printf("PAC load failure: will retry in %d seconds\n", interval);
#endif
mScheduledReload = PR_Now() + PRInt64(interval) * PR_USEC_PER_SEC;
}
void
nsPACMan::CancelExistingLoad()
{
@ -340,7 +410,7 @@ nsPACMan::OnStreamComplete(nsIStreamLoader *loader,
mLoader = nsnull;
if (NS_SUCCEEDED(status)) {
if (NS_SUCCEEDED(status) && HttpRequestSucceeded(loader)) {
// Get the URI spec used to load this PAC script.
nsCAutoString pacURI;
{
@ -367,6 +437,14 @@ nsPACMan::OnStreamComplete(nsIStreamLoader *loader,
const char *text = (const char *) data;
status = mPAC->Init(pacURI, NS_ConvertASCIItoUTF16(text, dataLen));
}
// Even if the PAC file could not be parsed, we did succeed in loading the
// data for it.
mLoadFailureCount = 0;
} else {
// We were unable to load the PAC file (presumably because of a network
// failure). Try again a little later.
OnLoadFailure();
}
// Reset mPAC if necessary

View File

@ -118,7 +118,8 @@ public:
* processed once the PAC file finishes loading.
*
* @param pacURI
* The nsIURI of the PAC file to load.
* The nsIURI of the PAC file to load. If this parameter is null,
* then the previous PAC URI is simply reloaded.
*/
nsresult LoadPACFromURI(nsIURI *pacURI);
@ -151,6 +152,16 @@ private:
*/
void StartLoading();
/**
* Reload the PAC file if there is reason to.
*/
void MaybeReloadPAC();
/**
* Called when we fail to load the PAC file.
*/
void OnLoadFailure();
/**
* Returns true if the given URI matches the URI of our PAC file.
*/
@ -166,6 +177,8 @@ private:
nsCOMPtr<nsIStreamLoader> mLoader;
PRPackedBool mLoadPending;
PRPackedBool mShutdown;
PRTime mScheduledReload;
PRUint32 mLoadFailureCount;
};
#endif // nsPACMan_h__