Backing out fix for bug 579846 on suspicion of causing test failures.

This commit is contained in:
Robert O'Callahan 2011-01-17 09:37:46 +13:00
commit 3069839113
14 changed files with 392 additions and 229 deletions

View File

@ -456,6 +456,8 @@ _TEST_FILES2 = \
test_bug622117.html \
test_bug622246.html \
test_bug484396.html \
test_bug466080.html \
bug466080.sjs \
$(NULL)
# This test fails on the Mac for some reason

View File

@ -0,0 +1,17 @@
function handleRequest(request, response)
{
var body = "loaded";
var origin = "localhost";
try {
var origin = request.getHeader("Origin");
} catch(e) {}
response.setHeader("Access-Control-Allow-Origin",
origin,
false);
response.setHeader("Access-Control-Allow-Credentials", "true", false);
response.setHeader("Connection", "Keep-alive", false);
response.bodyOutputStream.write(body, body.length);
}

View File

@ -0,0 +1,119 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test bug 466080</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="onWindowLoad()">
<iframe id="frame1"
src="https://requireclientcert.example.com/tests/content/base/test/bug466080.sjs"
onload="document.iframeWasLoaded = true">
This iframe should load the resource via the src-attribute from
a secure server which requires a client-cert. Doing this is
supposed to work, but further below in the test we try to load
the resource from the same url using a XHR, which should not work.
TODO : What if we change 'src' from JS? Would/should it load?
</iframe>
<script class="testbody" type="text/javascript">
document.iframeWasLoaded = false;
var alltests = [
// load resource from a relative url - this should work
{ url:"bug466080.sjs",
status_check:"==200",
error:"XHR from relative URL"},
// TODO - load the resource from a relative url via https..?
// load a non-existing resource - should get "404 Not Found"
{ url:"bug466080-does-not.exist",
status_check:"==404",
error:"XHR loading non-existing resource"},
// load resource from cross-site non-secure server
{ url:"http://test1.example.com/tests/content/base/test/bug466080.sjs",
status_check:"==200",
error:"XHR from cross-site plaintext server"},
// load resource from cross-site secure server - should work since no credentials are needed
{ url:"https://test1.example.com/tests/content/base/test/bug466080.sjs",
status_check:"==200",
error:"XHR from cross-site secure server"},
// load resource from cross-site secure server - should work since the server just requests certs
{ url:"https://requestclientcert.example.com/tests/content/base/test/bug466080.sjs",
status_check:"==200",
error:"XHR from cross-site secure server requesting certificate"},
// load resource from cross-site secure server - should NOT work since the server requires cert
// note that this is the url which is used in the iframe.src above
{ url:"https://requireclientcert.example.com/tests/content/base/test/bug466080.sjs",
status_check:"!=200",
error:"XHR from cross-site secure server requiring certificate"},
// repeat previous, - should NOT work
{ url:"https://requireclientcert.example.com/tests/content/base/test/bug466080.sjs",
status_check:"==200",
error:"XHR w/ credentials from cross-site secure server requiring certificate",
withCredentials:"true"},
// repeat previous, but with credentials - should work
{ url:"https://requireclientcert.example.com/tests/content/base/test/bug466080.sjs",
status_check:"==200",
error:"XHR w/ credentials from cross-site secure server requiring certificate",
withCredentials:"true"},
// repeat previous, withCredentials but using a weird method to force preflight
// should NOT work since our preflight is anonymous and will fail with our simple server
{ url:"https://requireclientcert.example.com/tests/content/base/test/bug466080.sjs",
status_check:"!=200",
error:"XHR PREFLIGHT from cross-site secure server requiring certificate",
withCredentials:"true",
method:"XMETHOD"},
];
function onWindowLoad() {
// First, check that resource was loaded into the iframe
// This check in fact depends on bug #444165... :)
ok(document.iframeWasLoaded, "Loading resource via src-attribute");
for each (test in alltests) {
var xhr = new XMLHttpRequest();
var method = "GET";
if (test.method != null) { method = test.method; }
xhr.open(method, test.url, false);
xhr.withCredentials = test.withCredentials;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
xhr.setRequestHeader("Connection", "Keep-Alive", false);
netscape.security.PrivilegeManager.disablePrivilege("UniversalXPConnect");
try {
xhr.send();
} catch(e) {
}
var success = eval(xhr.status + test.status_check);
ok(success, test.error);
}
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

View File

@ -281,6 +281,12 @@ nsDOMStorageManager::Initialize()
os->AddObserver(gStorageManager, "profile-after-change", PR_FALSE);
os->AddObserver(gStorageManager, "perm-changed", PR_FALSE);
os->AddObserver(gStorageManager, "browser:purge-domain-data", PR_FALSE);
#ifdef MOZ_STORAGE
// Used for temporary table flushing
os->AddObserver(gStorageManager, "profile-before-change", PR_FALSE);
os->AddObserver(gStorageManager, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
os->AddObserver(gStorageManager, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, PR_FALSE);
#endif
return NS_OK;
}
@ -441,8 +447,6 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
nsCOMPtr<nsIObserverService> obsserv = mozilla::services::GetObserverService();
if (obsserv)
obsserv->NotifyObservers(nsnull, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, nsnull);
if (!UnflushedDataExists())
DOMStorageImpl::gStorageDB->StopTempTableFlushTimer();
} else if (!strcmp(aTopic, "browser:purge-domain-data")) {
// Convert the domain name to the ACE format
nsCAutoString aceDomain;
@ -470,6 +474,19 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
NS_ENSURE_SUCCESS(rv, rv);
DOMStorageImpl::gStorageDB->RemoveOwner(aceDomain, PR_TRUE);
} else if (!strcmp(aTopic, "profile-before-change") ||
!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
if (DOMStorageImpl::gStorageDB) {
nsresult rv = DOMStorageImpl::gStorageDB->FlushAndDeleteTemporaryTables(true);
if (NS_FAILED(rv))
NS_WARNING("DOMStorage: temporary table commit failed");
}
} else if (!strcmp(aTopic, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER)) {
if (DOMStorageImpl::gStorageDB) {
nsresult rv = DOMStorageImpl::gStorageDB->FlushAndDeleteTemporaryTables(false);
if (NS_FAILED(rv))
NS_WARNING("DOMStorage: temporary table commit failed");
}
#endif
}
@ -539,26 +556,6 @@ nsDOMStorageManager::RemoveFromStoragesHash(DOMStorageImpl* aStorage)
mStorages.RemoveEntry(aStorage);
}
static PLDHashOperator
CheckUnflushedData(nsDOMStorageEntry* aEntry, void* userArg)
{
if (aEntry->mStorage->WasTemporaryTableLoaded()) {
PRBool *unflushedData = (PRBool*)userArg;
*unflushedData = PR_TRUE;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
PRBool
nsDOMStorageManager::UnflushedDataExists()
{
PRBool unflushedData = PR_FALSE;
mStorages.EnumerateEntries(CheckUnflushedData, &unflushedData);
return unflushedData;
}
//
// nsDOMStorage
//
@ -726,25 +723,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMStorageImpl)
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(DOMStorageImpl, nsIObserver)
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(DOMStorageImpl, nsIObserver)
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMStorageImpl)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMStorageImpl)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMStorageImpl)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage)
: mLoadedTemporaryTable(false)
{
Init(aStorage);
}
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage, DOMStorageImpl& aThat)
: DOMStorageBase(aThat)
, mLoadedTemporaryTable(aThat.mLoadedTemporaryTable)
, mLastTemporaryTableAccessTime(aThat.mLastTemporaryTableAccessTime)
, mTemporaryTableAge(aThat.mTemporaryTableAge)
{
Init(aStorage);
}
@ -807,8 +798,6 @@ DOMStorageImpl::InitFromChild(bool aUseDB, bool aCanUseChromePersist,
mQuotaDomainDBKey = aQuotaDomainDBKey;
mQuotaETLDplus1DomainDBKey = aQuotaETLDplus1DomainDBKey;
mStorageType = static_cast<nsPIDOMStorage::nsDOMStorageType>(aStorageType);
if (mStorageType != nsPIDOMStorage::SessionStorage)
RegisterObservers();
}
void
@ -828,14 +817,12 @@ DOMStorageImpl::InitAsLocalStorage(nsIURI* aDomainURI,
bool aCanUseChromePersist)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist);
RegisterObservers();
}
void
DOMStorageImpl::InitAsGlobalStorage(const nsACString& aDomainDemanded)
{
DOMStorageBase::InitAsGlobalStorage(aDomainDemanded);
RegisterObservers();
}
bool
@ -1032,86 +1019,6 @@ DOMStorageImpl::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat)
return NS_OK;
}
nsresult
DOMStorageImpl::RegisterObservers()
{
nsCOMPtr<nsIObserverService> obsserv = mozilla::services::GetObserverService();
if (obsserv) {
obsserv->AddObserver(this, "profile-before-change", PR_TRUE);
obsserv->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
obsserv->AddObserver(this, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, PR_TRUE);
}
return NS_OK;
}
nsresult
DOMStorageImpl::MaybeCommitTemporaryTable(bool force)
{
#ifdef MOZ_STORAGE
if (!UseDB())
return NS_OK;
if (!mLoadedTemporaryTable)
return NS_OK;
// If we are not forced to flush (e.g. on shutdown) then don't flush if the
// last table access is less then 5 seconds ago or the table itself is not
// older then 30 secs
if (!force &&
((TimeStamp::Now() - mLastTemporaryTableAccessTime).ToSeconds() <
NS_DOMSTORAGE_MAXIMUM_TEMPTABLE_INACTIVITY_TIME) &&
((TimeStamp::Now() - mTemporaryTableAge).ToSeconds() <
NS_DOMSTORAGE_MAXIMUM_TEMPTABLE_AGE))
return NS_OK;
return gStorageDB->FlushAndDeleteTemporaryTableForStorage(this);
#endif
return NS_OK;
}
bool
DOMStorageImpl::WasTemporaryTableLoaded()
{
return mLoadedTemporaryTable;
}
void
DOMStorageImpl::SetTemporaryTableLoaded(bool loaded)
{
if (loaded) {
mLastTemporaryTableAccessTime = TimeStamp::Now();
if (!mLoadedTemporaryTable)
mTemporaryTableAge = mLastTemporaryTableAccessTime;
gStorageDB->EnsureTempTableFlushTimer();
}
mLoadedTemporaryTable = loaded;
}
NS_IMETHODIMP
DOMStorageImpl::Observe(nsISupports *subject,
const char *topic,
const PRUnichar *data)
{
bool isProfileBeforeChange = !strcmp(topic, "profile-before-change");
bool isXPCOMShutdown = !strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
bool isFlushTimer = !strcmp(topic, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER);
if (isXPCOMShutdown || isProfileBeforeChange || isFlushTimer) {
nsresult rv = MaybeCommitTemporaryTable(isXPCOMShutdown || isProfileBeforeChange);
if (NS_FAILED(rv)) {
NS_WARNING("DOMStorage: temporary table commit failed");
}
return NS_OK;
}
NS_WARNING("Unrecognized topic in nsDOMStorage::Observe");
return NS_OK;
}
nsresult
DOMStorageImpl::CacheKeysFromDB()
{

View File

@ -61,7 +61,6 @@
#include "nsIObserver.h"
#include "nsITimer.h"
#include "nsWeakReference.h"
#include "mozilla/TimeStamp.h"
#define NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER "domstorage-flush-timer"
@ -76,9 +75,7 @@
class nsDOMStorage;
class nsIDOMStorage;
class nsDOMStorageItem;
using mozilla::TimeStamp;
using mozilla::TimeDuration;
class nsDOMStoragePersistentDB;
namespace mozilla {
namespace dom {
@ -244,14 +241,11 @@ protected:
};
class DOMStorageImpl : public DOMStorageBase
, public nsIObserver
, public nsSupportsWeakReference
{
public:
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DOMStorageImpl, nsIObserver)
NS_DECL_CYCLE_COLLECTION_CLASS(DOMStorageImpl)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIOBSERVER
DOMStorageImpl(nsDOMStorage*);
DOMStorageImpl(nsDOMStorage*, DOMStorageImpl&);
@ -314,12 +308,6 @@ public:
virtual nsresult
CloneFrom(bool aCallerSecure, DOMStorageBase* aThat);
nsresult RegisterObservers();
nsresult MaybeCommitTemporaryTable(bool force);
bool WasTemporaryTableLoaded();
void SetTemporaryTableLoaded(bool loaded);
virtual bool CacheStoragePermissions();
private:
@ -327,6 +315,7 @@ private:
static nsDOMStorageDBWrapper* gStorageDB;
#endif
friend class nsDOMStorageManager;
friend class nsDOMStoragePersistentDB;
friend class StorageParent;
void Init(nsDOMStorage*);
@ -351,10 +340,6 @@ private:
// Weak reference to the owning storage instance
nsDOMStorage* mOwner;
bool mLoadedTemporaryTable;
TimeStamp mLastTemporaryTableAccessTime;
TimeStamp mTemporaryTableAge;
};
class nsDOMStorage : public nsIDOMStorageObsolete,

View File

@ -75,7 +75,6 @@ nsDOMStorageDBWrapper::nsDOMStorageDBWrapper()
nsDOMStorageDBWrapper::~nsDOMStorageDBWrapper()
{
StopTempTableFlushTimer();
}
nsresult
@ -99,29 +98,18 @@ nsDOMStorageDBWrapper::Init()
}
nsresult
nsDOMStorageDBWrapper::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTables(bool force)
{
if (aStorage->CanUseChromePersist())
return mChromePersistentDB.EnsureLoadTemporaryTableForStorage(aStorage);
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
return NS_OK;
if (aStorage->SessionOnly())
return NS_OK;
nsresult rv1, rv2;
rv1 = mChromePersistentDB.FlushTemporaryTables(force);
rv2 = mPersistentDB.FlushTemporaryTables(force);
return mPersistentDB.EnsureLoadTemporaryTableForStorage(aStorage);
}
// Everything flushed? Then no need for a timer.
if (!mChromePersistentDB.mTempTableLoads.Count() &&
!mPersistentDB.mTempTableLoads.Count())
StopTempTableFlushTimer();
nsresult
nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage)
{
if (aStorage->CanUseChromePersist())
return mChromePersistentDB.FlushAndDeleteTemporaryTableForStorage(aStorage);
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
return NS_OK;
if (aStorage->SessionOnly())
return NS_OK;
return mPersistentDB.FlushAndDeleteTemporaryTableForStorage(aStorage);
return NS_FAILED(rv1) ? rv1 : rv2;
}
nsresult

View File

@ -92,11 +92,6 @@ public:
nsresult
Init();
nsresult
EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage);
nsresult
FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage);
/**
* Retrieve a list of all the keys associated with a particular domain.
*/
@ -227,6 +222,14 @@ public:
*/
void EnsureTempTableFlushTimer();
/**
* Called by the timer or on shutdown/profile change to flush all temporary
* tables that are too long in memory to disk.
* Set force to flush even a table doesn't meet the age limits. Used during
* shutdown.
*/
nsresult FlushAndDeleteTemporaryTables(bool force);
/**
* Stops the temp table flush timer.
*/

View File

@ -55,6 +55,10 @@
#include "nsPrintfCString.h"
#include "nsNetUtil.h"
// Temporary tables for a storage scope will be flushed if found older
// then this time in seconds since the load
#define TEMP_TABLE_MAX_AGE (10) // seconds
class nsReverseStringSQLFunction : public mozIStorageFunction
{
NS_DECL_ISUPPORTS
@ -98,6 +102,7 @@ NS_IMPL_ISUPPORTS1(nsIsOfflineSQLFunction, mozIStorageFunction)
nsDOMStoragePersistentDB::nsDOMStoragePersistentDB()
{
mTempTableLoads.Init(16);
}
NS_IMETHODIMP
@ -446,7 +451,9 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
nsresult
nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
{
if (!aStorage->WasTemporaryTableLoaded()) {
TimeStamp timeStamp;
if (!mTempTableLoads.Get(aStorage->GetScopeDBKey(), &timeStamp)) {
nsresult rv;
rv = MaybeCommitInsertTransaction();
@ -466,57 +473,76 @@ nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aSt
rv = mCopyToTempTableStatement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
}
// Always call this to update the last access time
aStorage->SetTemporaryTableLoaded(true);
mTempTableLoads.Put(aStorage->GetScopeDBKey(), TimeStamp::Now());
DOMStorageImpl::gStorageDB->EnsureTempTableFlushTimer();
}
return NS_OK;
}
nsresult
nsDOMStoragePersistentDB::FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage)
/* static */
PLDHashOperator
nsDOMStoragePersistentDB::FlushTemporaryTable(nsCStringHashKey::KeyType aKey,
TimeStamp& aData,
void* aUserArg)
{
if (!aStorage->WasTemporaryTableLoaded())
return NS_OK;
FlushTemporaryTableData* data = (FlushTemporaryTableData*)aUserArg;
if (!data->mForce &&
((TimeStamp::Now() - aData).ToSeconds() < TEMP_TABLE_MAX_AGE))
return PL_DHASH_NEXT;
{
mozStorageStatementScoper scope(data->mDB->mCopyBackToDiskStatement);
Binder binder(data->mDB->mCopyBackToDiskStatement, &data->mRV);
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
data->mRV = binder->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"), aKey);
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
data->mRV = binder.Add();
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
data->mRV = data->mDB->mCopyBackToDiskStatement->Execute();
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
}
{
mozStorageStatementScoper scope(data->mDB->mDeleteTemporaryTableStatement);
Binder binder(data->mDB->mDeleteTemporaryTableStatement, &data->mRV);
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
data->mRV = binder->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"), aKey);
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
data->mRV = binder.Add();
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
data->mRV = data->mDB->mDeleteTemporaryTableStatement->Execute();
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
}
return PL_DHASH_REMOVE;
}
nsresult
nsDOMStoragePersistentDB::FlushTemporaryTables(bool force)
{
mozStorageTransaction trans(mConnection, PR_FALSE);
nsresult rv;
{
mozStorageStatementScoper scope(mCopyBackToDiskStatement);
FlushTemporaryTableData data;
data.mDB = this;
data.mForce = force;
data.mRV = NS_OK;
Binder binder(mCopyBackToDiskStatement, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = binder->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
aStorage->GetScopeDBKey());
NS_ENSURE_SUCCESS(rv, rv);
rv = binder.Add();
NS_ENSURE_SUCCESS(rv, rv);
rv = mCopyBackToDiskStatement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
}
{
mozStorageStatementScoper scope(mDeleteTemporaryTableStatement);
Binder binder(mDeleteTemporaryTableStatement, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = binder->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
aStorage->GetScopeDBKey());
NS_ENSURE_SUCCESS(rv, rv);
rv = binder.Add();
NS_ENSURE_SUCCESS(rv, rv);
rv = mDeleteTemporaryTableStatement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
}
mTempTableLoads.Enumerate(FlushTemporaryTable, &data);
NS_ENSURE_SUCCESS(data.mRV, data.mRV);
rv = trans.Commit();
NS_ENSURE_SUCCESS(rv, rv);
@ -524,8 +550,6 @@ nsDOMStoragePersistentDB::FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl*
rv = MaybeCommitInsertTransaction();
NS_ENSURE_SUCCESS(rv, rv);
aStorage->SetTemporaryTableLoaded(false);
return NS_OK;
}

View File

@ -43,10 +43,15 @@
#include "mozIStorageConnection.h"
#include "mozIStorageStatement.h"
#include "nsTHashtable.h"
#include "nsDataHashtable.h"
#include "mozilla/TimeStamp.h"
class DOMStorageImpl;
class nsSessionStorageEntry;
using mozilla::TimeStamp;
using mozilla::TimeDuration;
class nsDOMStoragePersistentDB
{
public:
@ -56,11 +61,6 @@ public:
nsresult
Init(const nsString& aDatabaseName);
nsresult
EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage);
nsresult
FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage);
/**
* Retrieve a list of all the keys associated with a particular domain.
*/
@ -162,7 +162,26 @@ public:
*/
nsresult MaybeCommitInsertTransaction();
/**
* Flushes all temporary tables based on time or forcibly during shutdown.
*/
nsresult FlushTemporaryTables(bool force);
protected:
/**
* Ensures that a temporary table is correctly filled for the scope of
* the given storage.
*/
nsresult EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage);
struct FlushTemporaryTableData {
nsDOMStoragePersistentDB* mDB;
bool mForce;
nsresult mRV;
};
static PLDHashOperator FlushTemporaryTable(nsCStringHashKey::KeyType aKey,
TimeStamp& aData,
void* aUserArg);
nsCOMPtr<mozIStorageConnection> mConnection;
@ -183,6 +202,11 @@ protected:
nsCString mCachedOwner;
PRInt32 mCachedUsage;
// Maps ScopeDBKey to time of the temporary table load for that scope.
// If a record is present, the temp table has been loaded. If it is not
// present, the table has not yet been loaded or has alrady been flushed.
nsDataHashtable<nsCStringHashKey, TimeStamp> mTempTableLoads;
friend class nsDOMStorageDBWrapper;
friend class nsDOMStorageMemoryDB;
nsresult

View File

@ -47,6 +47,7 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
frameBug624047.html \
frameChromeSlave.html \
frameMasterEqual.html \
frameMasterNotEqual.html \
@ -61,6 +62,7 @@ _TEST_FILES = \
interOriginTest2.js \
pbSwitch.js \
test_brokenUTF-16.html \
test_bug624047.html \
test_cookieBlock.html \
test_cookieSession-phase1.html \
test_cookieSession-phase2.html \

View File

@ -0,0 +1,30 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>slave for bug 624047 test</title>
<script type="text/javascript" src="interOriginFrame.js"></script>
<script type="text/javascript">
function doStep()
{
localStorage.name = 1;
var timer = setInterval(function() {
is(localStorage.name, 1, "Value is still present");
}, 1000);
setTimeout(function() {
clearTimeout(timer);
localStorage.clear();
postMsg("done");
}, 12000);
return false;
}
</script>
</head>
<body onload="postMsg('frame loaded');">
</body>
</html>

View File

@ -0,0 +1,65 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>bug 624047</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="interOriginTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
/*
This test does the folliwing:
- loads a page in an iframe that stores a value to localStorage
- sooner then in 5 seconds reloads the page
- now the page later then 5 seconds after load in the first step checks the
value is still present in localStorage (what is expected)
- if not, the bug is still present
*/
function flushTables()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]
.getService(Components.interfaces.nsIObserver);
storageManager.observe(null, "profile-before-change", null);
}
function startTest()
{
slaveOrigin = "http://sub2.test2.example.org";
slave = document.getElementById("__test_frame").contentWindow;
flushTables();
slave.location = slaveOrigin + slavePath + "frameBug624047.html";
setTimeout(function() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
slaveLoadsPending = 1;
slave.location.reload();
}, 2000);
}
function doNextTest()
{
SimpleTest.finish();
}
function doStep()
{
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body onload="startTest();">
This test takes about 15s to complete... Please wait...
<br/>
<iframe src="" id="__test_frame"></iframe>
</body>
</html>

View File

@ -969,9 +969,7 @@ const STATE_WAITING_FOR_REFTEST_WAIT_REMOVAL = 1;
const STATE_WAITING_TO_FINISH = 2;
const STATE_COMPLETED = 3;
function WaitForTestEnd() {
var currentDoc = gBrowser.contentDocument;
var contentRootElement = currentDoc ? currentDoc.documentElement : null;
function WaitForTestEnd(contentRootElement) {
var stopAfterPaintReceived = false;
var state = STATE_WAITING_TO_FIRE_INVALIDATE_EVENT;
@ -1176,23 +1174,20 @@ function OnDocumentLoad(event)
var contentRootElement = currentDoc ? currentDoc.documentElement : null;
setupZoom(contentRootElement);
var inPrintMode = false;
function AfterOnLoadScripts() {
if (doPrintMode(contentRootElement)) {
LogInfo("AfterOnLoadScripts setting up print mode");
setupPrintMode();
}
// Take a snapshot now. We need to do this before we check whether
// we should wait, since this might trigger dispatching of
// MozPaintWait events and make shouldWaitForExplicitPaintWaiters() true
// below.
InitCurrentCanvasWithSnapshot();
if (shouldWaitForExplicitPaintWaiters()) {
if (shouldWaitForExplicitPaintWaiters() ||
(!inPrintMode && doPrintMode(contentRootElement))) {
LogInfo("AfterOnLoadScripts belatedly entering WaitForTestEnd");
// Go into reftest-wait mode belatedly.
WaitForTestEnd();
WaitForTestEnd(contentRootElement);
} else {
RecordResult();
}
@ -1204,8 +1199,14 @@ function OnDocumentLoad(event)
// unsuppressed, after the onload event has finished dispatching.
gFailureReason = "timed out waiting for test to complete (trying to get into WaitForTestEnd)";
LogInfo("OnDocumentLoad triggering WaitForTestEnd");
setTimeout(WaitForTestEnd, 0);
setTimeout(WaitForTestEnd, 0, contentRootElement);
} else {
if (doPrintMode(contentRootElement)) {
LogInfo("OnDocumentLoad setting up print mode");
setupPrintMode();
inPrintMode = true;
}
// Since we can't use a bubbling-phase load listener from chrome,
// this is a capturing phase listener. So do setTimeout twice, the
// first to get us after the onload has fired in the content, and

View File

@ -241,19 +241,15 @@ nsresult imgRequest::Init(nsIURI *aURI,
// Register our pref observer if it hasn't been done yet.
if (NS_UNLIKELY(!gRegisteredPrefObserver)) {
imgRequestPrefObserver *observer = new imgRequestPrefObserver();
if (observer) {
nsCOMPtr<nsIPrefBranch2> branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (branch) {
branch->AddObserver(DISCARD_PREF, observer, PR_FALSE);
branch->AddObserver(DECODEONDRAW_PREF, observer, PR_FALSE);
branch->AddObserver(DISCARD_TIMEOUT_PREF, observer, PR_FALSE);
ReloadPrefs(branch);
gRegisteredPrefObserver = PR_TRUE;
}
nsCOMPtr<nsIPrefBranch2> branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (branch) {
nsCOMPtr<nsIObserver> observer(new imgRequestPrefObserver());
branch->AddObserver(DISCARD_PREF, observer, PR_FALSE);
branch->AddObserver(DECODEONDRAW_PREF, observer, PR_FALSE);
branch->AddObserver(DISCARD_TIMEOUT_PREF, observer, PR_FALSE);
ReloadPrefs(branch);
gRegisteredPrefObserver = PR_TRUE;
}
else
delete observer;
}
return NS_OK;