write cookies to disk after page load completes. bug 165268 r=ccarlen,darin

This commit is contained in:
danm%netscape.com 2003-02-24 21:45:58 +00:00
Родитель f4a0e93b73
Коммит a97874bfb4
2 изменённых файлов: 70 добавлений и 6 удалений

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

@ -55,6 +55,9 @@
static NS_DEFINE_IID(kDocLoaderServiceCID, NS_DOCUMENTLOADER_SERVICE_CID); static NS_DEFINE_IID(kDocLoaderServiceCID, NS_DOCUMENTLOADER_SERVICE_CID);
static const PRUint32 kLazyWriteLoadingTimeout = 10000; //msec
static const PRUint32 kLazyWriteFinishedTimeout = 1000; //msec
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -66,12 +69,16 @@ NS_IMPL_ISUPPORTS4(nsCookieService, nsICookieService,
PRBool gCookieIconVisible = PR_FALSE; PRBool gCookieIconVisible = PR_FALSE;
nsCookieService::nsCookieService() nsCookieService::nsCookieService() :
mLoadCount(0),
mWritePending(PR_FALSE)
{ {
} }
nsCookieService::~nsCookieService(void) nsCookieService::~nsCookieService(void)
{ {
if (mWriteTimer)
mWriteTimer->Cancel();
COOKIE_RemoveAll(); COOKIE_RemoveAll();
} }
@ -97,7 +104,8 @@ nsresult nsCookieService::Init()
nsCOMPtr<nsIWebProgress> progress(do_QueryInterface(docLoaderService)); nsCOMPtr<nsIWebProgress> progress(do_QueryInterface(docLoaderService));
if (progress) if (progress)
(void) progress->AddProgressListener((nsIWebProgressListener*)this, (void) progress->AddProgressListener((nsIWebProgressListener*)this,
nsIWebProgress::NOTIFY_STATE_DOCUMENT); nsIWebProgress::NOTIFY_STATE_DOCUMENT |
nsIWebProgress::NOTIFY_STATE_NETWORK);
} else { } else {
NS_ASSERTION(PR_FALSE, "Could not get nsIDocumentLoader"); NS_ASSERTION(PR_FALSE, "Could not get nsIDocumentLoader");
} }
@ -105,6 +113,36 @@ nsresult nsCookieService::Init()
return NS_OK; return NS_OK;
} }
void
nsCookieService::LazyWrite(PRBool aForce)
{
// !aForce resets the timer at load end, but only if a write is pending
if (!aForce && !mWritePending)
return;
PRUint32 timeout = mLoadCount > 0 ? kLazyWriteLoadingTimeout :
kLazyWriteFinishedTimeout;
if (mWriteTimer) {
mWriteTimer->SetDelay(timeout);
mWritePending = PR_TRUE;
} else {
mWriteTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mWriteTimer) {
mWriteTimer->InitWithFuncCallback(DoLazyWrite, this, timeout,
nsITimer::TYPE_ONE_SHOT);
mWritePending = PR_TRUE;
}
}
}
void
nsCookieService::DoLazyWrite(nsITimer *aTimer, void *aClosure)
{
nsCookieService *service = NS_REINTERPRET_CAST(nsCookieService *, aClosure);
service->mWritePending = PR_FALSE;
COOKIE_Write();
}
// nsIWebProgressListener implementation // nsIWebProgressListener implementation
NS_IMETHODIMP NS_IMETHODIMP
nsCookieService::OnProgressChange(nsIWebProgress *aProgress, nsCookieService::OnProgressChange(nsIWebProgress *aProgress,
@ -124,9 +162,21 @@ nsCookieService::OnStateChange(nsIWebProgress* aWebProgress,
PRUint32 progressStateFlags, PRUint32 progressStateFlags,
nsresult aStatus) nsresult aStatus)
{ {
if ((progressStateFlags & STATE_IS_DOCUMENT) && (progressStateFlags & STATE_STOP)) { if (progressStateFlags & STATE_IS_NETWORK) {
COOKIE_Notify(); if (progressStateFlags & STATE_START)
++mLoadCount;
if (progressStateFlags & STATE_STOP) {
if (mLoadCount > 0) // in case we missed STATE_START
--mLoadCount;
if (mLoadCount == 0)
LazyWrite(PR_FALSE);
} }
}
if ((progressStateFlags & STATE_IS_DOCUMENT) &&
(progressStateFlags & STATE_STOP))
COOKIE_Notify();
return NS_OK; return NS_OK;
} }
@ -180,6 +230,7 @@ NS_IMETHODIMP
nsCookieService::SetCookieString(nsIURI *aURL, nsIPrompt* aPrompt, const char * aCookie, nsIHttpChannel* aHttpChannel) { nsCookieService::SetCookieString(nsIURI *aURL, nsIPrompt* aPrompt, const char * aCookie, nsIHttpChannel* aHttpChannel) {
COOKIE_SetCookieString(aURL, aPrompt, aCookie, aHttpChannel); COOKIE_SetCookieString(aURL, aPrompt, aCookie, aHttpChannel);
LazyWrite(PR_TRUE);
return NS_OK; return NS_OK;
} }
@ -193,6 +244,7 @@ nsCookieService::SetCookieStringFromHttp(nsIURI *aURL, nsIURI *aFirstURL, nsIPro
COOKIE_SetCookieStringFromHttp( COOKIE_SetCookieStringFromHttp(
aURL, firstURL, aPrompter, aCookie, (char *)aExpires, aHttpChannel); aURL, firstURL, aPrompter, aCookie, (char *)aExpires, aHttpChannel);
LazyWrite(PR_TRUE);
return NS_OK; return NS_OK;
} }
@ -209,6 +261,8 @@ NS_IMETHODIMP nsCookieService::Observe(nsISupports *aSubject, const char *aTopic
if (!nsCRT::strcmp(aTopic, "profile-before-change")) { if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
// The profile is about to change, // The profile is about to change,
// or is going away because the application is shutting down. // or is going away because the application is shutting down.
if (mWriteTimer)
mWriteTimer->Cancel();
COOKIE_Write(); COOKIE_Write();
COOKIE_RemoveAll(); COOKIE_RemoveAll();

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

@ -44,7 +44,7 @@
#include "nsIWebProgressListener.h" #include "nsIWebProgressListener.h"
#include "nsWeakReference.h" #include "nsWeakReference.h"
#include "nsIIOService.h" #include "nsIIOService.h"
#include "nsIFile.h" #include "nsITimer.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -63,6 +63,16 @@ public:
nsCookieService(); nsCookieService();
virtual ~nsCookieService(void); virtual ~nsCookieService(void);
nsresult Init(); nsresult Init();
protected:
// Use LazyWrite to save the cookies file on a timer. It will write
// the file only once if repeatedly hammered quickly.
void LazyWrite(PRBool aForce);
static void DoLazyWrite(nsITimer *aTimer, void *aClosure);
nsCOMPtr<nsITimer> mWriteTimer;
PRUint32 mLoadCount;
PRBool mWritePending;
}; };
#endif /* nsCookieService_h__ */ #endif /* nsCookieService_h__ */