зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1599237 - Add a cookie manager API for deleting cookies by a time range, and use it in the clear data service; r=baku
Differential Revision: https://phabricator.services.mozilla.com/D54646 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
323c43dc11
Коммит
6216893099
|
@ -58,6 +58,7 @@
|
|||
#include "nsIInputStream.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/storage.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
|
@ -71,6 +72,7 @@
|
|||
#include "nsVariant.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::net;
|
||||
|
||||
// Create key from baseDomain that will access the default cookie namespace.
|
||||
|
@ -4863,6 +4865,88 @@ nsresult nsCookieService::RemoveCookiesFromExactHost(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class RemoveAllSinceRunnable : public Runnable {
|
||||
public:
|
||||
typedef nsTArray<nsCOMPtr<nsICookie>> CookieArray;
|
||||
RemoveAllSinceRunnable(Promise* aPromise, nsCookieService* aSelf,
|
||||
CookieArray&& aCookieArray, int64_t aSinceWhen)
|
||||
: Runnable("RemoveAllSinceRunnable"),
|
||||
mPromise(aPromise),
|
||||
mSelf(aSelf),
|
||||
mList(std::move(aCookieArray)),
|
||||
mIndex(0),
|
||||
mSinceWhen(aSinceWhen) {}
|
||||
|
||||
NS_IMETHODIMP Run() {
|
||||
RemoveSome();
|
||||
|
||||
if (mIndex < mList.Length()) {
|
||||
return NS_DispatchToCurrentThread(this);
|
||||
} else {
|
||||
mPromise->MaybeResolveWithUndefined();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
void RemoveSome() {
|
||||
for (CookieArray::size_type iter = 0;
|
||||
iter < kYieldPeriod && mIndex < mList.Length(); ++mIndex, ++iter) {
|
||||
nsCookie* cookie = static_cast<nsCookie*>(mList[mIndex].get());
|
||||
if (cookie->CreationTime() > mSinceWhen &&
|
||||
NS_FAILED(mSelf->Remove(cookie->Host(), cookie->OriginAttributesRef(),
|
||||
cookie->Name(), cookie->Path()))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<Promise> mPromise;
|
||||
RefPtr<nsCookieService> mSelf;
|
||||
CookieArray mList;
|
||||
CookieArray::size_type mIndex;
|
||||
int64_t mSinceWhen;
|
||||
static const CookieArray::size_type kYieldPeriod = 10;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookieService::RemoveAllSince(int64_t aSinceWhen, JSContext* aCx,
|
||||
Promise** aRetVal) {
|
||||
nsIGlobalObject* globalObject = xpc::CurrentNativeGlobal(aCx);
|
||||
if (NS_WARN_IF(!globalObject)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
ErrorResult result;
|
||||
RefPtr<Promise> promise = Promise::Create(globalObject, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
EnsureReadComplete(true);
|
||||
|
||||
typedef RemoveAllSinceRunnable::CookieArray CookieArray;
|
||||
CookieArray cookieList(mDBState->cookieCount);
|
||||
for (auto iter = mDBState->hostTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
const nsCookieEntry::ArrayType& cookies = iter.Get()->GetCookies();
|
||||
for (nsCookieEntry::IndexType i = 0; i < cookies.Length(); ++i) {
|
||||
cookieList.AppendElement(cookies[i]);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<RemoveAllSinceRunnable> runMe = new RemoveAllSinceRunnable(
|
||||
promise, this, std::move(cookieList), aSinceWhen);
|
||||
|
||||
promise.forget(aRetVal);
|
||||
|
||||
return runMe->Run();
|
||||
}
|
||||
|
||||
// find an secure cookie specified by host and name
|
||||
bool nsCookieService::FindSecureCookie(const nsCookieKey& aKey,
|
||||
nsCookie* aCookie) {
|
||||
|
|
|
@ -232,6 +232,13 @@ class nsCookieService final : public nsICookieService,
|
|||
const OriginAttributes& aOriginAttrs,
|
||||
nsTArray<nsCookie*>& aCookieList);
|
||||
|
||||
/**
|
||||
* This method is a helper that allows calling nsICookieManager::Remove()
|
||||
* with OriginAttributes parameter.
|
||||
*/
|
||||
nsresult Remove(const nsACString& aHost, const OriginAttributes& aAttrs,
|
||||
const nsACString& aName, const nsACString& aPath);
|
||||
|
||||
protected:
|
||||
virtual ~nsCookieService();
|
||||
|
||||
|
@ -337,14 +344,6 @@ class nsCookieService final : public nsICookieService,
|
|||
const mozilla::OriginAttributesPattern& aPattern,
|
||||
const nsCString& aBaseDomain);
|
||||
|
||||
/**
|
||||
* This method is a helper that allows calling nsICookieManager::Remove()
|
||||
* with OriginAttributes parameter.
|
||||
* NOTE: this could be added to a public interface if we happen to need it.
|
||||
*/
|
||||
nsresult Remove(const nsACString& aHost, const OriginAttributes& aAttrs,
|
||||
const nsACString& aName, const nsACString& aPath);
|
||||
|
||||
protected:
|
||||
nsresult RemoveCookiesFromExactHost(
|
||||
const nsACString& aHost,
|
||||
|
|
|
@ -237,4 +237,15 @@ interface nsICookieManager : nsISupports
|
|||
* @param aPattern origin attribute pattern in JSON format
|
||||
*/
|
||||
void removeCookiesFromExactHost(in AUTF8String aHost, in AString aPattern);
|
||||
|
||||
/**
|
||||
* Removes all cookies that were created on or after aSinceWhen, and returns
|
||||
* a Promise which will be resolved when the last such cookie has been
|
||||
* removed.
|
||||
*
|
||||
* @param aSinceWhen the starting point in time after which no cookies should
|
||||
* be created when the Promise returned from this method is resolved.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
Promise removeAllSince(in int64_t aSinceWhen);
|
||||
};
|
||||
|
|
|
@ -73,11 +73,7 @@ const CookieCleaner = {
|
|||
},
|
||||
|
||||
deleteByRange(aFrom, aTo) {
|
||||
let enumerator = Services.cookies.enumerator;
|
||||
return this._deleteInternal(
|
||||
enumerator,
|
||||
aCookie => aCookie.creationTime > aFrom
|
||||
);
|
||||
return Services.cookies.removeAllSince(aFrom);
|
||||
},
|
||||
|
||||
deleteAll() {
|
||||
|
@ -86,34 +82,6 @@ const CookieCleaner = {
|
|||
aResolve();
|
||||
});
|
||||
},
|
||||
|
||||
_deleteInternal(aEnumerator, aCb) {
|
||||
// A number of iterations after which to yield time back to the system.
|
||||
const YIELD_PERIOD = 10;
|
||||
|
||||
return new Promise((aResolve, aReject) => {
|
||||
let count = 0;
|
||||
for (let cookie of aEnumerator) {
|
||||
if (aCb(cookie)) {
|
||||
Services.cookies.remove(
|
||||
cookie.host,
|
||||
cookie.name,
|
||||
cookie.path,
|
||||
cookie.originAttributes
|
||||
);
|
||||
// We don't want to block the main-thread.
|
||||
if (++count % YIELD_PERIOD == 0) {
|
||||
setTimeout(() => {
|
||||
this._deleteInternal(aEnumerator, aCb).then(aResolve, aReject);
|
||||
}, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aResolve();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const CertCleaner = {
|
||||
|
|
Загрузка…
Ссылка в новой задаче