Fixes for bug 70348 autoconfig feature

r=bnesse, sr=alecf and a=dbaron
This commit is contained in:
mitesh%netscape.com 2001-06-23 22:22:27 +00:00
Родитель e34f882502
Коммит 293528ba7d
3 изменённых файлов: 152 добавлений и 153 удалений

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
@ -40,35 +40,33 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsAutoConfig, nsIAutoConfig, nsITimerCallback, nsI
nsAutoConfig::nsAutoConfig()
{
/* member initializers and constructor code */
NS_INIT_REFCNT();
}
nsresult nsAutoConfig::Init()
{
/* member initializers and constructor code */
// member initializers and constructor code
nsresult rv=NS_OK;
nsresult rv;
mLoaded = PR_FALSE;
// Registering the object as an observer to the profile-after-change topic
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
rv = observerService->AddObserver(this,NS_LITERAL_STRING("profile-after-change").get());
if (NS_FAILED(rv))
return rv;
if (observerService) {
rv = observerService->AddObserver(this,
NS_LITERAL_STRING("profile-after-change").get());
if (NS_FAILED(rv)) return rv;
}
nsCOMPtr<nsIPrefService> prefs =
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
rv = prefs->GetBranch(nsnull,getter_AddRefs(mPrefBranch));
if (NS_FAILED(rv)) return rv;
return NS_OK;
return rv;
}
nsAutoConfig::~nsAutoConfig()
@ -77,9 +75,7 @@ nsAutoConfig::~nsAutoConfig()
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
if (observerService)
rv = observerService->RemoveObserver(this,
NS_LITERAL_STRING("profile-after-change").get());
rv = observerService->RemoveObserver(this,NS_LITERAL_STRING("profile-after-change").get());
}
@ -99,16 +95,13 @@ nsAutoConfig::OnDataAvailable(nsIRequest* request,
{
PRUint32 amt, size;
nsresult rv;
char buf[1025];
char buf[1024];
while (aLength) {
size = PR_MIN(aLength, sizeof(buf));
rv = aIStream->Read(buf, size, &amt);
if (NS_FAILED(rv)) {
NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv),
"The stream should never block.");
if (NS_FAILED(rv))
return rv;
}
mBuf.Append(buf,amt);
aLength -= amt;
}
@ -120,7 +113,6 @@ NS_IMETHODIMP
nsAutoConfig::OnStopRequest(nsIRequest* request, nsISupports* context,
nsresult aStatus)
{
nsresult rv;
// If the request is failed, go read the failover.jsc file
@ -128,7 +120,7 @@ nsAutoConfig::OnStopRequest(nsIRequest* request, nsISupports* context,
return readOfflineFile();
}
//Checking for the http response, if failure go read the failover file.
// Checking for the http response, if failure go read the failover file.
nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(request));
if (pHTTPCon) {
PRUint32 httpStatus;
@ -138,26 +130,33 @@ nsAutoConfig::OnStopRequest(nsIRequest* request, nsISupports* context,
}
// Send the autoconfig.jsc to javascript engine.
PRBool success = PREF_EvaluateConfigScript(mBuf.get(), mBuf.Length(),nsnull,
PR_FALSE,PR_TRUE,PR_FALSE);
PRBool success = PREF_EvaluateConfigScript(mBuf.get(), mBuf.Length(),
nsnull, PR_FALSE,PR_TRUE,
PR_FALSE);
if (success) {
rv = writeFailoverFile(); /* Write the autoconfig.jsc to
failover.jsc (cached copy) */
if(NS_FAILED(rv))
// Write the autoconfig.jsc to failover.jsc (cached copy)
rv = writeFailoverFile();
if (NS_FAILED(rv))
NS_WARNING("Error writing failover.jsc file");
// Clean up the previous read.
// If there is a timer, these methods will be called again.
mBuf.Truncate(0);
mLoaded = PR_TRUE; //Releasing the deadlock
// Releasing the lock to allow the main thread to start execution
mLoaded = PR_TRUE;
return NS_OK;
}
else {
NS_WARNING("Error reading autoconfig.jsc from the network, reading the offline version");
// Clean up the previous read so it will be ready for
// the next updated read.
mBuf.Truncate(0);
return readOfflineFile();
}
// there is an error in parsing of the autoconfig file.
NS_WARNING("Error reading autoconfig.jsc from the network, reading the offline version");
// Clean up the previous read so it will be ready for
// the next updated read.
mBuf.Truncate(0);
return readOfflineFile();
}
// Notify method as a TimerCallBack function
@ -170,36 +169,34 @@ NS_IMETHODIMP_(void) nsAutoConfig::Notify(nsITimer *timer)
after the profile is set. It doesn't do anything but return NS_OK during the
creation time. Second time it calls DownloadAutoCfg().
*/
NS_IMETHODIMP nsAutoConfig::Observe(nsISupports *aSubject, const PRUnichar *aTopic, const PRUnichar *someData)
NS_IMETHODIMP nsAutoConfig::Observe(nsISupports *aSubject,
const PRUnichar *aTopic,
const PRUnichar *someData)
{
nsresult rv = NS_OK;
if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("profile-after-change").get()))
{
// Getting the current profile name since we already have the
// pointer to the object.
nsCOMPtr<nsIProfile> profile = do_QueryInterface(aSubject);
if (profile) {
nsXPIDLString profileName;
rv = profile->GetCurrentProfile(getter_Copies(profileName));
if (NS_SUCCEEDED(rv))
// setting the member variable to the current profile name
mCurrProfile.AssignWithConversion(profileName);
else
return rv;
}
return DownloadAutoCfg();
}
else if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("app-startup").get()))
{
// This is the object instantiation, do nothing and return NS_OK;
return NS_OK;
nsresult rv=NS_OK;
if (!nsCRT::strcmp(aTopic,
NS_LITERAL_STRING("profile-after-change").get())) {
// Getting the current profile name since we already have the
// pointer to the object.
nsCOMPtr<nsIProfile> profile = do_QueryInterface(aSubject);
if (profile) {
nsXPIDLString profileName;
rv = profile->GetCurrentProfile(getter_Copies(profileName));
if (NS_FAILED(rv))
return rv;
// setting the member variable to the current profile name
mCurrProfile = NS_ConvertUCS2toUTF8(profileName);
}
return NS_OK;
rv = DownloadAutoCfg();
}
return rv;
}
NS_IMETHODIMP nsAutoConfig::DownloadAutoCfg()
{
nsresult rv = NS_OK;
nsresult rv;
nsCAutoString emailAddr;
nsXPIDLCString urlName;
PRBool appendMail=PR_FALSE, offline=PR_FALSE;
@ -208,27 +205,27 @@ NS_IMETHODIMP nsAutoConfig::DownloadAutoCfg()
// get the value of the autoconfig url
rv = mPrefBranch->GetCharPref("autoadmin.global_config_url",
getter_Copies(urlName));
if(NS_FAILED(rv) || (nsCRT::strlen(urlName) == 0))
return NS_OK; /* Return ok if there is no config url set. */
getter_Copies(urlName));
if (NS_FAILED(rv) || (nsCRT::strlen(urlName) == 0))
return NS_OK; // Return ok if there is no config url set.
// Check to see if the network is online/offline
nsCOMPtr<nsIIOService> ios =
do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = ios->GetOffline(&offline);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
if (offline) {
PRBool offlineFailover = PR_FALSE;
rv = mPrefBranch->GetBoolPref("autoadmin.offline_failover",
&offlineFailover);
&offlineFailover);
// Read the failover.jsc if the network is offline and the pref says so
if ( offlineFailover ) {
if (offlineFailover) {
return readOfflineFile();
}
}
@ -239,7 +236,7 @@ NS_IMETHODIMP nsAutoConfig::DownloadAutoCfg()
/* Append user's identity at the end of the URL if the pref says so.
First we are checking for the user's email address but if it is not
available in the case where the client is used without messenger, user's
available in the case where the client is used without messenger, user's
profile name will be used as an unique identifier
*/
@ -248,9 +245,11 @@ NS_IMETHODIMP nsAutoConfig::DownloadAutoCfg()
if (NS_SUCCEEDED(rv) && appendMail) {
rv = getEmailAddr(emailAddr);
if (NS_SUCCEEDED(rv) && emailAddr) {
/* Adding the unique identifier at the end of autoconfig URL.
In this case the autoconfig URL is a script and
emailAddr as passed as an argument */
emailAddr as passed as an argument
*/
cfgUrl.Append("?");
cfgUrl.Append(emailAddr);
}
@ -258,30 +257,32 @@ NS_IMETHODIMP nsAutoConfig::DownloadAutoCfg()
// Getting an event queue. If we start an AsyncOpen, the thread
// needs to wait before the reading of autoconfig is done
nsCOMPtr<nsIEventQueue> currentThreadQ;
// We are having the event queue processing only for the startup
// It is not needed with the repeating timer.
if (firstTime) {
nsCOMPtr<nsIEventQueueService> service =
do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
rv = service->GetThreadEventQueue(NS_CURRENT_THREAD,getter_AddRefs(currentThreadQ));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
if (NS_FAILED(rv))
return rv;
}
mLoaded = PR_FALSE;
// create a new url
nsCOMPtr<nsIURI> url;
nsCOMPtr<nsIChannel> channel;
rv = NS_NewURI(getter_AddRefs(url), cfgUrl, nsnull, nsnull);
if(NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
// open a channel for the url
rv = NS_OpenURI(getter_AddRefs(channel),url, nsnull, nsnull, nsnull, nsIRequest::INHIBIT_PERSISTENT_CACHING | nsIRequest::LOAD_BYPASS_CACHE);
if(NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
rv = channel->AsyncOpen(this, nsnull);
if (NS_FAILED(rv)) {
@ -289,44 +290,45 @@ NS_IMETHODIMP nsAutoConfig::DownloadAutoCfg()
return rv;
}
// Set a repeating timer if the pref is set.
// This is to be done only once.
if (firstTime) {
firstTime = PR_FALSE;
PRInt32 minutes = 0;
rv = mPrefBranch->GetIntPref("autoadmin.refresh_interval",
&minutes);
if(NS_SUCCEEDED(rv) && minutes > 0) {
&minutes);
if (NS_SUCCEEDED(rv) && minutes > 0) {
// Create a new timer and pass this nsAutoConfig
// object as a timer callback.
nsCOMPtr<nsITimer> timer;
timer = do_CreateInstance("@mozilla.org/timer;1",&rv);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
rv = timer->Init(this, minutes*60*1000, NS_PRIORITY_NORMAL,
NS_TYPE_REPEATING_SLACK);
if (NS_FAILED(rv)) return rv;
NS_TYPE_REPEATING_SLACK);
if (NS_FAILED(rv))
return rv;
}
// process events until we're finished. AutoConfig.jsc reading needs
// to be finished before the browser starts loading up
// We are waiting for the mLoaded which will be set through
// onStopRequest or readOfflineFile methods
// There is a possibility of deadlock so we need to make sure
// that mLoaded will be set to true in any case (success/failure)
/* process events until we're finished. AutoConfig.jsc reading needs
to be finished before the browser starts loading up
We are waiting for the mLoaded which will be set through
onStopRequest or readOfflineFile methods
There is a possibility of deadlock so we need to make sure
that mLoaded will be set to true in any case (success/failure)
*/
PLEvent *event;
while (!mLoaded) {
rv = currentThreadQ->WaitForEvent(&event);
NS_ASSERTION(NS_SUCCEEDED(rv),"-->nsAutoConfig::DownloadAutoCfg: currentThreadQ->WaitForEvent failed...");
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
rv = currentThreadQ->HandleEvent(event);
NS_ASSERTION(NS_SUCCEEDED(rv), "-->nsAutoConfig::DownloadAutoCfg: currentThreadQ->HandleEvent failed...");
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
}
} //first_time
@ -343,6 +345,12 @@ nsresult nsAutoConfig::readOfflineFile()
nsresult rv;
PRBool offline;
/* Releasing the lock to allow main thread to start
execution. At this point we do not need to stall
the thread since all network activities are done.
*/
mLoaded = PR_TRUE;
rv = mPrefBranch->GetBoolPref("autoadmin.failover_to_cached", &failCache);
if (failCache == PR_FALSE) {
@ -351,41 +359,43 @@ nsresult nsAutoConfig::readOfflineFile()
nsCOMPtr<nsIIOService> ios =
do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return reportError();
if (NS_FAILED(rv))
return rv;
rv = ios->GetOffline(&offline);
if (NS_FAILED(rv)) return reportError();
if (NS_FAILED(rv))
return rv;
if (!offline) {
rv = ios->SetOffline(PR_TRUE);
if (NS_FAILED(rv)) return reportError();
if (NS_FAILED(rv))
return rv;
}
// lock the "network.online" prference so user cannot toggle back to
// online mode.
rv = mPrefBranch->SetBoolPref("network.online", PR_FALSE);
if (NS_FAILED(rv)) return reportError();
if (NS_FAILED(rv))
return rv;
mPrefBranch->LockPref("network.online");
mLoaded = PR_TRUE;
return NS_OK;
}
// failCache = true
// Open the file and read the content.
// execute the javascript file
/* faiover_to_cached is set to true so
Open the file and read the content.
execute the javascript file
*/
nsCOMPtr<nsIFile> failoverFile;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(failoverFile));
if (NS_FAILED(rv)) return reportError();
if (NS_FAILED(rv))
return rv;
failoverFile->Append("failover.jsc");
rv = evaluateLocalFile(failoverFile);
if (NS_FAILED(rv))
NS_WARNING("Couldn't open failover.jsc, going back to default prefs");
mLoaded = PR_TRUE;
return NS_OK;
}
@ -395,28 +405,26 @@ nsresult nsAutoConfig::evaluateLocalFile(nsIFile* file)
nsCOMPtr<nsIInputStream> inStr;
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
PRInt64 fileSize;
PRUint32 fs, amt=0;
file->GetFileSize(&fileSize);
LL_L2UI(fs, fileSize); // Converting 64 bit structure to unsigned int
char* buf = (char *) PR_Malloc(fs*sizeof(char)) ;
if(!buf)
if (!buf)
return NS_ERROR_OUT_OF_MEMORY;
rv = inStr->Read(buf, fs, &amt);
if (NS_FAILED(rv))
NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv),
"The stream should never block.");
if (!PREF_EvaluateConfigScript(buf,fs,nsnull, PR_FALSE, PR_TRUE, PR_FALSE)){
PR_FREEIF(buf);
return NS_ERROR_FAILURE;
if (NS_SUCCEEDED(rv)) {
if (!PREF_EvaluateConfigScript(buf,fs,nsnull, PR_FALSE,
PR_TRUE, PR_FALSE))
rv = NS_ERROR_FAILURE;
}
inStr->Close();
PR_FREEIF(buf);
return NS_OK;
PR_Free(buf);
return rv;
}
nsresult nsAutoConfig::writeFailoverFile()
@ -425,15 +433,17 @@ nsresult nsAutoConfig::writeFailoverFile()
nsCOMPtr<nsIFile> failoverFile;
nsCOMPtr<nsIOutputStream> outStr;
PRUint32 amt;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(failoverFile));
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
failoverFile->Append("failover.jsc");
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStr), failoverFile);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
rv = outStr->Write(mBuf.get(),mBuf.Length(),&amt);
outStr->Close();
return rv;
@ -441,7 +451,7 @@ nsresult nsAutoConfig::writeFailoverFile()
nsresult nsAutoConfig::getEmailAddr(nsAWritableCString & emailAddr)
{
nsresult rv;
nsXPIDLCString prefValue;
@ -462,14 +472,14 @@ nsresult nsAutoConfig::getEmailAddr(nsAWritableCString & emailAddr)
nsDependentCString(prefValue, len) + NS_LITERAL_CSTRING(".identities");
rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
getter_Copies(prefValue));
// should the following |strlen|s ask |== 0|? |PRUint32| can't be |<0|
if (NS_FAILED(rv) || (len = nsCRT::strlen(prefValue)) < 0) return rv;
if (NS_FAILED(rv) || (len = nsCRT::strlen(prefValue)) == 0)
return rv;
emailAddr = NS_LITERAL_CSTRING("mail.identity.") +
nsDependentCString(prefValue, len) + NS_LITERAL_CSTRING(".useremail");
rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
getter_Copies(prefValue));
if (NS_FAILED(rv) || (len = nsCRT::strlen(prefValue)) < 0) return rv;
if (NS_FAILED(rv) || (len = nsCRT::strlen(prefValue)) == 0)
return rv;
emailAddr = nsDependentCString(prefValue, len);
}
else {
@ -481,10 +491,3 @@ nsresult nsAutoConfig::getEmailAddr(nsAWritableCString & emailAddr)
return NS_OK;
}
nsresult nsAutoConfig::reportError()
{
NS_ERROR("AutoConfig::readOfflineFile() failed");
mLoaded = PR_TRUE; //Releasing lock to avoid deadlock in DownloadAutoCfg()
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -56,7 +56,6 @@ class nsAutoConfig : public nsIAutoConfig,
nsresult evaluateLocalFile(nsIFile * file);
nsresult writeFailoverFile();
nsresult getEmailAddr(nsAWritableCString & emailAddr);
nsresult reportError();
nsCString mBuf, mCurrProfile;
nsCOMPtr<nsIPrefBranch> mPrefBranch;
PRBool mLoaded;

Просмотреть файл

@ -61,19 +61,16 @@ function setOfflineUI(offline)
//Checking for a preference "network.online", if it's locked, disabling
// network icon and menu item
try {
var prefService = Components.classes["@mozilla.org/preferences-service;1"];
prefService = prefService.getService();
prefService = prefService.QueryInterface(Components.interfaces.nsIPrefService);
var prefBranch = prefService.getBranch(null);
var offlineLocked = prefBranch.prefIsLocked("network.online");
if (offlineLocked ) {
broadcaster.setAttribute("disabled","true");
}
} catch(e) {
var prefService = Components.classes["@mozilla.org/preferences-service;1"];
prefService = prefService.getService();
prefService = prefService.QueryInterface(Components.interfaces.nsIPrefService);
var prefBranch = prefService.getBranch(null);
var offlineLocked = prefBranch.prefIsLocked("network.online");
if (offlineLocked ) {
broadcaster.setAttribute("disabled","true");
}
var bundle = srGetStrBundle("chrome://communicator/locale/utilityOverlay.properties");