mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 1468501 - Implement a way to delete network cache by nsIPrincipal, r=mayhemer, r=michal
This commit is contained in:
parent
d55ae44eff
commit
28962b5168
@ -16,6 +16,7 @@
|
||||
#include "nsIDirectoryEnumerator.h"
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/net/MozURL.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
@ -93,7 +94,8 @@ CacheFileContextEvictor::ContextsCount()
|
||||
|
||||
nsresult
|
||||
CacheFileContextEvictor::AddContext(nsILoadContextInfo *aLoadContextInfo,
|
||||
bool aPinned)
|
||||
bool aPinned,
|
||||
const nsAString& aOrigin)
|
||||
{
|
||||
LOG(("CacheFileContextEvictor::AddContext() [this=%p, loadContextInfo=%p, pinned=%d]",
|
||||
this, aLoadContextInfo, aPinned));
|
||||
@ -107,7 +109,8 @@ CacheFileContextEvictor::AddContext(nsILoadContextInfo *aLoadContextInfo,
|
||||
for (uint32_t i = 0; i < mEntries.Length(); ++i) {
|
||||
if (mEntries[i]->mInfo &&
|
||||
mEntries[i]->mInfo->Equals(aLoadContextInfo) &&
|
||||
mEntries[i]->mPinned == aPinned) {
|
||||
mEntries[i]->mPinned == aPinned &&
|
||||
mEntries[i]->mOrigin.Equals(aOrigin)) {
|
||||
entry = mEntries[i];
|
||||
break;
|
||||
}
|
||||
@ -119,7 +122,8 @@ CacheFileContextEvictor::AddContext(nsILoadContextInfo *aLoadContextInfo,
|
||||
for (uint32_t i = mEntries.Length(); i > 0;) {
|
||||
--i;
|
||||
if (mEntries[i]->mInfo && mEntries[i]->mPinned == aPinned) {
|
||||
RemoveEvictInfoFromDisk(mEntries[i]->mInfo, mEntries[i]->mPinned);
|
||||
RemoveEvictInfoFromDisk(mEntries[i]->mInfo, mEntries[i]->mPinned,
|
||||
mEntries[i]->mOrigin);
|
||||
mEntries.RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
@ -129,12 +133,13 @@ CacheFileContextEvictor::AddContext(nsILoadContextInfo *aLoadContextInfo,
|
||||
entry = new CacheFileContextEvictorEntry();
|
||||
entry->mInfo = aLoadContextInfo;
|
||||
entry->mPinned = aPinned;
|
||||
entry->mOrigin = aOrigin;
|
||||
mEntries.AppendElement(entry);
|
||||
}
|
||||
|
||||
entry->mTimeStamp = PR_Now() / PR_USEC_PER_MSEC;
|
||||
|
||||
PersistEvictionInfoToDisk(aLoadContextInfo, aPinned);
|
||||
PersistEvictionInfoToDisk(aLoadContextInfo, aPinned, aOrigin);
|
||||
|
||||
if (mIndexIsUpToDate) {
|
||||
// Already existing context could be added again, in this case the iterator
|
||||
@ -263,7 +268,8 @@ CacheFileContextEvictor::WasEvicted(const nsACString &aKey, nsIFile *aFile,
|
||||
|
||||
nsresult
|
||||
CacheFileContextEvictor::PersistEvictionInfoToDisk(
|
||||
nsILoadContextInfo *aLoadContextInfo, bool aPinned)
|
||||
nsILoadContextInfo *aLoadContextInfo, bool aPinned,
|
||||
const nsAString& aOrigin)
|
||||
{
|
||||
LOG(("CacheFileContextEvictor::PersistEvictionInfoToDisk() [this=%p, "
|
||||
"loadContextInfo=%p]", this, aLoadContextInfo));
|
||||
@ -273,7 +279,7 @@ CacheFileContextEvictor::PersistEvictionInfoToDisk(
|
||||
MOZ_ASSERT(CacheFileIOManager::IsOnIOThread());
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
rv = GetContextFile(aLoadContextInfo, aPinned, getter_AddRefs(file));
|
||||
rv = GetContextFile(aLoadContextInfo, aPinned, aOrigin, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -299,7 +305,7 @@ CacheFileContextEvictor::PersistEvictionInfoToDisk(
|
||||
|
||||
nsresult
|
||||
CacheFileContextEvictor::RemoveEvictInfoFromDisk(
|
||||
nsILoadContextInfo *aLoadContextInfo, bool aPinned)
|
||||
nsILoadContextInfo *aLoadContextInfo, bool aPinned, const nsAString& aOrigin)
|
||||
{
|
||||
LOG(("CacheFileContextEvictor::RemoveEvictInfoFromDisk() [this=%p, "
|
||||
"loadContextInfo=%p]", this, aLoadContextInfo));
|
||||
@ -309,7 +315,7 @@ CacheFileContextEvictor::RemoveEvictInfoFromDisk(
|
||||
MOZ_ASSERT(CacheFileIOManager::IsOnIOThread());
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
rv = GetContextFile(aLoadContextInfo, aPinned, getter_AddRefs(file));
|
||||
rv = GetContextFile(aLoadContextInfo, aPinned, aOrigin, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -393,6 +399,16 @@ CacheFileContextEvictor::LoadEvictInfoFromDisk()
|
||||
decoded = Substring(decoded, 1);
|
||||
}
|
||||
|
||||
// Let's see if we have an origin.
|
||||
nsAutoCString origin;
|
||||
if (decoded.Contains('\t')) {
|
||||
auto split = decoded.Split('\t');
|
||||
MOZ_ASSERT(decoded.CountChar('\t') == 2);
|
||||
|
||||
origin = split.Get(0);
|
||||
decoded = split.Get(1);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadContextInfo> info;
|
||||
if (!NS_LITERAL_CSTRING("*").Equals(decoded)) {
|
||||
// "*" is indication of 'delete all', info left null will pass
|
||||
@ -417,6 +433,7 @@ CacheFileContextEvictor::LoadEvictInfoFromDisk()
|
||||
CacheFileContextEvictorEntry *entry = new CacheFileContextEvictorEntry();
|
||||
entry->mInfo = info;
|
||||
entry->mPinned = pinned;
|
||||
CopyUTF8toUTF16(origin, entry->mOrigin);
|
||||
entry->mTimeStamp = lastModifiedTime;
|
||||
mEntries.AppendElement(entry);
|
||||
}
|
||||
@ -427,6 +444,7 @@ CacheFileContextEvictor::LoadEvictInfoFromDisk()
|
||||
nsresult
|
||||
CacheFileContextEvictor::GetContextFile(nsILoadContextInfo *aLoadContextInfo,
|
||||
bool aPinned,
|
||||
const nsAString& aOrigin,
|
||||
nsIFile **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
@ -445,6 +463,10 @@ CacheFileContextEvictor::GetContextFile(nsILoadContextInfo *aLoadContextInfo,
|
||||
} else {
|
||||
keyPrefix.Append('*');
|
||||
}
|
||||
if (!aOrigin.IsEmpty()) {
|
||||
keyPrefix.Append('\t');
|
||||
keyPrefix.Append(NS_ConvertUTF16toUTF8(aOrigin));
|
||||
}
|
||||
|
||||
nsAutoCString data64;
|
||||
rv = Base64Encode(keyPrefix, data64);
|
||||
@ -516,7 +538,7 @@ CacheFileContextEvictor::StartEvicting()
|
||||
MOZ_ASSERT(CacheFileIOManager::IsOnIOThread());
|
||||
|
||||
if (mEvicting) {
|
||||
LOG(("CacheFileContextEvictor::StartEvicting() - already evicintg."));
|
||||
LOG(("CacheFileContextEvictor::StartEvicting() - already evicting."));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -590,7 +612,8 @@ CacheFileContextEvictor::EvictEntries()
|
||||
LOG(("CacheFileContextEvictor::EvictEntries() - No more entries left in "
|
||||
"iterator. [iterator=%p, info=%p]", mEntries[0]->mIterator.get(),
|
||||
mEntries[0]->mInfo.get()));
|
||||
RemoveEvictInfoFromDisk(mEntries[0]->mInfo, mEntries[0]->mPinned);
|
||||
RemoveEvictInfoFromDisk(mEntries[0]->mInfo, mEntries[0]->mPinned,
|
||||
mEntries[0]->mOrigin);
|
||||
mEntries.RemoveElementAt(0);
|
||||
continue;
|
||||
} else if (NS_FAILED(rv)) {
|
||||
@ -634,6 +657,47 @@ CacheFileContextEvictor::EvictEntries()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mEntries[0]->mOrigin.IsEmpty()) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
CacheFileIOManager::gInstance->GetFile(&hash, getter_AddRefs(file));
|
||||
|
||||
// Read metadata from the file synchronously
|
||||
RefPtr<CacheFileMetadata> metadata = new CacheFileMetadata();
|
||||
rv = metadata->SyncReadMetadata(file);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now get the context + enhance id + URL from the key.
|
||||
nsAutoCString key;
|
||||
metadata->GetKey(key);
|
||||
|
||||
nsAutoCString uriSpec;
|
||||
|
||||
RefPtr<nsILoadContextInfo> info =
|
||||
CacheFileUtils::ParseKey(key, nullptr, &uriSpec);
|
||||
MOZ_ASSERT(info);
|
||||
if (!info) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RefPtr<MozURL> url;
|
||||
rv = MozURL::Init(getter_AddRefs(url), uriSpec);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("CacheFileContextEvictor::EvictEntries() - Skipping entry since MozURL "
|
||||
"fails in the parsing of the uriSpec"));
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoCString urlOrigin;
|
||||
url->Origin(urlOrigin);
|
||||
if (urlOrigin.Equals(NS_ConvertUTF16toUTF8(mEntries[0]->mOrigin))) {
|
||||
LOG(("CacheFileContextEvictor::EvictEntries() - Skipping entry since origin "
|
||||
"doesn't match"));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoCString leafName;
|
||||
CacheFileIOManager::HashToStr(&hash, leafName);
|
||||
|
||||
|
@ -21,6 +21,7 @@ struct CacheFileContextEvictorEntry
|
||||
{
|
||||
nsCOMPtr<nsILoadContextInfo> mInfo;
|
||||
bool mPinned;
|
||||
nsString mOrigin; // it can be empty
|
||||
PRTime mTimeStamp; // in milliseconds
|
||||
RefPtr<CacheIndexIterator> mIterator;
|
||||
};
|
||||
@ -41,8 +42,9 @@ public:
|
||||
|
||||
// Returns number of contexts that are being evicted.
|
||||
uint32_t ContextsCount();
|
||||
// Start evicting given context.
|
||||
nsresult AddContext(nsILoadContextInfo *aLoadContextInfo, bool aPinned);
|
||||
// Start evicting given context and an origin, if not empty.
|
||||
nsresult AddContext(nsILoadContextInfo *aLoadContextInfo, bool aPinned,
|
||||
const nsAString& aOrigin);
|
||||
// CacheFileIOManager calls this method when CacheIndex's state changes. We
|
||||
// check whether the index is up to date and start or stop evicting according
|
||||
// to index's state.
|
||||
@ -60,15 +62,17 @@ private:
|
||||
// done for every context added to the evictor to be able to recover eviction
|
||||
// after a shutdown or crash. When the context file is found after startup, we
|
||||
// restore mTimeStamp from the last modified time of the file.
|
||||
nsresult PersistEvictionInfoToDisk(nsILoadContextInfo *aLoadContextInfo, bool aPinned);
|
||||
nsresult PersistEvictionInfoToDisk(nsILoadContextInfo *aLoadContextInfo,
|
||||
bool aPinned, const nsAString& aOrigin);
|
||||
// Once we are done with eviction for the given context, the eviction info is
|
||||
// removed from the disk.
|
||||
nsresult RemoveEvictInfoFromDisk(nsILoadContextInfo *aLoadContextInfo, bool aPinned);
|
||||
nsresult RemoveEvictInfoFromDisk(nsILoadContextInfo *aLoadContextInfo,
|
||||
bool aPinned, const nsAString& aOrigin);
|
||||
// Tries to load all contexts from the disk. This method is called just once
|
||||
// after startup.
|
||||
nsresult LoadEvictInfoFromDisk();
|
||||
nsresult GetContextFile(nsILoadContextInfo *aLoadContextInfo, bool aPinned,
|
||||
nsIFile **_retval);
|
||||
const nsAString& aOrigin, nsIFile **_retval);
|
||||
|
||||
void CreateIterators();
|
||||
void CloseIterators();
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsICacheStorageVisitor.h"
|
||||
#include "nsISizeOf.h"
|
||||
#include "mozilla/net/MozURL.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Services.h"
|
||||
@ -3134,7 +3135,9 @@ CacheFileIOManager::EvictAllInternal()
|
||||
|
||||
// static
|
||||
nsresult
|
||||
CacheFileIOManager::EvictByContext(nsILoadContextInfo *aLoadContextInfo, bool aPinned)
|
||||
CacheFileIOManager::EvictByContext(nsILoadContextInfo *aLoadContextInfo,
|
||||
bool aPinned,
|
||||
const nsAString& aOrigin)
|
||||
{
|
||||
LOG(("CacheFileIOManager::EvictByContext() [loadContextInfo=%p]",
|
||||
aLoadContextInfo));
|
||||
@ -3147,12 +3150,13 @@ CacheFileIOManager::EvictByContext(nsILoadContextInfo *aLoadContextInfo, bool aP
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev;
|
||||
ev = NewRunnableMethod<nsCOMPtr<nsILoadContextInfo>, bool>(
|
||||
ev = NewRunnableMethod<nsCOMPtr<nsILoadContextInfo>, bool, nsString>(
|
||||
"net::CacheFileIOManager::EvictByContextInternal",
|
||||
ioMan,
|
||||
&CacheFileIOManager::EvictByContextInternal,
|
||||
aLoadContextInfo,
|
||||
aPinned);
|
||||
aPinned,
|
||||
aOrigin);
|
||||
|
||||
rv = ioMan->mIOThread->DispatchAfterPendingOpens(ev);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@ -3163,7 +3167,9 @@ CacheFileIOManager::EvictByContext(nsILoadContextInfo *aLoadContextInfo, bool aP
|
||||
}
|
||||
|
||||
nsresult
|
||||
CacheFileIOManager::EvictByContextInternal(nsILoadContextInfo *aLoadContextInfo, bool aPinned)
|
||||
CacheFileIOManager::EvictByContextInternal(nsILoadContextInfo *aLoadContextInfo,
|
||||
bool aPinned,
|
||||
const nsAString& aOrigin)
|
||||
{
|
||||
LOG(("CacheFileIOManager::EvictByContextInternal() [loadContextInfo=%p, pinned=%d]",
|
||||
aLoadContextInfo, aPinned));
|
||||
@ -3206,6 +3212,8 @@ CacheFileIOManager::EvictByContextInternal(nsILoadContextInfo *aLoadContextInfo,
|
||||
}
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 origin(aOrigin);
|
||||
|
||||
// Doom all active handles that matches the load context
|
||||
nsTArray<RefPtr<CacheFileHandle> > handles;
|
||||
mHandles.GetActiveHandles(&handles);
|
||||
@ -3213,18 +3221,30 @@ CacheFileIOManager::EvictByContextInternal(nsILoadContextInfo *aLoadContextInfo,
|
||||
for (uint32_t i = 0; i < handles.Length(); ++i) {
|
||||
CacheFileHandle* handle = handles[i];
|
||||
|
||||
if (aLoadContextInfo) {
|
||||
bool equals;
|
||||
rv = CacheFileUtils::KeyMatchesLoadContextInfo(handle->Key(),
|
||||
aLoadContextInfo,
|
||||
&equals);
|
||||
nsAutoCString uriSpec;
|
||||
RefPtr<nsILoadContextInfo> info =
|
||||
CacheFileUtils::ParseKey(handle->Key(), nullptr, &uriSpec);
|
||||
if (!info) {
|
||||
LOG(("CacheFileIOManager::EvictByContextInternal() - Cannot parse key in "
|
||||
"handle! [handle=%p, key=%s]", handle, handle->Key().get()));
|
||||
MOZ_CRASH("Unexpected error!");
|
||||
}
|
||||
|
||||
if (aLoadContextInfo && !info->Equals(aLoadContextInfo)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!origin.IsEmpty()) {
|
||||
RefPtr<MozURL> url;
|
||||
rv = MozURL::Init(getter_AddRefs(url), uriSpec);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("CacheFileIOManager::EvictByContextInternal() - Cannot parse key in "
|
||||
"handle! [handle=%p, key=%s]", handle, handle->Key().get()));
|
||||
MOZ_CRASH("Unexpected error!");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!equals) {
|
||||
nsAutoCString urlOrigin;
|
||||
url->Origin(urlOrigin);
|
||||
|
||||
if (!urlOrigin.Equals(origin)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -3250,7 +3270,7 @@ CacheFileIOManager::EvictByContextInternal(nsILoadContextInfo *aLoadContextInfo,
|
||||
mContextEvictor->Init(mCacheDirectory);
|
||||
}
|
||||
|
||||
mContextEvictor->AddContext(aLoadContextInfo, aPinned);
|
||||
mContextEvictor->AddContext(aLoadContextInfo, aPinned, aOrigin);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -332,7 +332,8 @@ public:
|
||||
static nsresult EvictIfOverLimit();
|
||||
static nsresult EvictAll();
|
||||
static nsresult EvictByContext(nsILoadContextInfo *aLoadContextInfo,
|
||||
bool aPinning);
|
||||
bool aPinning,
|
||||
const nsAString& aOrigin);
|
||||
|
||||
static nsresult InitIndexEntry(CacheFileHandle *aHandle,
|
||||
OriginAttrsHash aOriginAttrsHash,
|
||||
@ -417,7 +418,7 @@ private:
|
||||
nsresult OverLimitEvictionInternal();
|
||||
nsresult EvictAllInternal();
|
||||
nsresult EvictByContextInternal(nsILoadContextInfo *aLoadContextInfo,
|
||||
bool aPinning);
|
||||
bool aPinning, const nsAString& aOrigin);
|
||||
|
||||
nsresult TrashDirectory(nsIFile *aFile);
|
||||
static void OnTrashTimer(nsITimer *aTimer, void *aClosure);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "nsIFile.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
@ -795,7 +796,117 @@ NS_IMETHODIMP CacheStorageService::Clear()
|
||||
|
||||
// Passing null as a load info means to evict all contexts.
|
||||
// EvictByContext() respects the entry pinning. EvictAll() does not.
|
||||
rv = CacheFileIOManager::EvictByContext(nullptr, false);
|
||||
rv = CacheFileIOManager::EvictByContext(nullptr, false, EmptyString());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP CacheStorageService::ClearOrigin(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (NS_WARN_IF(!aPrincipal)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoString origin;
|
||||
rv = nsContentUtils::GetUTFOrigin(aPrincipal, origin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ClearOriginInternal(origin, aPrincipal->OriginAttributesRef(), true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ClearOriginInternal(origin, aPrincipal->OriginAttributesRef(), false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
RemoveExactEntry(CacheEntryTable* aEntries,
|
||||
nsACString const& aKey,
|
||||
CacheEntry* aEntry,
|
||||
bool aOverwrite)
|
||||
{
|
||||
RefPtr<CacheEntry> existingEntry;
|
||||
if (!aEntries->Get(aKey, getter_AddRefs(existingEntry))) {
|
||||
LOG(("RemoveExactEntry [entry=%p already gone]", aEntry));
|
||||
return false; // Already removed...
|
||||
}
|
||||
|
||||
if (!aOverwrite && existingEntry != aEntry) {
|
||||
LOG(("RemoveExactEntry [entry=%p already replaced]", aEntry));
|
||||
return false; // Already replaced...
|
||||
}
|
||||
|
||||
LOG(("RemoveExactEntry [entry=%p removed]", aEntry));
|
||||
aEntries->Remove(aKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CacheStorageService::ClearOriginInternal(const nsAString& aOrigin,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
bool aAnonymous)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
RefPtr<LoadContextInfo> info =
|
||||
GetLoadContextInfo(aAnonymous, aOriginAttributes);
|
||||
if (NS_WARN_IF(!info)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mozilla::MutexAutoLock lock(mLock);
|
||||
|
||||
if (sGlobalEntryTables) {
|
||||
for (auto iter = sGlobalEntryTables->Iter(); !iter.Done(); iter.Next()) {
|
||||
bool matches = false;
|
||||
rv = CacheFileUtils::KeyMatchesLoadContextInfo(iter.Key(), info,
|
||||
&matches);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!matches) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CacheEntryTable* table = iter.UserData();
|
||||
MOZ_ASSERT(table);
|
||||
|
||||
nsTArray<RefPtr<CacheEntry>> entriesToDelete;
|
||||
|
||||
for (auto entryIter = table->Iter(); !entryIter.Done(); entryIter.Next()) {
|
||||
CacheEntry* entry = entryIter.UserData();
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), entry->GetURI());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString origin;
|
||||
rv = nsContentUtils::GetUTFOrigin(uri, origin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (origin != aOrigin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entriesToDelete.AppendElement(entry);
|
||||
}
|
||||
|
||||
for (RefPtr<CacheEntry>& entry : entriesToDelete) {
|
||||
nsAutoCString entryKey;
|
||||
rv = entry->HashingKey(entryKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("aEntry->HashingKey() failed?");
|
||||
return rv;
|
||||
}
|
||||
|
||||
RemoveExactEntry(table, entryKey, entry, false /* don't overwrite */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = CacheFileIOManager::EvictByContext(info, false /* pinned */, aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
@ -976,28 +1087,6 @@ AddExactEntry(CacheEntryTable* aEntries,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
RemoveExactEntry(CacheEntryTable* aEntries,
|
||||
nsACString const& aKey,
|
||||
CacheEntry* aEntry,
|
||||
bool aOverwrite)
|
||||
{
|
||||
RefPtr<CacheEntry> existingEntry;
|
||||
if (!aEntries->Get(aKey, getter_AddRefs(existingEntry))) {
|
||||
LOG(("RemoveExactEntry [entry=%p already gone]", aEntry));
|
||||
return false; // Already removed...
|
||||
}
|
||||
|
||||
if (!aOverwrite && existingEntry != aEntry) {
|
||||
LOG(("RemoveExactEntry [entry=%p already replaced]", aEntry));
|
||||
return false; // Already replaced...
|
||||
}
|
||||
|
||||
LOG(("RemoveExactEntry [entry=%p removed]", aEntry));
|
||||
aEntries->Remove(aKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageService::RemoveEntry(CacheEntry* aEntry, bool aOnlyUnreferenced)
|
||||
{
|
||||
@ -1844,7 +1933,7 @@ CacheStorageService::DoomStorageEntries(const nsACString& aContextKey,
|
||||
|
||||
if (aContext && !aContext->IsPrivate()) {
|
||||
LOG((" dooming disk entries"));
|
||||
CacheFileIOManager::EvictByContext(aContext, aPinned);
|
||||
CacheFileIOManager::EvictByContext(aContext, aPinned, EmptyString());
|
||||
}
|
||||
} else {
|
||||
LOG((" dooming memory-only storage of %s", aContextKey.BeginReading()));
|
||||
|
@ -30,6 +30,9 @@ class nsIThread;
|
||||
class nsIEventTarget;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
|
||||
namespace net {
|
||||
|
||||
class CacheStorageService;
|
||||
@ -311,6 +314,10 @@ private:
|
||||
bool aReplace,
|
||||
CacheEntryHandle** aResult);
|
||||
|
||||
nsresult ClearOriginInternal(const nsAString& aOrigin,
|
||||
const mozilla::OriginAttributes& aOriginAttributes,
|
||||
bool aAnonymous);
|
||||
|
||||
static CacheStorageService* sSelf;
|
||||
|
||||
mozilla::Mutex mLock;
|
||||
|
@ -10,6 +10,7 @@ interface nsIApplicationCache;
|
||||
interface nsIEventTarget;
|
||||
interface nsICacheStorageConsumptionObserver;
|
||||
interface nsICacheStorageVisitor;
|
||||
interface nsIPrincipal;
|
||||
|
||||
/**
|
||||
* Provides access to particual cache storages of the network URI cache.
|
||||
@ -70,6 +71,14 @@ interface nsICacheStorageService : nsISupports
|
||||
*/
|
||||
nsICacheStorage synthesizedCacheStorage(in nsILoadContextInfo aLoadContextInfo);
|
||||
|
||||
/**
|
||||
* Evict any cache entry having the same origin of aPrincipal.
|
||||
*
|
||||
* @param aPrincipal
|
||||
* The principal to compare the entries with.
|
||||
*/
|
||||
void clearOrigin(in nsIPrincipal aPrincipal);
|
||||
|
||||
/**
|
||||
* Evict the whole cache.
|
||||
*/
|
||||
|
40
netwerk/test/unit/test_cache2-32-clear-origin.js
Normal file
40
netwerk/test/unit/test_cache2-32-clear-origin.js
Normal file
@ -0,0 +1,40 @@
|
||||
const URL = "http://example.net";
|
||||
const URL2 = "http://foo.bar";
|
||||
|
||||
function run_test()
|
||||
{
|
||||
do_get_profile();
|
||||
|
||||
asyncOpenCacheEntry(URL + "/a", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
|
||||
new OpenCallback(NEW, "e1m", "e1d", function(entry) {
|
||||
asyncOpenCacheEntry(URL + "/a", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
|
||||
new OpenCallback(NORMAL, "e1m", "e1d", function(entry) {
|
||||
asyncOpenCacheEntry(URL2 + "/a", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
|
||||
new OpenCallback(NEW, "f1m", "f1d", function(entry) {
|
||||
asyncOpenCacheEntry(URL2 + "/a", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
|
||||
new OpenCallback(NORMAL, "f1m", "f1d", function(entry) {
|
||||
var url = Services.io.newURI(URL);
|
||||
var principal = Services.scriptSecurityManager.createCodebasePrincipal(url, {});
|
||||
|
||||
get_cache_service().clearOrigin(principal);
|
||||
|
||||
asyncOpenCacheEntry(URL + "/a", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
|
||||
new OpenCallback(NEW, "e1m", "e1d", function(entry) {
|
||||
asyncOpenCacheEntry(URL2 + "/a", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
|
||||
new OpenCallback(NORMAL, "f1m", "f1d", function(entry) {
|
||||
finish_cache2_test();
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
do_test_pending();
|
||||
}
|
@ -78,6 +78,7 @@ skip-if = true
|
||||
[test_cache2-30c-pinning-deferred-doom.js]
|
||||
[test_cache2-30d-pinning-WasEvicted-API.js]
|
||||
[test_cache2-31-visit-all.js]
|
||||
[test_cache2-32-clear-origin.js]
|
||||
[test_partial_response_entry_size_smart_shrink.js]
|
||||
[test_304_responses.js]
|
||||
[test_421.js]
|
||||
|
@ -86,6 +86,13 @@ const CookieCleaner = {
|
||||
};
|
||||
|
||||
const NetworkCacheCleaner = {
|
||||
deleteByPrincipal(aPrincipal) {
|
||||
return new Promise(aResolve => {
|
||||
Services.cache2.asyncClearOrigin(aPrincipal);
|
||||
aResolve();
|
||||
});
|
||||
},
|
||||
|
||||
deleteAll() {
|
||||
return new Promise(aResolve => {
|
||||
Services.cache2.clear();
|
||||
|
Loading…
Reference in New Issue
Block a user