mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Bug 1624146 - Cookie code refactoring - part 7 - CookiePrivateStorage and CookieDefaultStorage, r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D67756 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
299696f535
commit
e444769cb0
@ -151,8 +151,12 @@ void BindCookieParameters(mozIStorageBindingParamsArray* aParamsArray,
|
||||
rv = aParamsArray->AddParams(params);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CookieEntry
|
||||
|
||||
size_t CookieEntry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
|
||||
size_t amount = CookieKey::SizeOfExcludingThis(aMallocSizeOf);
|
||||
|
||||
@ -164,11 +168,10 @@ size_t CookieEntry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
|
||||
return amount;
|
||||
}
|
||||
|
||||
CookieStorage::CookieStorage(bool aPrivateStorage)
|
||||
: cookieCount(0),
|
||||
cookieOldestTime(INT64_MAX),
|
||||
corruptFlag(OK),
|
||||
mPrivateStorage(aPrivateStorage) {}
|
||||
// ---------------------------------------------------------------------------
|
||||
// CookieStorage
|
||||
|
||||
CookieStorage::CookieStorage() : cookieCount(0), cookieOldestTime(INT64_MAX) {}
|
||||
|
||||
CookieStorage::~CookieStorage() = default;
|
||||
|
||||
@ -334,7 +337,6 @@ void CookieStorage::RemoveCookie(const nsACString& aBaseDomain,
|
||||
void CookieStorage::RemoveCookiesWithOriginAttributes(
|
||||
const mozilla::OriginAttributesPattern& aPattern,
|
||||
const nsACString& aBaseDomain) {
|
||||
mozStorageTransaction transaction(dbConn, false);
|
||||
// Iterate the hash table of CookieEntry.
|
||||
for (auto iter = hostTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
CookieEntry* entry = iter.Get();
|
||||
@ -363,75 +365,11 @@ void CookieStorage::RemoveCookiesWithOriginAttributes(
|
||||
}
|
||||
}
|
||||
}
|
||||
DebugOnly<nsresult> rv = transaction.Commit();
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
// remove a cookie from the hashtable, and update the iterator state.
|
||||
void CookieStorage::RemoveCookieFromList(
|
||||
const CookieListIter& aIter, mozIStorageBindingParamsArray* aParamsArray) {
|
||||
// if it's a non-session cookie, remove it from the db
|
||||
if (!aIter.Cookie()->IsSession() && dbConn) {
|
||||
// Use the asynchronous binding methods to ensure that we do not acquire
|
||||
// the database lock.
|
||||
mozIStorageAsyncStatement* stmt = stmtDelete;
|
||||
nsCOMPtr<mozIStorageBindingParamsArray> paramsArray(aParamsArray);
|
||||
if (!paramsArray) {
|
||||
stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIStorageBindingParams> params;
|
||||
paramsArray->NewBindingParams(getter_AddRefs(params));
|
||||
|
||||
DebugOnly<nsresult> rv = params->BindUTF8StringByName(
|
||||
NS_LITERAL_CSTRING("name"), aIter.Cookie()->Name());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("host"),
|
||||
aIter.Cookie()->Host());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("path"),
|
||||
aIter.Cookie()->Path());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsAutoCString suffix;
|
||||
aIter.Cookie()->OriginAttributesRef().CreateSuffix(suffix);
|
||||
rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("originAttributes"),
|
||||
suffix);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = paramsArray->AddParams(params);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// If we weren't given a params array, we'll need to remove it ourselves.
|
||||
if (!aParamsArray) {
|
||||
rv = stmt->BindParameters(paramsArray);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
rv = stmt->ExecuteAsync(removeListener, getter_AddRefs(handle));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
if (aIter.entry->GetCookies().Length() == 1) {
|
||||
// we're removing the last element in the array - so just remove the entry
|
||||
// from the hash. note that the entryclass' dtor will take care of
|
||||
// releasing this last element for us!
|
||||
hostTable.RawRemoveEntry(aIter.entry);
|
||||
|
||||
} else {
|
||||
// just remove the element from the list
|
||||
aIter.entry->GetCookies().RemoveElementAt(aIter.index);
|
||||
}
|
||||
|
||||
--cookieCount;
|
||||
}
|
||||
|
||||
void CookieStorage::RemoveCookiesFromExactHost(
|
||||
const nsACString& aHost, const nsACString& aBaseDomain,
|
||||
const mozilla::OriginAttributesPattern& aPattern) {
|
||||
mozStorageTransaction transaction(dbConn, false);
|
||||
// Iterate the hash table of CookieEntry.
|
||||
for (auto iter = hostTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
CookieEntry* entry = iter.Get();
|
||||
@ -461,9 +399,6 @@ void CookieStorage::RemoveCookiesFromExactHost(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DebugOnly<nsresult> rv = transaction.Commit();
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
void CookieStorage::RemoveAll() {
|
||||
@ -473,23 +408,7 @@ void CookieStorage::RemoveAll() {
|
||||
cookieCount = 0;
|
||||
cookieOldestTime = INT64_MAX;
|
||||
|
||||
// clear the cookie file
|
||||
if (dbConn) {
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmt;
|
||||
nsresult rv = dbConn->CreateAsyncStatement(
|
||||
NS_LITERAL_CSTRING("DELETE FROM moz_cookies"), getter_AddRefs(stmt));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
rv = stmt->ExecuteAsync(removeListener, getter_AddRefs(handle));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
} else {
|
||||
// Recreate the database.
|
||||
COOKIE_LOGSTRING(LogLevel::Debug,
|
||||
("RemoveAll(): corruption detected with rv 0x%" PRIx32,
|
||||
static_cast<uint32_t>(rv)));
|
||||
HandleCorruptDB();
|
||||
}
|
||||
}
|
||||
RemoveAllInternal();
|
||||
|
||||
NotifyChanged(nullptr, u"cleared");
|
||||
}
|
||||
@ -504,110 +423,14 @@ void CookieStorage::RemoveAll() {
|
||||
// cookies.
|
||||
void CookieStorage::NotifyChanged(nsISupports* aSubject, const char16_t* aData,
|
||||
bool aOldCookieIsSession, bool aFromHttp) {
|
||||
const char* topic =
|
||||
mPrivateStorage ? "private-cookie-changed" : "cookie-changed";
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (!os) {
|
||||
return;
|
||||
}
|
||||
// Notify for topic "private-cookie-changed" or "cookie-changed"
|
||||
os->NotifyObservers(aSubject, topic, aData);
|
||||
os->NotifyObservers(aSubject, NotificationTopic(), aData);
|
||||
|
||||
// Notify for topic "session-cookie-changed" to update the copy of session
|
||||
// cookies in session restore component.
|
||||
// Ignore private session cookies since they will not be restored.
|
||||
if (mPrivateStorage) {
|
||||
return;
|
||||
}
|
||||
// Filter out notifications for individual non-session cookies.
|
||||
if (NS_LITERAL_STRING("changed").Equals(aData) ||
|
||||
NS_LITERAL_STRING("deleted").Equals(aData) ||
|
||||
NS_LITERAL_STRING("added").Equals(aData)) {
|
||||
nsCOMPtr<nsICookie> xpcCookie = do_QueryInterface(aSubject);
|
||||
MOZ_ASSERT(xpcCookie);
|
||||
auto cookie = static_cast<Cookie*>(xpcCookie.get());
|
||||
if (!cookie->IsSession() && !aOldCookieIsSession) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
os->NotifyObservers(aSubject, "session-cookie-changed", aData);
|
||||
}
|
||||
|
||||
void CookieStorage::HandleCorruptDB() {
|
||||
if (mPrivateStorage) {
|
||||
// We've either closed the state or we've switched profiles. It's getting
|
||||
// a bit late to rebuild -- bail instead.
|
||||
COOKIE_LOGSTRING(
|
||||
LogLevel::Warning,
|
||||
("HandleCorruptDB(): CookieStorage %p is already closed, aborting",
|
||||
this));
|
||||
return;
|
||||
}
|
||||
|
||||
COOKIE_LOGSTRING(LogLevel::Debug,
|
||||
("HandleCorruptDB(): CookieStorage %p has corruptFlag %u",
|
||||
this, corruptFlag));
|
||||
|
||||
// Mark the database corrupt, so the close listener can begin reconstructing
|
||||
// it.
|
||||
switch (corruptFlag) {
|
||||
case CookieStorage::OK: {
|
||||
// Move to 'closing' state.
|
||||
corruptFlag = CookieStorage::CLOSING_FOR_REBUILD;
|
||||
|
||||
CleanupCachedStatements();
|
||||
dbConn->AsyncClose(closeListener);
|
||||
CleanupDefaultDBConnection();
|
||||
break;
|
||||
}
|
||||
case CookieStorage::CLOSING_FOR_REBUILD: {
|
||||
// We had an error while waiting for close completion. That's OK, just
|
||||
// ignore it -- we're rebuilding anyway.
|
||||
return;
|
||||
}
|
||||
case CookieStorage::REBUILDING: {
|
||||
// We had an error while rebuilding the DB. Game over. Close the database
|
||||
// and let the close handler do nothing; then we'll move it out of the
|
||||
// way.
|
||||
CleanupCachedStatements();
|
||||
if (dbConn) {
|
||||
dbConn->AsyncClose(closeListener);
|
||||
}
|
||||
CleanupDefaultDBConnection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Null out the statements.
|
||||
// This must be done before closing the connection.
|
||||
void CookieStorage::CleanupCachedStatements() {
|
||||
stmtInsert = nullptr;
|
||||
stmtDelete = nullptr;
|
||||
stmtUpdate = nullptr;
|
||||
}
|
||||
|
||||
// Null out the listeners, and the database connection itself. This
|
||||
// will not null out the statements, cancel a pending read or
|
||||
// asynchronously close the connection -- these must be done
|
||||
// beforehand if necessary.
|
||||
void CookieStorage::CleanupDefaultDBConnection() {
|
||||
MOZ_ASSERT(!stmtInsert, "stmtInsert has been cleaned up");
|
||||
MOZ_ASSERT(!stmtDelete, "stmtDelete has been cleaned up");
|
||||
MOZ_ASSERT(!stmtUpdate, "stmtUpdate has been cleaned up");
|
||||
|
||||
// Null out the database connections. If 'dbConn' has not been used for any
|
||||
// asynchronous operations yet, this will synchronously close it; otherwise,
|
||||
// it's expected that the caller has performed an AsyncClose prior.
|
||||
dbConn = nullptr;
|
||||
|
||||
// Manually null out our listeners. This is necessary because they hold a
|
||||
// strong ref to the CookieStorage itself. They'll stay alive until whatever
|
||||
// statements are still executing complete.
|
||||
insertListener = nullptr;
|
||||
updateListener = nullptr;
|
||||
removeListener = nullptr;
|
||||
closeListener = nullptr;
|
||||
NotifyChangedInternal(aSubject, aData, aOldCookieIsSession);
|
||||
}
|
||||
|
||||
// this is a backend function for adding a cookie to the list, via SetCookie.
|
||||
@ -813,11 +636,6 @@ void CookieStorage::AddCookieToList(const nsACString& aBaseDomain,
|
||||
Cookie* aCookie,
|
||||
mozIStorageBindingParamsArray* aParamsArray,
|
||||
bool aWriteToDB) {
|
||||
NS_ASSERTION(!(dbConn && !aWriteToDB && aParamsArray),
|
||||
"Not writing to the DB but have a params array?");
|
||||
NS_ASSERTION(!(!dbConn && aParamsArray),
|
||||
"Do not have a DB connection but have a params array?");
|
||||
|
||||
if (!aCookie) {
|
||||
NS_WARNING("Attempting to AddCookieToList with null cookie");
|
||||
return;
|
||||
@ -836,25 +654,8 @@ void CookieStorage::AddCookieToList(const nsACString& aBaseDomain,
|
||||
|
||||
// if it's a non-session cookie and hasn't just been read from the db, write
|
||||
// it out.
|
||||
if (aWriteToDB && !aCookie->IsSession() && dbConn) {
|
||||
mozIStorageAsyncStatement* stmt = stmtInsert;
|
||||
nsCOMPtr<mozIStorageBindingParamsArray> paramsArray(aParamsArray);
|
||||
if (!paramsArray) {
|
||||
stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
|
||||
}
|
||||
|
||||
BindCookieParameters(paramsArray, key, aCookie);
|
||||
|
||||
// If we were supplied an array to store parameters, we shouldn't call
|
||||
// executeAsync - someone up the stack will do this for us.
|
||||
if (!aParamsArray) {
|
||||
DebugOnly<nsresult> rv = stmt->BindParameters(paramsArray);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
rv = stmt->ExecuteAsync(insertListener, getter_AddRefs(handle));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
if (aWriteToDB && !aCookie->IsSession()) {
|
||||
WriteCookieToDB(aBaseDomain, aOriginAttributes, aCookie, aParamsArray);
|
||||
}
|
||||
}
|
||||
|
||||
@ -943,11 +744,8 @@ already_AddRefed<nsIArray> CookieStorage::PurgeCookies(
|
||||
|
||||
// Create a params array to batch the removals. This is OK here because
|
||||
// all the removals are in order, and there are no interleaved additions.
|
||||
mozIStorageAsyncStatement* stmt = stmtDelete;
|
||||
nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
|
||||
if (dbConn) {
|
||||
stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
|
||||
}
|
||||
MaybeCreateDeleteBindingParamsArray(getter_AddRefs(paramsArray));
|
||||
|
||||
int64_t currentTime = aCurrentTimeInUsec / PR_USEC_PER_SEC;
|
||||
int64_t purgeTime = aCurrentTimeInUsec - aCookiePurgeAge;
|
||||
@ -1018,18 +816,7 @@ already_AddRefed<nsIArray> CookieStorage::PurgeCookies(
|
||||
}
|
||||
|
||||
// Update the database if we have entries to purge.
|
||||
if (paramsArray) {
|
||||
uint32_t length;
|
||||
paramsArray->GetLength(&length);
|
||||
if (length) {
|
||||
DebugOnly<nsresult> rv = stmt->BindParameters(paramsArray);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
rv = stmt->ExecuteAsync(removeListener, getter_AddRefs(handle));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
DeleteFromDB(paramsArray);
|
||||
|
||||
// reset the oldest time indicator
|
||||
cookieOldestTime = oldestTime;
|
||||
@ -1044,12 +831,279 @@ already_AddRefed<nsIArray> CookieStorage::PurgeCookies(
|
||||
return removedList.forget();
|
||||
}
|
||||
|
||||
nsresult CookieStorage::ImportCookies(nsIFile* aCookieFile,
|
||||
nsIEffectiveTLDService* aTLDService,
|
||||
uint16_t aMaxNumberOfCookies,
|
||||
uint16_t aMaxCookiesPerHost,
|
||||
uint16_t aCookieQuotaPerHost,
|
||||
int64_t aCookiePurgeAge) {
|
||||
// remove a cookie from the hashtable, and update the iterator state.
|
||||
void CookieStorage::RemoveCookieFromList(
|
||||
const CookieListIter& aIter, mozIStorageBindingParamsArray* aParamsArray) {
|
||||
RemoveCookieFromListInternal(aIter, aParamsArray);
|
||||
|
||||
if (aIter.entry->GetCookies().Length() == 1) {
|
||||
// we're removing the last element in the array - so just remove the entry
|
||||
// from the hash. note that the entryclass' dtor will take care of
|
||||
// releasing this last element for us!
|
||||
hostTable.RawRemoveEntry(aIter.entry);
|
||||
|
||||
} else {
|
||||
// just remove the element from the list
|
||||
aIter.entry->GetCookies().RemoveElementAt(aIter.index);
|
||||
}
|
||||
|
||||
--cookieCount;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// CookiePrivateStorage
|
||||
|
||||
// static
|
||||
already_AddRefed<CookiePrivateStorage> CookiePrivateStorage::Create() {
|
||||
RefPtr<CookiePrivateStorage> storage = new CookiePrivateStorage();
|
||||
return storage.forget();
|
||||
}
|
||||
|
||||
void CookiePrivateStorage::StaleCookies(const nsTArray<Cookie*>& aCookieList,
|
||||
int64_t aCurrentTimeInUsec) {
|
||||
int32_t count = aCookieList.Length();
|
||||
for (int32_t i = 0; i < count; ++i) {
|
||||
Cookie* cookie = aCookieList.ElementAt(i);
|
||||
|
||||
if (cookie->IsStale()) {
|
||||
cookie->SetLastAccessed(aCurrentTimeInUsec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CookieDefaultStorage
|
||||
|
||||
// static
|
||||
already_AddRefed<CookieDefaultStorage> CookieDefaultStorage::Create() {
|
||||
RefPtr<CookieDefaultStorage> storage = new CookieDefaultStorage();
|
||||
return storage.forget();
|
||||
}
|
||||
|
||||
CookieDefaultStorage::CookieDefaultStorage() : corruptFlag(OK) {}
|
||||
|
||||
void CookieDefaultStorage::NotifyChangedInternal(nsISupports* aSubject,
|
||||
const char16_t* aData,
|
||||
bool aOldCookieIsSession) {
|
||||
// Notify for topic "session-cookie-changed" to update the copy of session
|
||||
// cookies in session restore component.
|
||||
|
||||
// Filter out notifications for individual non-session cookies.
|
||||
if (NS_LITERAL_STRING("changed").Equals(aData) ||
|
||||
NS_LITERAL_STRING("deleted").Equals(aData) ||
|
||||
NS_LITERAL_STRING("added").Equals(aData)) {
|
||||
nsCOMPtr<nsICookie> xpcCookie = do_QueryInterface(aSubject);
|
||||
MOZ_ASSERT(xpcCookie);
|
||||
auto cookie = static_cast<Cookie*>(xpcCookie.get());
|
||||
if (!cookie->IsSession() && !aOldCookieIsSession) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->NotifyObservers(aSubject, "session-cookie-changed", aData);
|
||||
}
|
||||
}
|
||||
|
||||
void CookieDefaultStorage::RemoveAllInternal() {
|
||||
// clear the cookie file
|
||||
if (dbConn) {
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmt;
|
||||
nsresult rv = dbConn->CreateAsyncStatement(
|
||||
NS_LITERAL_CSTRING("DELETE FROM moz_cookies"), getter_AddRefs(stmt));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
rv = stmt->ExecuteAsync(removeListener, getter_AddRefs(handle));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
} else {
|
||||
// Recreate the database.
|
||||
COOKIE_LOGSTRING(LogLevel::Debug,
|
||||
("RemoveAll(): corruption detected with rv 0x%" PRIx32,
|
||||
static_cast<uint32_t>(rv)));
|
||||
HandleCorruptDB();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CookieDefaultStorage::WriteCookieToDB(
|
||||
const nsACString& aBaseDomain, const OriginAttributes& aOriginAttributes,
|
||||
mozilla::net::Cookie* aCookie,
|
||||
mozIStorageBindingParamsArray* aParamsArray) {
|
||||
if (dbConn) {
|
||||
mozIStorageAsyncStatement* stmt = stmtInsert;
|
||||
nsCOMPtr<mozIStorageBindingParamsArray> paramsArray(aParamsArray);
|
||||
if (!paramsArray) {
|
||||
stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
|
||||
}
|
||||
|
||||
CookieKey key(aBaseDomain, aOriginAttributes);
|
||||
BindCookieParameters(paramsArray, key, aCookie);
|
||||
|
||||
// If we were supplied an array to store parameters, we shouldn't call
|
||||
// executeAsync - someone up the stack will do this for us.
|
||||
if (!aParamsArray) {
|
||||
DebugOnly<nsresult> rv = stmt->BindParameters(paramsArray);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
rv = stmt->ExecuteAsync(insertListener, getter_AddRefs(handle));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CookieDefaultStorage::HandleCorruptDB() {
|
||||
COOKIE_LOGSTRING(LogLevel::Debug,
|
||||
("HandleCorruptDB(): CookieStorage %p has corruptFlag %u",
|
||||
this, corruptFlag));
|
||||
|
||||
// Mark the database corrupt, so the close listener can begin reconstructing
|
||||
// it.
|
||||
switch (corruptFlag) {
|
||||
case OK: {
|
||||
// Move to 'closing' state.
|
||||
corruptFlag = CLOSING_FOR_REBUILD;
|
||||
|
||||
CleanupCachedStatements();
|
||||
dbConn->AsyncClose(closeListener);
|
||||
CleanupDefaultDBConnection();
|
||||
break;
|
||||
}
|
||||
case CLOSING_FOR_REBUILD: {
|
||||
// We had an error while waiting for close completion. That's OK, just
|
||||
// ignore it -- we're rebuilding anyway.
|
||||
return;
|
||||
}
|
||||
case REBUILDING: {
|
||||
// We had an error while rebuilding the DB. Game over. Close the database
|
||||
// and let the close handler do nothing; then we'll move it out of the
|
||||
// way.
|
||||
CleanupCachedStatements();
|
||||
if (dbConn) {
|
||||
dbConn->AsyncClose(closeListener);
|
||||
}
|
||||
CleanupDefaultDBConnection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CookieDefaultStorage::RemoveCookiesWithOriginAttributes(
|
||||
const mozilla::OriginAttributesPattern& aPattern,
|
||||
const nsACString& aBaseDomain) {
|
||||
mozStorageTransaction transaction(dbConn, false);
|
||||
|
||||
CookieStorage::RemoveCookiesWithOriginAttributes(aPattern, aBaseDomain);
|
||||
|
||||
DebugOnly<nsresult> rv = transaction.Commit();
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
void CookieDefaultStorage::RemoveCookiesFromExactHost(
|
||||
const nsACString& aHost, const nsACString& aBaseDomain,
|
||||
const mozilla::OriginAttributesPattern& aPattern) {
|
||||
mozStorageTransaction transaction(dbConn, false);
|
||||
|
||||
CookieStorage::RemoveCookiesFromExactHost(aHost, aBaseDomain, aPattern);
|
||||
|
||||
DebugOnly<nsresult> rv = transaction.Commit();
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
void CookieDefaultStorage::RemoveCookieFromListInternal(
|
||||
const CookieListIter& aIter, mozIStorageBindingParamsArray* aParamsArray) {
|
||||
// if it's a non-session cookie, remove it from the db
|
||||
if (!aIter.Cookie()->IsSession() && dbConn) {
|
||||
// Use the asynchronous binding methods to ensure that we do not acquire
|
||||
// the database lock.
|
||||
mozIStorageAsyncStatement* stmt = stmtDelete;
|
||||
nsCOMPtr<mozIStorageBindingParamsArray> paramsArray(aParamsArray);
|
||||
if (!paramsArray) {
|
||||
stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIStorageBindingParams> params;
|
||||
paramsArray->NewBindingParams(getter_AddRefs(params));
|
||||
|
||||
DebugOnly<nsresult> rv = params->BindUTF8StringByName(
|
||||
NS_LITERAL_CSTRING("name"), aIter.Cookie()->Name());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("host"),
|
||||
aIter.Cookie()->Host());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("path"),
|
||||
aIter.Cookie()->Path());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsAutoCString suffix;
|
||||
aIter.Cookie()->OriginAttributesRef().CreateSuffix(suffix);
|
||||
rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("originAttributes"),
|
||||
suffix);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = paramsArray->AddParams(params);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// If we weren't given a params array, we'll need to remove it ourselves.
|
||||
if (!aParamsArray) {
|
||||
rv = stmt->BindParameters(paramsArray);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
rv = stmt->ExecuteAsync(removeListener, getter_AddRefs(handle));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Null out the statements.
|
||||
// This must be done before closing the connection.
|
||||
void CookieDefaultStorage::CleanupCachedStatements() {
|
||||
stmtInsert = nullptr;
|
||||
stmtDelete = nullptr;
|
||||
stmtUpdate = nullptr;
|
||||
}
|
||||
|
||||
// Null out the listeners, and the database connection itself. This
|
||||
// will not null out the statements, cancel a pending read or
|
||||
// asynchronously close the connection -- these must be done
|
||||
// beforehand if necessary.
|
||||
void CookieDefaultStorage::CleanupDefaultDBConnection() {
|
||||
MOZ_ASSERT(!stmtInsert, "stmtInsert has been cleaned up");
|
||||
MOZ_ASSERT(!stmtDelete, "stmtDelete has been cleaned up");
|
||||
MOZ_ASSERT(!stmtUpdate, "stmtUpdate has been cleaned up");
|
||||
|
||||
// Null out the database connections. If 'dbConn' has not been used for any
|
||||
// asynchronous operations yet, this will synchronously close it; otherwise,
|
||||
// it's expected that the caller has performed an AsyncClose prior.
|
||||
dbConn = nullptr;
|
||||
|
||||
// Manually null out our listeners. This is necessary because they hold a
|
||||
// strong ref to the CookieStorage itself. They'll stay alive until whatever
|
||||
// statements are still executing complete.
|
||||
insertListener = nullptr;
|
||||
updateListener = nullptr;
|
||||
removeListener = nullptr;
|
||||
closeListener = nullptr;
|
||||
}
|
||||
|
||||
void CookieDefaultStorage::Close() {
|
||||
// Cleanup cached statements before we can close anything.
|
||||
CleanupCachedStatements();
|
||||
|
||||
if (dbConn) {
|
||||
// Asynchronously close the connection. We will null it below.
|
||||
dbConn->AsyncClose(closeListener);
|
||||
}
|
||||
|
||||
CleanupDefaultDBConnection();
|
||||
}
|
||||
|
||||
nsresult CookieDefaultStorage::ImportCookies(
|
||||
nsIFile* aCookieFile, nsIEffectiveTLDService* aTLDService,
|
||||
uint16_t aMaxNumberOfCookies, uint16_t aMaxCookiesPerHost,
|
||||
uint16_t aCookieQuotaPerHost, int64_t aCookiePurgeAge) {
|
||||
MOZ_ASSERT(aCookieFile);
|
||||
MOZ_ASSERT(aTLDService);
|
||||
|
||||
@ -1210,7 +1264,7 @@ nsresult CookieStorage::ImportCookies(nsIFile* aCookieFile,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void CookieStorage::StaleCookies(const nsTArray<Cookie*>& aCookieList,
|
||||
void CookieDefaultStorage::StaleCookies(const nsTArray<Cookie*>& aCookieList,
|
||||
int64_t aCurrentTimeInUsec) {
|
||||
// Create an array of parameters to bind to our update statement. Batching
|
||||
// is OK here since we're updating cookies with no interleaved operations.
|
||||
@ -1243,7 +1297,7 @@ void CookieStorage::StaleCookies(const nsTArray<Cookie*>& aCookieList,
|
||||
}
|
||||
}
|
||||
|
||||
void CookieStorage::UpdateCookieInList(
|
||||
void CookieDefaultStorage::UpdateCookieInList(
|
||||
Cookie* aCookie, int64_t aLastAccessed,
|
||||
mozIStorageBindingParamsArray* aParamsArray) {
|
||||
MOZ_ASSERT(aCookie);
|
||||
@ -1286,16 +1340,25 @@ void CookieStorage::UpdateCookieInList(
|
||||
}
|
||||
}
|
||||
|
||||
void CookieStorage::Close() {
|
||||
// Cleanup cached statements before we can close anything.
|
||||
CleanupCachedStatements();
|
||||
|
||||
void CookieDefaultStorage::MaybeCreateDeleteBindingParamsArray(
|
||||
mozIStorageBindingParamsArray** aParamsArray) {
|
||||
if (dbConn) {
|
||||
// Asynchronously close the connection. We will null it below.
|
||||
dbConn->AsyncClose(closeListener);
|
||||
stmtDelete->NewBindingParamsArray(aParamsArray);
|
||||
}
|
||||
}
|
||||
|
||||
CleanupDefaultDBConnection();
|
||||
void CookieDefaultStorage::DeleteFromDB(
|
||||
mozIStorageBindingParamsArray* aParamsArray) {
|
||||
uint32_t length;
|
||||
aParamsArray->GetLength(&length);
|
||||
if (length) {
|
||||
DebugOnly<nsresult> rv = stmtDelete->BindParameters(aParamsArray);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
rv = stmtDelete->ExecuteAsync(removeListener, getter_AddRefs(handle));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
|
@ -62,12 +62,10 @@ struct CookieListIter {
|
||||
CookieEntry::IndexType index;
|
||||
};
|
||||
|
||||
class CookieStorage final {
|
||||
class CookieStorage {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(CookieStorage)
|
||||
|
||||
explicit CookieStorage(bool aPrivateStorage);
|
||||
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
void GetCookies(nsTArray<RefPtr<nsICookie>>& aCookies) const;
|
||||
@ -96,11 +94,11 @@ class CookieStorage final {
|
||||
const nsACString& aHost, const nsACString& aName,
|
||||
const nsACString& aPath);
|
||||
|
||||
void RemoveCookiesWithOriginAttributes(
|
||||
virtual void RemoveCookiesWithOriginAttributes(
|
||||
const mozilla::OriginAttributesPattern& aPattern,
|
||||
const nsACString& aBaseDomain);
|
||||
|
||||
void RemoveCookiesFromExactHost(
|
||||
virtual void RemoveCookiesFromExactHost(
|
||||
const nsACString& aHost, const nsACString& aBaseDomain,
|
||||
const mozilla::OriginAttributesPattern& aPattern);
|
||||
|
||||
@ -109,10 +107,6 @@ class CookieStorage final {
|
||||
void NotifyChanged(nsISupports* aSubject, const char16_t* aData,
|
||||
bool aOldCookieIsSession = false, bool aFromHttp = false);
|
||||
|
||||
void HandleCorruptDB();
|
||||
void CleanupCachedStatements();
|
||||
void CleanupDefaultDBConnection();
|
||||
|
||||
void AddCookie(const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes, Cookie* aCookie,
|
||||
int64_t aCurrentTimeInUsec, nsIURI* aHostURI,
|
||||
@ -126,32 +120,164 @@ class CookieStorage final {
|
||||
mozIStorageBindingParamsArray* aParamsArray,
|
||||
bool aWriteToDB = true);
|
||||
|
||||
void RemoveCookieFromList(
|
||||
const CookieListIter& aIter,
|
||||
mozIStorageBindingParamsArray* aParamsArray = nullptr);
|
||||
|
||||
void FindStaleCookies(CookieEntry* aEntry, int64_t aCurrentTime,
|
||||
bool aIsSecure, nsTArray<CookieListIter>& aOutput,
|
||||
uint32_t aLimit);
|
||||
|
||||
void CreateOrUpdatePurgeList(nsIArray** aPurgeList, nsICookie* aCookie);
|
||||
|
||||
already_AddRefed<nsIArray> PurgeCookies(int64_t aCurrentTimeInUsec,
|
||||
uint16_t aMaxNumberOfCookies,
|
||||
int64_t aCookiePurgeAge);
|
||||
|
||||
virtual void StaleCookies(const nsTArray<Cookie*>& aCookieList,
|
||||
int64_t aCurrentTimeInUsec) = 0;
|
||||
|
||||
virtual void Close() = 0;
|
||||
|
||||
// TODO: private:
|
||||
nsTHashtable<CookieEntry> hostTable;
|
||||
|
||||
uint32_t cookieCount;
|
||||
int64_t cookieOldestTime;
|
||||
|
||||
protected:
|
||||
CookieStorage();
|
||||
virtual ~CookieStorage();
|
||||
|
||||
virtual const char* NotificationTopic() const = 0;
|
||||
|
||||
virtual void NotifyChangedInternal(nsISupports* aSubject,
|
||||
const char16_t* aData,
|
||||
bool aOldCookieIsSession) = 0;
|
||||
|
||||
virtual void WriteCookieToDB(const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
mozilla::net::Cookie* aCookie,
|
||||
mozIStorageBindingParamsArray* aParamsArray) = 0;
|
||||
|
||||
virtual void RemoveAllInternal() = 0;
|
||||
|
||||
void RemoveCookieFromList(
|
||||
const CookieListIter& aIter,
|
||||
mozIStorageBindingParamsArray* aParamsArray = nullptr);
|
||||
|
||||
virtual void RemoveCookieFromListInternal(
|
||||
const CookieListIter& aIter,
|
||||
mozIStorageBindingParamsArray* aParamsArray = nullptr) = 0;
|
||||
|
||||
virtual void MaybeCreateDeleteBindingParamsArray(
|
||||
mozIStorageBindingParamsArray** aParamsArray) = 0;
|
||||
|
||||
virtual void DeleteFromDB(mozIStorageBindingParamsArray* aParamsArray) = 0;
|
||||
|
||||
private:
|
||||
bool FindSecureCookie(const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
Cookie* aCookie);
|
||||
|
||||
void FindStaleCookies(CookieEntry* aEntry, int64_t aCurrentTime,
|
||||
bool aIsSecure, nsTArray<CookieListIter>& aOutput,
|
||||
uint32_t aLimit);
|
||||
|
||||
void UpdateCookieOldestTime(Cookie* aCookie);
|
||||
|
||||
already_AddRefed<nsIArray> CreatePurgeList(nsICookie* aCookie);
|
||||
};
|
||||
|
||||
class CookiePrivateStorage final : public CookieStorage {
|
||||
public:
|
||||
static already_AddRefed<CookiePrivateStorage> Create();
|
||||
|
||||
void StaleCookies(const nsTArray<Cookie*>& aCookieList,
|
||||
int64_t aCurrentTimeInUsec) override;
|
||||
|
||||
void Close() override{};
|
||||
|
||||
protected:
|
||||
const char* NotificationTopic() const override {
|
||||
return "private-cookie-changed";
|
||||
}
|
||||
|
||||
void NotifyChangedInternal(nsISupports* aSubject, const char16_t* aData,
|
||||
bool aOldCookieIsSession) override {}
|
||||
|
||||
void WriteCookieToDB(const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
mozilla::net::Cookie* aCookie,
|
||||
mozIStorageBindingParamsArray* aParamsArray) override{};
|
||||
|
||||
void RemoveAllInternal() override {}
|
||||
|
||||
void RemoveCookieFromListInternal(
|
||||
const CookieListIter& aIter,
|
||||
mozIStorageBindingParamsArray* aParamsArray = nullptr) override {}
|
||||
|
||||
void MaybeCreateDeleteBindingParamsArray(
|
||||
mozIStorageBindingParamsArray** aParamsArray) override {}
|
||||
|
||||
void DeleteFromDB(mozIStorageBindingParamsArray* aParamsArray) override {}
|
||||
};
|
||||
|
||||
class CookieDefaultStorage final : public CookieStorage {
|
||||
public:
|
||||
static already_AddRefed<CookieDefaultStorage> Create();
|
||||
|
||||
void HandleCorruptDB();
|
||||
|
||||
void RemoveCookiesWithOriginAttributes(
|
||||
const mozilla::OriginAttributesPattern& aPattern,
|
||||
const nsACString& aBaseDomain) override;
|
||||
|
||||
void RemoveCookiesFromExactHost(
|
||||
const nsACString& aHost, const nsACString& aBaseDomain,
|
||||
const mozilla::OriginAttributesPattern& aPattern) override;
|
||||
|
||||
void StaleCookies(const nsTArray<Cookie*>& aCookieList,
|
||||
int64_t aCurrentTimeInUsec) override;
|
||||
|
||||
void Close() override;
|
||||
|
||||
void CleanupCachedStatements();
|
||||
void CleanupDefaultDBConnection();
|
||||
|
||||
nsresult ImportCookies(nsIFile* aCookieFile,
|
||||
nsIEffectiveTLDService* aTLDService,
|
||||
uint16_t aMaxNumberOfCookies,
|
||||
uint16_t aMaxCookiesPerHost,
|
||||
uint16_t aCookieQuotaPerHost, int64_t aCookiePurgeAge);
|
||||
|
||||
void StaleCookies(const nsTArray<Cookie*>& aCookieList,
|
||||
int64_t aCurrentTimeInUsec);
|
||||
protected:
|
||||
const char* NotificationTopic() const override { return "cookie-changed"; }
|
||||
|
||||
void Close();
|
||||
void NotifyChangedInternal(nsISupports* aSubject, const char16_t* aData,
|
||||
bool aOldCOokieIsSession) override;
|
||||
|
||||
void WriteCookieToDB(const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
mozilla::net::Cookie* aCookie,
|
||||
mozIStorageBindingParamsArray* aParamsArray) override;
|
||||
|
||||
void RemoveAllInternal() override;
|
||||
|
||||
void RemoveCookieFromListInternal(
|
||||
const CookieListIter& aIter,
|
||||
mozIStorageBindingParamsArray* aParamsArray = nullptr) override;
|
||||
|
||||
void MaybeCreateDeleteBindingParamsArray(
|
||||
mozIStorageBindingParamsArray** aParamsArray) override;
|
||||
|
||||
void DeleteFromDB(mozIStorageBindingParamsArray* aParamsArray) override;
|
||||
|
||||
private:
|
||||
CookieDefaultStorage();
|
||||
|
||||
void UpdateCookieInList(Cookie* aCookie, int64_t aLastAccessed,
|
||||
mozIStorageBindingParamsArray* aParamsArray);
|
||||
|
||||
// TODO: private:
|
||||
public:
|
||||
nsCOMPtr<nsIFile> cookieFile;
|
||||
nsCOMPtr<mozIStorageConnection> dbConn;
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmtInsert;
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmtDelete;
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmtUpdate;
|
||||
|
||||
// State of the database connection.
|
||||
enum CorruptFlag {
|
||||
@ -160,17 +286,6 @@ class CookieStorage final {
|
||||
REBUILDING // close complete, rebuilding database from memory
|
||||
};
|
||||
|
||||
nsTHashtable<CookieEntry> hostTable;
|
||||
|
||||
uint32_t cookieCount;
|
||||
int64_t cookieOldestTime;
|
||||
|
||||
nsCOMPtr<nsIFile> cookieFile;
|
||||
nsCOMPtr<mozIStorageConnection> dbConn;
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmtInsert;
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmtDelete;
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmtUpdate;
|
||||
|
||||
CorruptFlag corruptFlag;
|
||||
|
||||
// Various parts representing asynchronous read state. These are useful
|
||||
@ -183,22 +298,6 @@ class CookieStorage final {
|
||||
nsCOMPtr<mozIStorageStatementCallback> updateListener;
|
||||
nsCOMPtr<mozIStorageStatementCallback> removeListener;
|
||||
nsCOMPtr<mozIStorageCompletionCallback> closeListener;
|
||||
|
||||
private:
|
||||
~CookieStorage();
|
||||
|
||||
bool FindSecureCookie(const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
Cookie* aCookie);
|
||||
|
||||
void UpdateCookieOldestTime(Cookie* aCookie);
|
||||
|
||||
already_AddRefed<nsIArray> CreatePurgeList(nsICookie* aCookie);
|
||||
|
||||
void UpdateCookieInList(Cookie* aCookie, int64_t aLastAccessed,
|
||||
mozIStorageBindingParamsArray* aParamsArray);
|
||||
|
||||
bool mPrivateStorage;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
@ -149,8 +149,9 @@ static void bindCookieParameters(mozIStorageBindingParamsArray* aParamsArray,
|
||||
******************************************************************************/
|
||||
class DBListenerErrorHandler : public mozIStorageStatementCallback {
|
||||
protected:
|
||||
explicit DBListenerErrorHandler(CookieStorage* dbState) : mStorage(dbState) {}
|
||||
RefPtr<CookieStorage> mStorage;
|
||||
explicit DBListenerErrorHandler(CookieDefaultStorage* dbState)
|
||||
: mStorage(dbState) {}
|
||||
RefPtr<CookieDefaultStorage> mStorage;
|
||||
virtual const char* GetOpType() = 0;
|
||||
|
||||
public:
|
||||
@ -188,7 +189,7 @@ class InsertCookieDBListener final : public DBListenerErrorHandler {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit InsertCookieDBListener(CookieStorage* dbState)
|
||||
explicit InsertCookieDBListener(CookieDefaultStorage* dbState)
|
||||
: DBListenerErrorHandler(dbState) {}
|
||||
NS_IMETHOD HandleResult(mozIStorageResultSet*) override {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
@ -199,12 +200,12 @@ class InsertCookieDBListener final : public DBListenerErrorHandler {
|
||||
NS_IMETHOD HandleCompletion(uint16_t aReason) override {
|
||||
// If we were rebuilding the db and we succeeded, make our corruptFlag say
|
||||
// so.
|
||||
if (mStorage->corruptFlag == CookieStorage::REBUILDING &&
|
||||
if (mStorage->corruptFlag == CookieDefaultStorage::REBUILDING &&
|
||||
aReason == mozIStorageStatementCallback::REASON_FINISHED) {
|
||||
COOKIE_LOGSTRING(
|
||||
LogLevel::Debug,
|
||||
("InsertCookieDBListener::HandleCompletion(): rebuild complete"));
|
||||
mStorage->corruptFlag = CookieStorage::OK;
|
||||
mStorage->corruptFlag = CookieDefaultStorage::OK;
|
||||
}
|
||||
|
||||
// This notification is just for testing.
|
||||
@ -232,7 +233,7 @@ class UpdateCookieDBListener final : public DBListenerErrorHandler {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit UpdateCookieDBListener(CookieStorage* dbState)
|
||||
explicit UpdateCookieDBListener(CookieDefaultStorage* dbState)
|
||||
: DBListenerErrorHandler(dbState) {}
|
||||
NS_IMETHOD HandleResult(mozIStorageResultSet*) override {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
@ -258,7 +259,7 @@ class RemoveCookieDBListener final : public DBListenerErrorHandler {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit RemoveCookieDBListener(CookieStorage* dbState)
|
||||
explicit RemoveCookieDBListener(CookieDefaultStorage* dbState)
|
||||
: DBListenerErrorHandler(dbState) {}
|
||||
NS_IMETHOD HandleResult(mozIStorageResultSet*) override {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
@ -280,8 +281,9 @@ class CloseCookieDBListener final : public mozIStorageCompletionCallback {
|
||||
~CloseCookieDBListener() = default;
|
||||
|
||||
public:
|
||||
explicit CloseCookieDBListener(CookieStorage* dbState) : mStorage(dbState) {}
|
||||
RefPtr<CookieStorage> mStorage;
|
||||
explicit CloseCookieDBListener(CookieDefaultStorage* dbState)
|
||||
: mStorage(dbState) {}
|
||||
RefPtr<CookieDefaultStorage> mStorage;
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Complete(nsresult, nsISupports*) override {
|
||||
@ -428,9 +430,9 @@ void nsCookieService::InitCookieStorages() {
|
||||
NS_ASSERTION(!mInitializedCookieStorages, "already initialized");
|
||||
NS_ASSERTION(!mThread, "already have a cookie thread");
|
||||
|
||||
// Create a new default CookieStorage and set our current one.
|
||||
mDefaultStorage = new CookieStorage(false);
|
||||
mPrivateStorage = new CookieStorage(true);
|
||||
// Create two new CookieStorages.
|
||||
mDefaultStorage = CookieDefaultStorage::Create();
|
||||
mPrivateStorage = CookiePrivateStorage::Create();
|
||||
|
||||
// Get our cookie file.
|
||||
nsresult rv = NS_GetSpecialDirectory(
|
||||
@ -1555,7 +1557,7 @@ void nsCookieService::CloseCookieStorages() {
|
||||
mInitializedCookieStorages = false;
|
||||
}
|
||||
|
||||
void nsCookieService::HandleDBClosed(CookieStorage* aCookieStorage) {
|
||||
void nsCookieService::HandleDBClosed(CookieDefaultStorage* aCookieStorage) {
|
||||
COOKIE_LOGSTRING(
|
||||
LogLevel::Debug,
|
||||
("HandleDBClosed(): CookieStorage %p closed", aCookieStorage));
|
||||
@ -1563,19 +1565,19 @@ void nsCookieService::HandleDBClosed(CookieStorage* aCookieStorage) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
|
||||
switch (aCookieStorage->corruptFlag) {
|
||||
case CookieStorage::OK: {
|
||||
case CookieDefaultStorage::OK: {
|
||||
// Database is healthy. Notify of closure.
|
||||
if (os) {
|
||||
os->NotifyObservers(nullptr, "cookie-db-closed", nullptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CookieStorage::CLOSING_FOR_REBUILD: {
|
||||
case CookieDefaultStorage::CLOSING_FOR_REBUILD: {
|
||||
// Our close finished. Start the rebuild, and notify of db closure later.
|
||||
RebuildCorruptDB(aCookieStorage);
|
||||
break;
|
||||
}
|
||||
case CookieStorage::REBUILDING: {
|
||||
case CookieDefaultStorage::REBUILDING: {
|
||||
// We encountered an error during rebuild, closed the database, and now
|
||||
// here we are. We already have a 'cookies.sqlite.bak' from the original
|
||||
// dead database; we don't want to overwrite it, so let's move this one to
|
||||
@ -1598,15 +1600,15 @@ void nsCookieService::HandleDBClosed(CookieStorage* aCookieStorage) {
|
||||
}
|
||||
}
|
||||
|
||||
void nsCookieService::RebuildCorruptDB(CookieStorage* aCookieStorage) {
|
||||
void nsCookieService::RebuildCorruptDB(CookieDefaultStorage* aCookieStorage) {
|
||||
NS_ASSERTION(!aCookieStorage->dbConn, "shouldn't have an open db connection");
|
||||
NS_ASSERTION(
|
||||
aCookieStorage->corruptFlag == CookieStorage::CLOSING_FOR_REBUILD,
|
||||
aCookieStorage->corruptFlag == CookieDefaultStorage::CLOSING_FOR_REBUILD,
|
||||
"should be in CLOSING_FOR_REBUILD state");
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
|
||||
aCookieStorage->corruptFlag = CookieStorage::REBUILDING;
|
||||
aCookieStorage->corruptFlag = CookieDefaultStorage::REBUILDING;
|
||||
|
||||
if (mDefaultStorage != aCookieStorage) {
|
||||
// We've either closed the state or we've switched profiles. It's getting
|
||||
@ -1650,7 +1652,7 @@ void nsCookieService::RebuildCorruptDB(CookieStorage* aCookieStorage) {
|
||||
gCookieService->mDefaultStorage->CleanupCachedStatements();
|
||||
gCookieService->mDefaultStorage->CleanupDefaultDBConnection();
|
||||
gCookieService->mDefaultStorage->corruptFlag =
|
||||
CookieStorage::OK;
|
||||
CookieDefaultStorage::OK;
|
||||
if (os) {
|
||||
os->NotifyObservers(nullptr, "cookie-db-closed", nullptr);
|
||||
}
|
||||
@ -1693,7 +1695,7 @@ void nsCookieService::RebuildCorruptDB(CookieStorage* aCookieStorage) {
|
||||
LogLevel::Debug,
|
||||
("RebuildCorruptDB(): nothing to write, rebuild complete"));
|
||||
gCookieService->mDefaultStorage->corruptFlag =
|
||||
CookieStorage::OK;
|
||||
CookieDefaultStorage::OK;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1751,7 +1753,7 @@ nsCookieService::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
mozilla::OriginAttributesPattern pattern;
|
||||
pattern.mPrivateBrowsingId.Construct(1);
|
||||
RemoveCookiesWithOriginAttributes(pattern, EmptyCString());
|
||||
mPrivateStorage = new CookieStorage(true);
|
||||
mPrivateStorage = CookiePrivateStorage::Create();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1893,10 +1895,7 @@ void nsCookieService::SetCookieStringInternal(
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
CookieStorage* storage =
|
||||
(aOriginAttrs.mPrivateBrowsingId > 0) ? mPrivateStorage : mDefaultStorage;
|
||||
CookieStorage* storage = PickStorage(aOriginAttrs);
|
||||
|
||||
// get the base domain for the host URI.
|
||||
// e.g. for "www.bbc.co.uk", this would be "bbc.co.uk".
|
||||
@ -2116,12 +2115,6 @@ nsCookieService::AddNative(const nsACString& aHost, const nsACString& aPath,
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
CookieStorage* storage = (aOriginAttributes->mPrivateBrowsingId > 0)
|
||||
? mPrivateStorage
|
||||
: mDefaultStorage;
|
||||
|
||||
// first, normalize the hostname, and fail if it contains illegal characters.
|
||||
nsAutoCString host(aHost);
|
||||
nsresult rv = NormalizeHost(host);
|
||||
@ -2144,6 +2137,7 @@ nsCookieService::AddNative(const nsACString& aHost, const nsACString& aPath,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
CookieStorage* storage = PickStorage(*aOriginAttributes);
|
||||
storage->AddCookie(baseDomain, *aOriginAttributes, cookie, currentTimeInUsec,
|
||||
nullptr, VoidCString(), true, mMaxNumberOfCookies,
|
||||
mMaxCookiesPerHost, mCookieQuotaPerHost, mCookiePurgeAge);
|
||||
@ -2169,10 +2163,7 @@ nsresult nsCookieService::Remove(const nsACString& aHost,
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
CookieStorage* storage =
|
||||
(aAttrs.mPrivateBrowsingId > 0) ? mPrivateStorage : mDefaultStorage;
|
||||
CookieStorage* storage = PickStorage(aAttrs);
|
||||
storage->RemoveCookie(baseDomain, aAttrs, host, PromiseFlatCString(aName),
|
||||
PromiseFlatCString(aPath));
|
||||
|
||||
@ -2419,10 +2410,7 @@ void nsCookieService::GetCookiesForURI(
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
CookieStorage* storage =
|
||||
(aOriginAttrs.mPrivateBrowsingId > 0) ? mPrivateStorage : mDefaultStorage;
|
||||
CookieStorage* storage = PickStorage(aOriginAttrs);
|
||||
|
||||
// get the base domain, host, and path from the URI.
|
||||
// e.g. for "www.bbc.co.uk", the base domain would be "bbc.co.uk".
|
||||
@ -3664,17 +3652,12 @@ nsCookieService::CookieExistsNative(const nsACString& aHost,
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
nsAutoCString baseDomain;
|
||||
nsresult rv = GetBaseDomainFromHost(mTLDService, aHost, baseDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
CookieStorage* storage = (aOriginAttributes->mPrivateBrowsingId > 0)
|
||||
? mPrivateStorage
|
||||
: mDefaultStorage;
|
||||
|
||||
CookieListIter iter;
|
||||
CookieStorage* storage = PickStorage(*aOriginAttributes);
|
||||
*aFoundCookie = storage->FindCookie(baseDomain, *aOriginAttributes, aHost,
|
||||
aName, aPath, iter);
|
||||
return NS_OK;
|
||||
@ -3730,10 +3713,8 @@ nsCookieService::GetCookiesFromHost(const nsACString& aHost,
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
CookieStorage* storage = PickStorage(attrs);
|
||||
|
||||
CookieStorage* storage =
|
||||
(attrs.mPrivateBrowsingId > 0) ? mPrivateStorage : mDefaultStorage;
|
||||
const nsTArray<RefPtr<Cookie>>* cookies =
|
||||
storage->GetCookiesFromHost(baseDomain, attrs);
|
||||
|
||||
@ -3770,18 +3751,9 @@ nsCookieService::GetCookiesWithOriginAttributes(
|
||||
nsresult nsCookieService::GetCookiesWithOriginAttributes(
|
||||
const mozilla::OriginAttributesPattern& aPattern,
|
||||
const nsCString& aBaseDomain, nsTArray<RefPtr<nsICookie>>& aResult) {
|
||||
if (!IsInitialized()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
CookieStorage* storage = (aPattern.mPrivateBrowsingId.WasPassed() &&
|
||||
aPattern.mPrivateBrowsingId.Value() > 0)
|
||||
? mPrivateStorage
|
||||
: mDefaultStorage;
|
||||
|
||||
CookieStorage* storage = PickStorage(aPattern);
|
||||
storage->GetCookiesWithOriginAttributes(aPattern, aBaseDomain, aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3813,14 +3785,9 @@ nsresult nsCookieService::RemoveCookiesWithOriginAttributes(
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
CookieStorage* storage = (aPattern.mPrivateBrowsingId.WasPassed() &&
|
||||
aPattern.mPrivateBrowsingId.Value() > 0)
|
||||
? mPrivateStorage
|
||||
: mDefaultStorage;
|
||||
|
||||
CookieStorage* storage = PickStorage(aPattern);
|
||||
storage->RemoveCookiesWithOriginAttributes(aPattern, aBaseDomain);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3851,14 +3818,9 @@ nsresult nsCookieService::RemoveCookiesFromExactHost(
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
CookieStorage* storage = (aPattern.mPrivateBrowsingId.WasPassed() &&
|
||||
aPattern.mPrivateBrowsingId.Value() > 0)
|
||||
? mPrivateStorage
|
||||
: mDefaultStorage;
|
||||
|
||||
CookieStorage* storage = PickStorage(aPattern);
|
||||
storage->RemoveCookiesFromExactHost(aHost, baseDomain, aPattern);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -4033,3 +3995,37 @@ nsCookieService::CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsCookieService::IsInitialized() const {
|
||||
if (!mDefaultStorage) {
|
||||
NS_WARNING("No CookieStorage! Profile already close?");
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPrivateStorage);
|
||||
return true;
|
||||
}
|
||||
|
||||
CookieStorage* nsCookieService::PickStorage(const OriginAttributes& aAttrs) {
|
||||
MOZ_ASSERT(IsInitialized());
|
||||
EnsureReadComplete(true);
|
||||
|
||||
if (aAttrs.mPrivateBrowsingId > 0) {
|
||||
return mPrivateStorage;
|
||||
}
|
||||
|
||||
return mDefaultStorage;
|
||||
}
|
||||
|
||||
CookieStorage* nsCookieService::PickStorage(
|
||||
const OriginAttributesPattern& aAttrs) {
|
||||
MOZ_ASSERT(IsInitialized());
|
||||
EnsureReadComplete(true);
|
||||
|
||||
if (aAttrs.mPrivateBrowsingId.WasPassed() &&
|
||||
aAttrs.mPrivateBrowsingId.Value() > 0) {
|
||||
return mPrivateStorage;
|
||||
}
|
||||
|
||||
return mDefaultStorage;
|
||||
}
|
||||
|
@ -171,8 +171,8 @@ class nsCookieService final : public nsICookieService,
|
||||
nsresult CreateTableForSchemaVersion6();
|
||||
nsresult CreateTableForSchemaVersion5();
|
||||
void CloseCookieStorages();
|
||||
void HandleDBClosed(mozilla::net::CookieStorage* aCookieStorage);
|
||||
void RebuildCorruptDB(mozilla::net::CookieStorage* aCookieStorage);
|
||||
void HandleDBClosed(mozilla::net::CookieDefaultStorage* aCookieStorage);
|
||||
void RebuildCorruptDB(mozilla::net::CookieDefaultStorage* aCookieStorage);
|
||||
OpenDBResult Read();
|
||||
mozilla::UniquePtr<mozilla::net::CookieStruct> GetCookieFromRow(
|
||||
mozIStorageStatement* aRow);
|
||||
@ -237,6 +237,11 @@ class nsCookieService final : public nsICookieService,
|
||||
const nsCString& aBaseDomain);
|
||||
|
||||
protected:
|
||||
mozilla::net::CookieStorage* PickStorage(
|
||||
const mozilla::OriginAttributes& aAttrs);
|
||||
mozilla::net::CookieStorage* PickStorage(
|
||||
const mozilla::OriginAttributesPattern& aAttrs);
|
||||
|
||||
nsresult RemoveCookiesFromExactHost(
|
||||
const nsACString& aHost,
|
||||
const mozilla::OriginAttributesPattern& aPattern);
|
||||
@ -256,8 +261,8 @@ class nsCookieService final : public nsICookieService,
|
||||
|
||||
// we have two separate Cookie Storages: one for normal browsing and one for
|
||||
// private browsing.
|
||||
RefPtr<mozilla::net::CookieStorage> mDefaultStorage;
|
||||
RefPtr<mozilla::net::CookieStorage> mPrivateStorage;
|
||||
RefPtr<mozilla::net::CookieDefaultStorage> mDefaultStorage;
|
||||
RefPtr<mozilla::net::CookiePrivateStorage> mPrivateStorage;
|
||||
|
||||
uint16_t mMaxNumberOfCookies;
|
||||
uint16_t mMaxCookiesPerHost;
|
||||
|
Loading…
Reference in New Issue
Block a user