mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 01:08:21 +00:00
Bug 1360480 - about:url-classifier: Cache information. r=francois
MozReview-Commit-ID: 4YXtb2KPgwL --HG-- extra : rebase_source : ad9f897aa5772d6001a757e189730d427713f915
This commit is contained in:
parent
de5fa4f269
commit
c632a44157
@ -886,6 +886,18 @@ Classifier::ApplyFullHashes(nsTArray<TableUpdate*>* aUpdates)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Classifier::GetCacheInfo(const nsACString& aTable,
|
||||
nsIUrlClassifierCacheInfo** aCache)
|
||||
{
|
||||
LookupCache* lookupCache = GetLookupCache(aTable);
|
||||
if (!lookupCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
lookupCache->GetCacheInfo(aCache);
|
||||
}
|
||||
|
||||
void
|
||||
Classifier::DropStores()
|
||||
{
|
||||
|
@ -124,6 +124,9 @@ public:
|
||||
LookupCache *GetLookupCache(const nsACString& aTable,
|
||||
bool aForUpdate = false);
|
||||
|
||||
void GetCacheInfo(const nsACString& aTable,
|
||||
nsIUrlClassifierCacheInfo** aCache);
|
||||
|
||||
private:
|
||||
void DropStores();
|
||||
void DeleteTables(nsIFile* aDirectory, const nsTArray<nsCString>& aTables);
|
||||
|
@ -6,11 +6,13 @@
|
||||
#include "LookupCache.h"
|
||||
#include "HashStore.h"
|
||||
#include "nsISeekableStream.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "prprf.h"
|
||||
#include "Classifier.h"
|
||||
#include "nsUrlClassifierInfo.h"
|
||||
|
||||
// We act as the main entry point for all the real lookups,
|
||||
// so note that those are not done to the actual HashStore.
|
||||
@ -47,6 +49,22 @@ const int CacheResultV4::VER = CacheResult::V4;
|
||||
|
||||
const int LookupCacheV2::VER = 2;
|
||||
|
||||
static
|
||||
void CStringToHexString(const nsACString& aIn, nsACString& aOut)
|
||||
{
|
||||
static const char* const lut = "0123456789ABCDEF";
|
||||
|
||||
size_t len = aIn.Length();
|
||||
MOZ_ASSERT(len <= COMPLETE_SIZE);
|
||||
|
||||
aOut.SetCapacity(2 * len);
|
||||
for (size_t i = 0; i < aIn.Length(); ++i) {
|
||||
const char c = static_cast<const char>(aIn[i]);
|
||||
aOut.Append(lut[(c >> 4) & 0x0F]);
|
||||
aOut.Append(lut[c & 15]);
|
||||
}
|
||||
}
|
||||
|
||||
LookupCache::LookupCache(const nsACString& aTableName,
|
||||
const nsACString& aProvider,
|
||||
nsIFile* aRootStoreDir)
|
||||
@ -213,6 +231,49 @@ LookupCache::ClearAll()
|
||||
mPrimed = false;
|
||||
}
|
||||
|
||||
void
|
||||
LookupCache::GetCacheInfo(nsIUrlClassifierCacheInfo** aCache)
|
||||
{
|
||||
MOZ_ASSERT(aCache);
|
||||
|
||||
RefPtr<nsUrlClassifierCacheInfo> info = new nsUrlClassifierCacheInfo;
|
||||
info->table = mTableName;
|
||||
|
||||
for (auto iter = mCache.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
RefPtr<nsUrlClassifierCacheEntry> entry = new nsUrlClassifierCacheEntry;
|
||||
|
||||
// Set prefix of the cache entry.
|
||||
nsAutoCString prefix(reinterpret_cast<const char*>(&iter.Key()), PREFIX_SIZE);
|
||||
CStringToHexString(prefix, entry->prefix);
|
||||
|
||||
// Set expiry of the cache entry.
|
||||
CachedFullHashResponse* response = iter.Data();
|
||||
entry->expirySec = response->negativeCacheExpirySec;
|
||||
|
||||
// Set positive cache.
|
||||
FullHashExpiryCache& fullHashes = response->fullHashes;
|
||||
for (auto iter2 = fullHashes.ConstIter(); !iter2.Done(); iter2.Next()) {
|
||||
RefPtr<nsUrlClassifierPositiveCacheEntry> match =
|
||||
new nsUrlClassifierPositiveCacheEntry;
|
||||
|
||||
// Set fullhash of positive cache entry.
|
||||
CStringToHexString(iter2.Key(), match->fullhash);
|
||||
|
||||
// Set expiry of positive cache entry.
|
||||
match->expirySec = iter2.Data();
|
||||
|
||||
entry->matches.AppendElement(
|
||||
static_cast<nsIUrlClassifierPositiveCacheEntry*>(match));
|
||||
}
|
||||
|
||||
info->entries.AppendElement(static_cast<nsIUrlClassifierCacheEntry*>(entry));
|
||||
}
|
||||
|
||||
NS_ADDREF(*aCache = info);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
LookupCache::IsCanonicalizedIP(const nsACString& aHost)
|
||||
{
|
||||
@ -425,21 +486,6 @@ LookupCache::LoadPrefixSet()
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
static
|
||||
void CStringToHexString(const nsACString& aIn, nsACString& aOut)
|
||||
{
|
||||
static const char* const lut = "0123456789ABCDEF";
|
||||
// 32 bytes is the longest hash
|
||||
size_t len = COMPLETE_SIZE;
|
||||
|
||||
aOut.SetCapacity(2 * len);
|
||||
for (size_t i = 0; i < aIn.Length(); ++i) {
|
||||
const char c = static_cast<const char>(aIn[i]);
|
||||
aOut.Append(lut[(c >> 4) & 0x0F]);
|
||||
aOut.Append(lut[c & 15]);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
nsCString GetFormattedTimeString(int64_t aCurTimeSec)
|
||||
{
|
||||
@ -461,16 +507,19 @@ LookupCache::DumpCache()
|
||||
|
||||
for (auto iter = mCache.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
CachedFullHashResponse* response = iter.Data();
|
||||
LOG(("Caches prefix: %X, Expire time: %s",
|
||||
iter.Key(),
|
||||
GetFormattedTimeString(response->negativeCacheExpirySec).get()));
|
||||
|
||||
nsAutoCString prefix;
|
||||
CStringToHexString(
|
||||
nsCString(reinterpret_cast<const char*>(&iter.Key()), PREFIX_SIZE), prefix);
|
||||
LOG(("Cache prefix(%s): %s, Expiry: %s", mTableName.get(), prefix.get(),
|
||||
GetFormattedTimeString(response->negativeCacheExpirySec).get()));
|
||||
|
||||
FullHashExpiryCache& fullHashes = response->fullHashes;
|
||||
for (auto iter2 = fullHashes.ConstIter(); !iter2.Done(); iter2.Next()) {
|
||||
nsAutoCString strFullhash;
|
||||
CStringToHexString(iter2.Key(), strFullhash);
|
||||
LOG((" - %s, Expire time: %s", strFullhash.get(),
|
||||
GetFormattedTimeString(iter2.Data()).get()));
|
||||
nsAutoCString fullhash;
|
||||
CStringToHexString(iter2.Key(), fullhash);
|
||||
LOG((" - %s, Expiry: %s", fullhash.get(),
|
||||
GetFormattedTimeString(iter2.Data()).get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -601,18 +650,14 @@ LookupCacheV2::AddGethashResultToCache(AddCompleteArray& aAddCompletes,
|
||||
reinterpret_cast<const char*>(add.CompleteHash().buf), COMPLETE_SIZE);
|
||||
|
||||
CachedFullHashResponse* response = mCache.LookupOrAdd(add.ToUint32());
|
||||
// Set negative cache expiry to the same value as positive cache
|
||||
// expiry when the gethash request returns a complete match.
|
||||
if (response->negativeCacheExpirySec == 0) {
|
||||
response->negativeCacheExpirySec = defaultExpirySec;
|
||||
}
|
||||
response->negativeCacheExpirySec = defaultExpirySec;
|
||||
|
||||
FullHashExpiryCache& fullHashes = response->fullHashes;
|
||||
fullHashes.Put(fullhash, defaultExpirySec);
|
||||
}
|
||||
|
||||
for (const Prefix& prefix : aMissPrefixes) {
|
||||
CachedFullHashResponse* response = mCache.LookupOrAdd(prefix.ToUint32());
|
||||
|
||||
response->negativeCacheExpirySec = defaultExpirySec;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "VariableLengthPrefixSet.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
#include "nsIUrlClassifierInfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace safebrowsing {
|
||||
@ -209,6 +210,8 @@ public:
|
||||
void DumpCache();
|
||||
#endif
|
||||
|
||||
void GetCacheInfo(nsIUrlClassifierCacheInfo** aCache);
|
||||
|
||||
virtual nsresult Open();
|
||||
virtual nsresult Init() = 0;
|
||||
virtual nsresult ClearPrefixes() = 0;
|
||||
|
@ -12,6 +12,7 @@ TEST_DIRS += ['tests']
|
||||
XPIDL_SOURCES += [
|
||||
'nsIUrlClassifierDBService.idl',
|
||||
'nsIUrlClassifierHashCompleter.idl',
|
||||
'nsIUrlClassifierInfo.idl',
|
||||
'nsIUrlClassifierPrefixSet.idl',
|
||||
'nsIUrlClassifierStreamUpdater.idl',
|
||||
'nsIUrlClassifierUtils.idl',
|
||||
@ -30,6 +31,7 @@ UNIFIED_SOURCES += [
|
||||
'LookupCacheV4.cpp',
|
||||
'nsCheckSummedOutputStream.cpp',
|
||||
'nsUrlClassifierDBService.cpp',
|
||||
'nsUrlClassifierInfo.cpp',
|
||||
'nsUrlClassifierProxies.cpp',
|
||||
'nsUrlClassifierUtils.cpp',
|
||||
'protobuf/safebrowsing.pb.cc',
|
||||
|
@ -201,6 +201,11 @@ interface nsIUrlClassifierDBService : nsISupports
|
||||
* for use in tests.
|
||||
*/
|
||||
void reloadDatabase();
|
||||
|
||||
/**
|
||||
* Empty all the caches.
|
||||
*/
|
||||
void clearCache();
|
||||
};
|
||||
|
||||
/**
|
||||
|
73
toolkit/components/url-classifier/nsIUrlClassifierInfo.idl
Normal file
73
toolkit/components/url-classifier/nsIUrlClassifierInfo.idl
Normal file
@ -0,0 +1,73 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIArray.idl"
|
||||
|
||||
/**
|
||||
* nsIUrlClassifierPositiveCacheEntry Represents a positive cache entry.
|
||||
*/
|
||||
[scriptable, uuid(b3c27f8c-7db8-4f3f-97a5-5a94d781e565)]
|
||||
interface nsIUrlClassifierPositiveCacheEntry : nsISupports {
|
||||
/**
|
||||
* Fullhash for the positive cache entry.
|
||||
*/
|
||||
readonly attribute ACString fullhash;
|
||||
|
||||
/**
|
||||
* Positive cache expiry.
|
||||
*/
|
||||
readonly attribute long long expiry;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsIUrlClassifierCacheEntry contains cache information for
|
||||
* a given prefix.
|
||||
*/
|
||||
[scriptable, uuid(d6297907-8236-4126-adaf-c3aa239a0d40)]
|
||||
interface nsIUrlClassifierCacheEntry : nsISupports {
|
||||
/**
|
||||
* Prefix for this cache entry.
|
||||
*/
|
||||
readonly attribute ACString prefix;
|
||||
|
||||
/**
|
||||
* Negative cache expiry.
|
||||
*/
|
||||
readonly attribute long long expiry;
|
||||
|
||||
/**
|
||||
* An array of nsIUrlClassifierPositiveCacheEntry, each item represents
|
||||
* a positive cache entry with its fullhash and expiry.
|
||||
*/
|
||||
readonly attribute nsIArray matches;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cache information for a given table.
|
||||
*/
|
||||
[scriptable, function, uuid(69384f24-d9c5-4462-b24e-351c69e3b46a)]
|
||||
interface nsIUrlClassifierCacheInfo : nsISupports {
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
readonly attribute ACString table;
|
||||
|
||||
/*
|
||||
* An array of nsIUrlClassifierCacheEntry.
|
||||
*/
|
||||
readonly attribute nsIArray entries;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface to query url-classifier information.
|
||||
*/
|
||||
[scriptable, function, uuid(411bbff4-1b88-4687-aa36-e2bbdd93f6e8)]
|
||||
interface nsIUrlClassifierInfo : nsISupports {
|
||||
/**
|
||||
* A synchronous call to return cache information for the table.
|
||||
*/
|
||||
nsIUrlClassifierCacheInfo getCacheInfo(in ACString table);
|
||||
};
|
@ -734,6 +734,18 @@ nsUrlClassifierDBServiceWorker::ReloadDatabase()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierDBServiceWorker::ClearCache()
|
||||
{
|
||||
nsTArray<nsCString> tables;
|
||||
nsresult rv = mClassifier->ActiveTables(tables);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mClassifier->ResetTables(Classifier::Clear_Cache, tables);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierDBServiceWorker::CancelUpdate()
|
||||
{
|
||||
@ -944,6 +956,19 @@ nsUrlClassifierDBServiceWorker::ClearLastResults()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUrlClassifierDBServiceWorker::GetCacheInfo(const nsACString& aTable,
|
||||
nsIUrlClassifierCacheInfo** aCache)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread(), "Must be on the background thread");
|
||||
if (!mClassifier) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
mClassifier->GetCacheInfo(aTable, aCache);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsUrlClassifierDBServiceWorker::IsSameAsLastResults(CacheResultArray& aResult)
|
||||
{
|
||||
@ -1507,6 +1532,7 @@ NS_INTERFACE_MAP_BEGIN(nsUrlClassifierDBService)
|
||||
// Only nsIURIClassifier is supported in the content process!
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUrlClassifierDBService, XRE_IsParentProcess())
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURIClassifier)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIUrlClassifierInfo)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIObserver, XRE_IsParentProcess())
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIClassifier)
|
||||
NS_INTERFACE_MAP_END
|
||||
@ -2198,6 +2224,24 @@ nsUrlClassifierDBService::ReloadDatabase()
|
||||
return mWorkerProxy->ReloadDatabase();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierDBService::ClearCache()
|
||||
{
|
||||
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
return mWorkerProxy->ClearCache();
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierDBService::GetCacheInfo(const nsACString& aTable,
|
||||
nsIUrlClassifierCacheInfo** aCache)
|
||||
{
|
||||
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
return mWorkerProxy->GetCacheInfo(aTable, aCache);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUrlClassifierDBService::CacheCompletions(CacheResultArray *results)
|
||||
{
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsIUrlClassifierHashCompleter.h"
|
||||
#include "nsIUrlListManager.h"
|
||||
#include "nsIUrlClassifierDBService.h"
|
||||
#include "nsIUrlClassifierInfo.h"
|
||||
#include "nsIURIClassifier.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsICryptoHMAC.h"
|
||||
@ -83,6 +84,7 @@ TablesToResponse(const nsACString& tables);
|
||||
// calls to the background thread.
|
||||
class nsUrlClassifierDBService final : public nsIUrlClassifierDBService,
|
||||
public nsIURIClassifier,
|
||||
public nsIUrlClassifierInfo,
|
||||
public nsIObserver
|
||||
{
|
||||
public:
|
||||
@ -98,6 +100,7 @@ public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIURLCLASSIFIERDBSERVICE
|
||||
NS_DECL_NSIURICLASSIFIER
|
||||
NS_DECL_NSIURLCLASSIFIERINFO
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
bool CanComplete(const nsACString &tableName);
|
||||
@ -229,6 +232,10 @@ public:
|
||||
// Should be called on the worker thread.
|
||||
void FlushAndDisableAsyncUpdate();
|
||||
|
||||
// A synchronous call to get cache information for the given table.
|
||||
// This is only used by about:url-classifier now.
|
||||
nsresult GetCacheInfo(const nsACString& aTable,
|
||||
nsIUrlClassifierCacheInfo** aCache);
|
||||
private:
|
||||
// No subclassing
|
||||
~nsUrlClassifierDBServiceWorker();
|
||||
|
105
toolkit/components/url-classifier/nsUrlClassifierInfo.cpp
Normal file
105
toolkit/components/url-classifier/nsUrlClassifierInfo.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsUrlClassifierInfo.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsUrlClassifierPositiveCacheEntry,
|
||||
nsIUrlClassifierPositiveCacheEntry)
|
||||
|
||||
nsUrlClassifierPositiveCacheEntry::nsUrlClassifierPositiveCacheEntry()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierPositiveCacheEntry::GetExpiry(int64_t* aExpiry)
|
||||
{
|
||||
if (!aExpiry) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aExpiry = expirySec;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierPositiveCacheEntry::GetFullhash(nsACString& aFullHash)
|
||||
{
|
||||
aFullHash = fullhash;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsUrlClassifierCacheEntry,
|
||||
nsIUrlClassifierCacheEntry)
|
||||
|
||||
nsUrlClassifierCacheEntry::nsUrlClassifierCacheEntry()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierCacheEntry::GetPrefix(nsACString& aPrefix)
|
||||
{
|
||||
aPrefix = prefix;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierCacheEntry::GetExpiry(int64_t* aExpiry)
|
||||
{
|
||||
if (!aExpiry) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aExpiry = expirySec;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierCacheEntry::GetMatches(nsIArray** aMatches)
|
||||
{
|
||||
if (!aMatches) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID));
|
||||
|
||||
for (uint32_t i = 0;i < matches.Length(); i++) {
|
||||
array->AppendElement(matches[i], false);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aMatches = array);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsUrlClassifierCacheInfo,
|
||||
nsIUrlClassifierCacheInfo)
|
||||
|
||||
nsUrlClassifierCacheInfo::nsUrlClassifierCacheInfo()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierCacheInfo::GetTable(nsACString& aTable)
|
||||
{
|
||||
aTable = table;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierCacheInfo::GetEntries(nsIArray** aEntries)
|
||||
{
|
||||
if (!aEntries) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID));
|
||||
|
||||
for (uint32_t i = 0;i < entries.Length(); i++) {
|
||||
array->AppendElement(entries[i], false);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aEntries = array);
|
||||
|
||||
return NS_OK;
|
||||
}
|
64
toolkit/components/url-classifier/nsUrlClassifierInfo.h
Normal file
64
toolkit/components/url-classifier/nsUrlClassifierInfo.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsUrlClassifierInfo_h_
|
||||
#define nsUrlClassifierInfo_h_
|
||||
|
||||
#include "nsIUrlClassifierInfo.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsUrlClassifierPositiveCacheEntry final : public nsIUrlClassifierPositiveCacheEntry
|
||||
{
|
||||
public:
|
||||
nsUrlClassifierPositiveCacheEntry();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIURLCLASSIFIERPOSITIVECACHEENTRY
|
||||
|
||||
private:
|
||||
~nsUrlClassifierPositiveCacheEntry() {}
|
||||
|
||||
public:
|
||||
nsCString fullhash;
|
||||
|
||||
int64_t expirySec;
|
||||
};
|
||||
|
||||
class nsUrlClassifierCacheEntry final : public nsIUrlClassifierCacheEntry
|
||||
{
|
||||
public:
|
||||
nsUrlClassifierCacheEntry();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIURLCLASSIFIERCACHEENTRY
|
||||
|
||||
private:
|
||||
~nsUrlClassifierCacheEntry() {}
|
||||
|
||||
public:
|
||||
nsCString prefix;
|
||||
|
||||
int64_t expirySec;
|
||||
|
||||
nsTArray<nsCOMPtr<nsIUrlClassifierPositiveCacheEntry>> matches;
|
||||
};
|
||||
|
||||
class nsUrlClassifierCacheInfo final : public nsIUrlClassifierCacheInfo
|
||||
{
|
||||
public:
|
||||
nsUrlClassifierCacheInfo();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIURLCLASSIFIERCACHEINFO
|
||||
|
||||
private:
|
||||
~nsUrlClassifierCacheInfo() {}
|
||||
|
||||
public:
|
||||
nsCString table;
|
||||
|
||||
nsTArray<nsCOMPtr<nsIUrlClassifierCacheEntry>> entries;
|
||||
};
|
||||
|
||||
#endif // nsUrlClassifierInfo_h_
|
@ -179,6 +179,15 @@ UrlClassifierDBServiceWorkerProxy::ReloadDatabase()
|
||||
return DispatchToWorkerThread(r);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierDBServiceWorkerProxy::ClearCache()
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
NewRunnableMethod(mTarget,
|
||||
&nsUrlClassifierDBServiceWorker::ClearCache);
|
||||
return DispatchToWorkerThread(r);
|
||||
}
|
||||
|
||||
nsresult
|
||||
UrlClassifierDBServiceWorkerProxy::OpenDb()
|
||||
{
|
||||
@ -224,6 +233,29 @@ UrlClassifierDBServiceWorkerProxy::ClearLastResultsRunnable::Run()
|
||||
return mTarget->ClearLastResults();
|
||||
}
|
||||
|
||||
nsresult
|
||||
UrlClassifierDBServiceWorkerProxy::GetCacheInfo(const nsACString& aTable,
|
||||
nsIUrlClassifierCacheInfo** aCache)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> r = new GetCacheInfoRunnable(mTarget, aTable, aCache);
|
||||
|
||||
nsIThread* t = nsUrlClassifierDBService::BackgroundThread();
|
||||
if (!t) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// This blocks main thread but since 'GetCacheInfo' is only used by
|
||||
// about:url-classifier so it should be fine.
|
||||
mozilla::SyncRunnable::DispatchToThread(t, r);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierDBServiceWorkerProxy::GetCacheInfoRunnable::Run()
|
||||
{
|
||||
return mTarget->GetCacheInfo(mTable, mCache);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(UrlClassifierLookupCallbackProxy,
|
||||
nsIUrlClassifierLookupCallback)
|
||||
|
||||
|
@ -167,6 +167,24 @@ public:
|
||||
RefPtr<nsUrlClassifierDBServiceWorker> mTarget;
|
||||
};
|
||||
|
||||
class GetCacheInfoRunnable: public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
explicit GetCacheInfoRunnable(nsUrlClassifierDBServiceWorker* aTarget,
|
||||
const nsACString& aTable,
|
||||
nsIUrlClassifierCacheInfo** aCache)
|
||||
: mTarget(aTarget),
|
||||
mTable(aTable),
|
||||
mCache(aCache)
|
||||
{ }
|
||||
|
||||
NS_DECL_NSIRUNNABLE
|
||||
private:
|
||||
RefPtr<nsUrlClassifierDBServiceWorker> mTarget;
|
||||
nsCString mTable;
|
||||
nsIUrlClassifierCacheInfo** mCache;
|
||||
};
|
||||
|
||||
public:
|
||||
nsresult DoLocalLookup(const nsACString& spec,
|
||||
const nsACString& tables,
|
||||
@ -177,6 +195,8 @@ public:
|
||||
|
||||
nsresult CacheCompletions(mozilla::safebrowsing::CacheResultArray * aEntries);
|
||||
|
||||
nsresult GetCacheInfo(const nsACString& aTable,
|
||||
nsIUrlClassifierCacheInfo** aCache);
|
||||
private:
|
||||
~UrlClassifierDBServiceWorkerProxy() {}
|
||||
|
||||
|
@ -18,7 +18,8 @@ SetupCacheEntry(LookupCacheV2* aLookupCache,
|
||||
MissPrefixArray misses;
|
||||
MissPrefixArray emptyMisses;
|
||||
|
||||
nsCOMPtr<nsICryptoHash> cryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID);
|
||||
nsCOMPtr<nsICryptoHash> cryptoHash =
|
||||
do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID);
|
||||
|
||||
AddComplete* add = completes.AppendElement(fallible);
|
||||
add->complete.FromPlaintext(aCompletion, cryptoHash);
|
||||
@ -26,11 +27,13 @@ SetupCacheEntry(LookupCacheV2* aLookupCache,
|
||||
Prefix* prefix = misses.AppendElement(fallible);
|
||||
prefix->FromPlaintext(aCompletion, cryptoHash);
|
||||
|
||||
int64_t negExpirySec = aNegExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC;
|
||||
aLookupCache->AddGethashResultToCache(emptyCompletes, misses, negExpirySec);
|
||||
|
||||
// Setup positive cache first otherwise negative cache expiry will be
|
||||
// overwritten.
|
||||
int64_t posExpirySec = aPosExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC;
|
||||
aLookupCache->AddGethashResultToCache(completes, emptyMisses, posExpirySec);
|
||||
|
||||
int64_t negExpirySec = aNegExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC;
|
||||
aLookupCache->AddGethashResultToCache(emptyCompletes, misses, negExpirySec);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -42,12 +45,14 @@ SetupCacheEntry(LookupCacheV4* aLookupCache,
|
||||
FullHashResponseMap map;
|
||||
|
||||
Prefix prefix;
|
||||
nsCOMPtr<nsICryptoHash> cryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID);
|
||||
nsCOMPtr<nsICryptoHash> cryptoHash =
|
||||
do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID);
|
||||
prefix.FromPlaintext(aCompletion, cryptoHash);
|
||||
|
||||
CachedFullHashResponse* response = map.LookupOrAdd(prefix.ToUint32());
|
||||
|
||||
response->negativeCacheExpirySec = aNegExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC;
|
||||
response->negativeCacheExpirySec =
|
||||
aNegExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC;
|
||||
response->fullHashes.Put(GeneratePrefix(aCompletion, COMPLETE_SIZE),
|
||||
aPosExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC);
|
||||
|
||||
|
@ -58,7 +58,11 @@ td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#debug-table {
|
||||
#cache-table > tbody > tr > td:last-child {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#debug-table, #cache-table {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ function unLoad() {
|
||||
window.removeEventListener("unload", unLoad);
|
||||
|
||||
Provider.uninit();
|
||||
Cache.uninit();
|
||||
Debug.uninit();
|
||||
}
|
||||
|
||||
@ -29,6 +30,7 @@ function onLoad() {
|
||||
window.addEventListener("unload", unLoad);
|
||||
|
||||
Provider.init();
|
||||
Cache.init();
|
||||
Debug.init();
|
||||
}
|
||||
|
||||
@ -179,6 +181,145 @@ var Provider = {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Cache
|
||||
*/
|
||||
var Cache = {
|
||||
// Tables that show cahe entries.
|
||||
showCacheEnties: null,
|
||||
|
||||
init() {
|
||||
this.showCacheEnties = new Set();
|
||||
|
||||
this.register()
|
||||
this.render();
|
||||
},
|
||||
|
||||
uninit() {
|
||||
Services.obs.removeObserver(this.refresh, UPDATE_FINISH);
|
||||
},
|
||||
|
||||
register() {
|
||||
this.refresh = this.refresh.bind(this);
|
||||
Services.obs.addObserver(this.refresh, UPDATE_FINISH);
|
||||
},
|
||||
|
||||
render() {
|
||||
this.createCacheEntries();
|
||||
|
||||
let refreshBtn = document.getElementById("refresh-cache-btn");
|
||||
refreshBtn.addEventListener("click", () => { this.refresh(); });
|
||||
|
||||
let clearBtn = document.getElementById("clear-cache-btn");
|
||||
clearBtn.addEventListener("click", () => {
|
||||
let dbservice = Cc["@mozilla.org/url-classifier/dbservice;1"]
|
||||
.getService(Ci.nsIUrlClassifierDBService);
|
||||
dbservice.clearCache();
|
||||
// Since clearCache is async call, we just simply assume it will be
|
||||
// updated in 100 milli-seconds.
|
||||
setTimeout(() => { this.refresh(); }, 100);
|
||||
});
|
||||
},
|
||||
|
||||
refresh() {
|
||||
this.clearCacheEntries();
|
||||
this.createCacheEntries();
|
||||
},
|
||||
|
||||
clearCacheEntries() {
|
||||
let ctbody = document.getElementById("cache-table-body");
|
||||
while (ctbody.firstChild) {
|
||||
ctbody.firstChild.remove();
|
||||
}
|
||||
|
||||
let cetbody = document.getElementById("cache-entries-table-body");
|
||||
while (cetbody.firstChild) {
|
||||
cetbody.firstChild.remove();
|
||||
}
|
||||
},
|
||||
|
||||
createCacheEntries() {
|
||||
function createRow(tds, body, cols) {
|
||||
let tr = document.createElement("tr");
|
||||
tds.forEach(function(v, i, a) {
|
||||
let td = document.createElement("td");
|
||||
if (i == 0 && tds.length != cols) {
|
||||
td.setAttribute("colspan", cols - tds.length + 1);
|
||||
}
|
||||
let elem = typeof v === "object" ? v : document.createTextNode(v);
|
||||
td.appendChild(elem);
|
||||
tr.appendChild(td);
|
||||
})
|
||||
body.appendChild(tr);
|
||||
}
|
||||
|
||||
let dbservice = Cc["@mozilla.org/url-classifier/dbservice;1"]
|
||||
.getService(Ci.nsIUrlClassifierInfo);
|
||||
|
||||
for (let provider of Provider.providers) {
|
||||
let pref = "browser.safebrowsing.provider." + provider + ".lists";
|
||||
let tables = Services.prefs.getCharPref(pref, "").split(",");
|
||||
|
||||
for (let table of tables) {
|
||||
let cache = dbservice.getCacheInfo(table);
|
||||
let entries = cache.entries;
|
||||
if (entries.length === 0) {
|
||||
this.showCacheEnties.delete(table);
|
||||
continue;
|
||||
}
|
||||
|
||||
let positiveCacheCount = 0;
|
||||
for (let i = 0; i < entries.length ; i++) {
|
||||
let entry = entries.queryElementAt(i, Ci.nsIUrlClassifierCacheEntry);
|
||||
let matches = entry.matches;
|
||||
positiveCacheCount += matches.length;
|
||||
|
||||
// If we don't have to show cache entries for this table then just
|
||||
// skip the following code.
|
||||
if (!this.showCacheEnties.has(table)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let tds = [table, entry.prefix, new Date(entry.expiry * 1000).toString()];
|
||||
let j = 0;
|
||||
do {
|
||||
if (matches.length >= 1) {
|
||||
let match =
|
||||
matches.queryElementAt(j, Ci.nsIUrlClassifierPositiveCacheEntry);
|
||||
let list = [match.fullhash, new Date(match.expiry * 1000).toString()];
|
||||
tds = tds.concat(list);
|
||||
} else {
|
||||
tds = tds.concat([STR_NA, STR_NA])
|
||||
}
|
||||
createRow(tds, document.getElementById("cache-entries-table-body"), 5);
|
||||
j++;
|
||||
tds = [""];
|
||||
} while (j < matches.length)
|
||||
}
|
||||
|
||||
// Create cache information entries.
|
||||
let chk = document.createElement("input");
|
||||
chk.type = "checkbox";
|
||||
chk.checked = this.showCacheEnties.has(table);
|
||||
chk.addEventListener("click", () => {
|
||||
if (chk.checked) {
|
||||
this.showCacheEnties.add(table);
|
||||
} else {
|
||||
this.showCacheEnties.delete(table);
|
||||
}
|
||||
this.refresh();
|
||||
});
|
||||
|
||||
let tds = [table, entries.length, positiveCacheCount, chk];
|
||||
createRow(tds, document.getElementById("cache-table-body"), tds.length);
|
||||
}
|
||||
}
|
||||
|
||||
let entries_div = document.getElementById("cache-entries");
|
||||
entries_div.style.display = this.showCacheEnties.size == 0 ? "none" : "block";
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Debug
|
||||
*/
|
||||
|
@ -37,6 +37,45 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="cache">
|
||||
<h2 class="major-section">&aboutUrlClassifier.cacheTitle;</h2>
|
||||
<div id="cache-modules" class="options">
|
||||
<button id="refresh-cache-btn">&aboutUrlClassifier.cacheRefreshBtn;</button>
|
||||
<button id="clear-cache-btn">&aboutUrlClassifier.cacheClearBtn;</button>
|
||||
<br></br>
|
||||
</div>
|
||||
<table id="cache-table">
|
||||
<thead>
|
||||
<tr id="cache-head-row">
|
||||
<th id="col-tablename">&aboutUrlClassifier.cacheTableName;</th>
|
||||
<th id="col-negativeentries">&aboutUrlClassifier.cacheNCacheEntries;</th>
|
||||
<th id="col-positiveentries">&aboutUrlClassifier.cachePCacheEntries;</th>
|
||||
<th id="col-showentries">&aboutUrlClassifier.cacheShowEntries;</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="cache-table-body">
|
||||
<!-- data is generated in javascript -->
|
||||
</tbody>
|
||||
</table>
|
||||
<br></br>
|
||||
</div>
|
||||
<div id="cache-entries">
|
||||
<h2 class="major-section">&aboutUrlClassifier.cacheEntries;</h2>
|
||||
<table id="cache-entries-table">
|
||||
<thead>
|
||||
<tr id="cache-entries-row">
|
||||
<th id="col-table">&aboutUrlClassifier.cacheTableName;</th>
|
||||
<th id="col-prefix">&aboutUrlClassifier.cachePrefix;</th>
|
||||
<th id="col-n-expire">&aboutUrlClassifier.cacheNCacheExpiry;</th>
|
||||
<th id="col-fullhash">&aboutUrlClassifier.cacheFullhash;</th>
|
||||
<th id="col-p-expire">&aboutUrlClassifier.cachePCacheExpiry;</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="cache-entries-table-body">
|
||||
<!-- data is generated in javascript -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="debug">
|
||||
<h2 class="major-section">&aboutUrlClassifier.debugTitle;</h2>
|
||||
<div id="debug-modules" class="options">
|
||||
|
@ -10,6 +10,18 @@
|
||||
<!ENTITY aboutUrlClassifier.providerNextUpdateTime "Next update time">
|
||||
<!ENTITY aboutUrlClassifier.providerLastUpdateStatus "Last update status">
|
||||
<!ENTITY aboutUrlClassifier.providerUpdateBtn "Update">
|
||||
<!ENTITY aboutUrlClassifier.cacheTitle "Cache">
|
||||
<!ENTITY aboutUrlClassifier.cacheRefreshBtn "Refresh">
|
||||
<!ENTITY aboutUrlClassifier.cacheClearBtn "Clear">
|
||||
<!ENTITY aboutUrlClassifier.cacheTableName "Table name">
|
||||
<!ENTITY aboutUrlClassifier.cacheNCacheEntries "Number of negative cache entries">
|
||||
<!ENTITY aboutUrlClassifier.cachePCacheEntries "Number of positive cache entries">
|
||||
<!ENTITY aboutUrlClassifier.cacheShowEntries "Show entries">
|
||||
<!ENTITY aboutUrlClassifier.cacheEntries "Cache Entries">
|
||||
<!ENTITY aboutUrlClassifier.cachePrefix "Prefix">
|
||||
<!ENTITY aboutUrlClassifier.cacheNCacheExpiry "Negative cache expiry">
|
||||
<!ENTITY aboutUrlClassifier.cacheFullhash "Full hash">
|
||||
<!ENTITY aboutUrlClassifier.cachePCacheExpiry "Positive cache expiry">
|
||||
<!ENTITY aboutUrlClassifier.lookupTitle "Lookup">
|
||||
<!ENTITY aboutUrlClassifier.lookupUrl "Url">
|
||||
<!ENTITY aboutUrlClassifier.lookupMatch "Match">
|
||||
|
Loading…
x
Reference in New Issue
Block a user