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:
Ehsan Akhgari 2019-11-27 11:01:45 +00:00
Родитель 323c43dc11
Коммит 6216893099
4 изменённых файлов: 103 добавлений и 41 удалений

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

@ -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 = {