Use SimpleUrlPatternMatcher for dictionary matching
The spec of Compression Dictionary Transport has been changed by [1] to use URLPattern [2] for the matching algorithm of dictionaries. Also [3] changed the Use-As-Dictionary header’s "match" value to be parsed as a constructor string of URLPattern. This CL changes the behavior of Chromium to follow those spec changes when V2 backend is enabled. [1]: https://github.com/httpwg/http-extensions/pull/2646 [2]: https://urlpattern.spec.whatwg.org/ [3]: https://github.com/httpwg/http-extensions/pull/2689 Fuchsia-Binary-Size: Size increase is unavoidable. Bug: 1413922 Change-Id: I6ffba1c8c016145822643a18bc4f18bb7f0ac35f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5232339 Reviewed-by: Patrick Meenan <pmeenan@chromium.org> Commit-Queue: Tsuyoshi Horo <horo@chromium.org> Cr-Commit-Position: refs/heads/main@{#1256029}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
a6665cf098
commit
cdb7dfa61e
docs/experiments
services/network/shared_dictionary
@ -201,7 +201,7 @@ construction to catch up the following spec changes:
|
||||
- Change Content-Encoding name "br-d" "zstd-d"
|
||||
- Stauts: Implemented by https://crrev.com/c/5185977.
|
||||
- Changed match to use URLPattern
|
||||
- Stauts: Not yet implemented.
|
||||
- Stauts: Implemented by https://crrev.com/c/5232339.
|
||||
- Added support for a server-provided dictionary id
|
||||
- Stauts: Not yet implemented.
|
||||
- Stop using "expires" value of "Use-As-Dictionary" header, and use the cache
|
||||
|
@ -160,18 +160,6 @@ void WriteDiskCacheEntry(SharedDictionaryManager* manager,
|
||||
write_callback.callback(), /*truncate=*/false)));
|
||||
}
|
||||
|
||||
base::UnguessableToken GetDiskCacheKeyTokenOfFirstDictionary(
|
||||
const std::map<url::SchemeHostPort,
|
||||
std::map<std::string, net::SharedDictionaryInfo>>&
|
||||
dictionary_map,
|
||||
const std::string& scheme_host_port_str) {
|
||||
auto it =
|
||||
dictionary_map.find(url::SchemeHostPort(GURL(scheme_host_port_str)));
|
||||
CHECK(it != dictionary_map.end()) << scheme_host_port_str;
|
||||
CHECK(!it->second.empty());
|
||||
return it->second.begin()->second.disk_cache_key_token();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class SharedDictionaryManagerOnDiskTest
|
||||
@ -207,6 +195,21 @@ class SharedDictionaryManagerOnDiskTest
|
||||
features::CompressionDictionaryTransportBackendVersion GetVersion() const {
|
||||
return GetParam();
|
||||
}
|
||||
|
||||
static base::UnguessableToken GetDiskCacheKeyTokenOfFirstDictionary(
|
||||
const std::map<
|
||||
url::SchemeHostPort,
|
||||
std::map<std::string,
|
||||
SharedDictionaryStorageOnDisk::DictionaryInfoWithMatcher>>&
|
||||
dictionary_map,
|
||||
const std::string& scheme_host_port_str) {
|
||||
auto it =
|
||||
dictionary_map.find(url::SchemeHostPort(GURL(scheme_host_port_str)));
|
||||
CHECK(it != dictionary_map.end()) << scheme_host_port_str;
|
||||
CHECK(!it->second.empty());
|
||||
return it->second.begin()->second.disk_cache_key_token();
|
||||
}
|
||||
|
||||
std::unique_ptr<SharedDictionaryManager> CreateSharedDictionaryManager(
|
||||
uint64_t cache_max_size = 0,
|
||||
uint64_t cache_max_count =
|
||||
@ -218,8 +221,10 @@ class SharedDictionaryManagerOnDiskTest
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
/*file_operations_factory=*/nullptr);
|
||||
}
|
||||
const std::map<url::SchemeHostPort,
|
||||
std::map<std::string, net::SharedDictionaryInfo>>&
|
||||
const std::map<
|
||||
url::SchemeHostPort,
|
||||
std::map<std::string,
|
||||
SharedDictionaryStorageOnDisk::DictionaryInfoWithMatcher>>&
|
||||
GetOnDiskDictionaryMap(SharedDictionaryStorage* storage) {
|
||||
return static_cast<SharedDictionaryStorageOnDisk*>(storage)
|
||||
->GetDictionaryMapForTesting();
|
||||
|
@ -229,8 +229,10 @@ class SharedDictionaryManagerTest
|
||||
return static_cast<SharedDictionaryStorageInMemory*>(storage)
|
||||
->GetDictionaryMap();
|
||||
}
|
||||
const std::map<url::SchemeHostPort,
|
||||
std::map<std::string, net::SharedDictionaryInfo>>&
|
||||
const std::map<
|
||||
url::SchemeHostPort,
|
||||
std::map<std::string,
|
||||
SharedDictionaryStorageOnDisk::DictionaryInfoWithMatcher>>&
|
||||
GetOnDiskDictionaryMap(SharedDictionaryStorage* storage) {
|
||||
return static_cast<SharedDictionaryStorageOnDisk*>(storage)
|
||||
->GetDictionaryMapForTesting();
|
||||
@ -716,6 +718,52 @@ TEST_P(SharedDictionaryManagerTest, DictionaryLifetimeFromCacheControlHeader) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(SharedDictionaryManagerTest, InvalidMatch) {
|
||||
std::unique_ptr<SharedDictionaryManager> manager =
|
||||
CreateSharedDictionaryManager();
|
||||
net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl1),
|
||||
kSite1);
|
||||
scoped_refptr<SharedDictionaryStorage> storage =
|
||||
manager->GetStorage(isolation_key);
|
||||
ASSERT_TRUE(storage);
|
||||
struct {
|
||||
std::string header_string;
|
||||
bool expect_success_v1;
|
||||
bool expect_success_v2;
|
||||
} kTestCases[] = {
|
||||
// Invalid as a constructor string of URLPattern.
|
||||
{"{", true, false},
|
||||
// Unsupported regexp group.
|
||||
{"(a|b)", true, false},
|
||||
};
|
||||
for (const auto& testcase : kTestCases) {
|
||||
SCOPED_TRACE(
|
||||
base::StringPrintf("match: %s", testcase.header_string.c_str()));
|
||||
scoped_refptr<net::HttpResponseHeaders> headers =
|
||||
net::HttpResponseHeaders::TryToCreate(base::StrCat(
|
||||
{"HTTP/1.1 200 OK\n", shared_dictionary::kUseAsDictionaryHeaderName,
|
||||
": match=\"", testcase.header_string, "\"\n",
|
||||
"cache-control:max-age=100\n\n"}));
|
||||
ASSERT_TRUE(headers);
|
||||
scoped_refptr<SharedDictionaryWriter> writer = storage->MaybeCreateWriter(
|
||||
GURL("https://origin1.test/testfile.txt"),
|
||||
/*request_time=*/base::Time::Now(), /*response_time=*/base::Time::Now(),
|
||||
*headers,
|
||||
/*was_fetched_via_cache=*/false,
|
||||
/*access_allowed_check_callback=*/base::BindOnce([]() {
|
||||
return true;
|
||||
}));
|
||||
switch (GetVersion()) {
|
||||
case features::CompressionDictionaryTransportBackendVersion::kV1:
|
||||
EXPECT_EQ(testcase.expect_success_v1, !!writer);
|
||||
break;
|
||||
case features::CompressionDictionaryTransportBackendVersion::kV2:
|
||||
EXPECT_EQ(testcase.expect_success_v2, !!writer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(SharedDictionaryManagerTest, AccessAllowedCheckReturnTrue) {
|
||||
std::unique_ptr<SharedDictionaryManager> manager =
|
||||
CreateSharedDictionaryManager();
|
||||
@ -987,6 +1035,54 @@ TEST_P(SharedDictionaryManagerTest, WriteAndReadDictionary) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(SharedDictionaryManagerTest, LongestMatchDictionaryWin) {
|
||||
std::unique_ptr<SharedDictionaryManager> manager =
|
||||
CreateSharedDictionaryManager();
|
||||
net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl1),
|
||||
kSite1);
|
||||
scoped_refptr<SharedDictionaryStorage> storage =
|
||||
manager->GetStorage(isolation_key);
|
||||
ASSERT_TRUE(storage);
|
||||
WriteDictionary(storage.get(), GURL("https://origin1.test/dict"), "*estfile*",
|
||||
{"Longer match"});
|
||||
WriteDictionary(storage.get(), GURL("https://origin1.test/dict"), "test*",
|
||||
{"Shorter match"});
|
||||
if (GetManagerType() == TestManagerType::kOnDisk) {
|
||||
FlushCacheTasks();
|
||||
}
|
||||
auto dict = storage->GetDictionarySync(GURL("https://origin1.test/testfile"));
|
||||
ASSERT_TRUE(dict);
|
||||
net::TestCompletionCallback read_callback;
|
||||
EXPECT_EQ(net::OK,
|
||||
read_callback.GetResult(dict->ReadAll(read_callback.callback())));
|
||||
EXPECT_EQ("Longer match", std::string(dict->data()->data(), dict->size()));
|
||||
}
|
||||
|
||||
TEST_P(SharedDictionaryManagerTest, LatestDictionaryWin) {
|
||||
std::unique_ptr<SharedDictionaryManager> manager =
|
||||
CreateSharedDictionaryManager();
|
||||
net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl1),
|
||||
kSite1);
|
||||
scoped_refptr<SharedDictionaryStorage> storage =
|
||||
manager->GetStorage(isolation_key);
|
||||
ASSERT_TRUE(storage);
|
||||
WriteDictionary(storage.get(), GURL("https://origin1.test/dict"), "test*",
|
||||
{"Old match"});
|
||||
task_environment_.FastForwardBy(base::Seconds(1));
|
||||
WriteDictionary(storage.get(), GURL("https://origin1.test/dict"), "*est*",
|
||||
{"New match"});
|
||||
if (GetManagerType() == TestManagerType::kOnDisk) {
|
||||
FlushCacheTasks();
|
||||
}
|
||||
auto dict = storage->GetDictionarySync(GURL("https://origin1.test/testfile"));
|
||||
ASSERT_TRUE(dict);
|
||||
net::TestCompletionCallback read_callback;
|
||||
EXPECT_EQ(net::OK,
|
||||
read_callback.GetResult(dict->ReadAll(read_callback.callback())));
|
||||
EXPECT_EQ("New match", std::string(dict->data()->data(), dict->size()));
|
||||
}
|
||||
|
||||
TEST_P(SharedDictionaryManagerTest, OverrideDictionary) {
|
||||
std::unique_ptr<SharedDictionaryManager> manager =
|
||||
CreateSharedDictionaryManager();
|
||||
|
@ -120,6 +120,12 @@ std::optional<DictionaryHeaderInfo> ParseDictionaryHeaderInfo(
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
bool SharedDictionaryStorage::NeedToUseUrlPatternMatcher() {
|
||||
return features::kCompressionDictionaryTransportBackendVersion.Get() !=
|
||||
features::CompressionDictionaryTransportBackendVersion::kV1;
|
||||
}
|
||||
|
||||
SharedDictionaryStorage::SharedDictionaryStorage() = default;
|
||||
|
||||
SharedDictionaryStorage::~SharedDictionaryStorage() = default;
|
||||
|
@ -63,6 +63,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) SharedDictionaryStorage
|
||||
protected:
|
||||
friend class base::RefCounted<SharedDictionaryStorage>;
|
||||
|
||||
// Returns true when V2 backend is used.
|
||||
// TODO(crbug.com/1413922): Remove this when we remove V1 backend support.
|
||||
static bool NeedToUseUrlPatternMatcher();
|
||||
|
||||
SharedDictionaryStorage();
|
||||
virtual ~SharedDictionaryStorage();
|
||||
|
||||
@ -93,23 +97,29 @@ DictionaryInfoType* GetMatchingDictionaryFromDictionaryInfoMap(
|
||||
if (it == dictionary_info_map.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
DictionaryInfoType* info = nullptr;
|
||||
size_t mached_path_size = 0;
|
||||
// TODO(crbug.com/1413922): If there are multiple matching dictionaries, this
|
||||
// method currently returns the dictionary with the longest path pattern. But
|
||||
// we should have a detailed description about `best-matching` in the spec.
|
||||
DictionaryInfoType* matched_info = nullptr;
|
||||
for (auto& item : it->second) {
|
||||
// TODO(crbug.com/1413922): base::MatchPattern() is treating '?' in the
|
||||
// pattern as an wildcard. We need to introduce a new flag in
|
||||
// base::MatchPattern() to treat '?' as a normal character.
|
||||
// TODO(crbug.com/1413922): Need support path expansion for relative paths.
|
||||
if ((item.first.size() > mached_path_size) &&
|
||||
base::MatchPattern(url.path(), item.first)) {
|
||||
mached_path_size = item.first.size();
|
||||
info = &item.second;
|
||||
DictionaryInfoType& info = item.second;
|
||||
CHECK_EQ(info.match(), item.first);
|
||||
if (matched_info &&
|
||||
((matched_info->match().size() > info.match().size()) ||
|
||||
(matched_info->match().size() == info.match().size() &&
|
||||
matched_info->response_time() > info.response_time()))) {
|
||||
continue;
|
||||
}
|
||||
if (!info.matcher()) {
|
||||
// This is for V1 backend.
|
||||
// TODO(crbug.com/1413922): Remove this after V1 backend is removed.
|
||||
if (base::MatchPattern(url.path(), info.match())) {
|
||||
matched_info = &info;
|
||||
}
|
||||
} else {
|
||||
if (info.matcher()->Match(url)) {
|
||||
matched_info = &info;
|
||||
}
|
||||
}
|
||||
}
|
||||
return info;
|
||||
return matched_info;
|
||||
}
|
||||
|
||||
// Returns true if the same dictionary is already registered in
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "services/network/shared_dictionary/shared_dictionary_in_memory.h"
|
||||
#include "services/network/shared_dictionary/shared_dictionary_manager_in_memory.h"
|
||||
#include "services/network/shared_dictionary/shared_dictionary_writer_in_memory.h"
|
||||
#include "services/network/shared_dictionary/simple_url_pattern_matcher.h"
|
||||
#include "url/scheme_host_port.h"
|
||||
|
||||
namespace network {
|
||||
@ -105,9 +106,18 @@ SharedDictionaryStorageInMemory::CreateWriter(const GURL& url,
|
||||
base::Time response_time,
|
||||
base::TimeDelta expiration,
|
||||
const std::string& match) {
|
||||
return base::MakeRefCounted<SharedDictionaryWriterInMemory>(base::BindOnce(
|
||||
&SharedDictionaryStorageInMemory::OnDictionaryWritten,
|
||||
weak_factory_.GetWeakPtr(), url, response_time, expiration, match));
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher;
|
||||
if (NeedToUseUrlPatternMatcher()) {
|
||||
auto matcher_create_result = SimpleUrlPatternMatcher::Create(match, url);
|
||||
if (!matcher_create_result.has_value()) {
|
||||
return nullptr;
|
||||
}
|
||||
matcher = std::move(matcher_create_result.value());
|
||||
}
|
||||
return base::MakeRefCounted<SharedDictionaryWriterInMemory>(
|
||||
base::BindOnce(&SharedDictionaryStorageInMemory::OnDictionaryWritten,
|
||||
weak_factory_.GetWeakPtr(), url, response_time, expiration,
|
||||
match, std::move(matcher)));
|
||||
}
|
||||
|
||||
bool SharedDictionaryStorageInMemory::IsAlreadyRegistered(
|
||||
@ -124,6 +134,7 @@ void SharedDictionaryStorageInMemory::OnDictionaryWritten(
|
||||
base::Time response_time,
|
||||
base::TimeDelta expiration,
|
||||
const std::string& match,
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher,
|
||||
SharedDictionaryWriterInMemory::Result result,
|
||||
scoped_refptr<net::IOBuffer> data,
|
||||
size_t size,
|
||||
@ -132,9 +143,9 @@ void SharedDictionaryStorageInMemory::OnDictionaryWritten(
|
||||
return;
|
||||
}
|
||||
dictionary_info_map_[url::SchemeHostPort(url)].insert_or_assign(
|
||||
match,
|
||||
DictionaryInfo(url, response_time, expiration, match,
|
||||
/*last_used_time=*/base::Time::Now(), data, size, hash));
|
||||
match, DictionaryInfo(url, response_time, expiration, match,
|
||||
/*last_used_time=*/base::Time::Now(), data, size,
|
||||
hash, std::move(matcher)));
|
||||
if (manager_) {
|
||||
manager_->MaybeRunCacheEvictionPerSite(isolation_key_.top_frame_site());
|
||||
manager_->MaybeRunCacheEviction();
|
||||
@ -149,7 +160,8 @@ SharedDictionaryStorageInMemory::DictionaryInfo::DictionaryInfo(
|
||||
base::Time last_used_time,
|
||||
scoped_refptr<net::IOBuffer> data,
|
||||
size_t size,
|
||||
const net::SHA256HashValue& hash)
|
||||
const net::SHA256HashValue& hash,
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher)
|
||||
: url_(url),
|
||||
response_time_(response_time),
|
||||
expiration_(expiration),
|
||||
@ -157,7 +169,8 @@ SharedDictionaryStorageInMemory::DictionaryInfo::DictionaryInfo(
|
||||
last_used_time_(last_used_time),
|
||||
data_(std::move(data)),
|
||||
size_(size),
|
||||
hash_(hash) {}
|
||||
hash_(hash),
|
||||
matcher_(std::move(matcher)) {}
|
||||
|
||||
SharedDictionaryStorageInMemory::DictionaryInfo::DictionaryInfo(
|
||||
DictionaryInfo&& other) = default;
|
||||
|
@ -30,6 +30,7 @@ class CorsURLLoaderSharedDictionaryTest;
|
||||
} // namespace cors
|
||||
|
||||
class SharedDictionaryManagerInMemory;
|
||||
class SimpleUrlPatternMatcher;
|
||||
|
||||
// A SharedDictionaryStorage which is managed by
|
||||
// SharedDictionaryManagerInMemory.
|
||||
@ -45,7 +46,8 @@ class SharedDictionaryStorageInMemory : public SharedDictionaryStorage {
|
||||
base::Time last_used_time,
|
||||
scoped_refptr<net::IOBuffer> data,
|
||||
size_t size,
|
||||
const net::SHA256HashValue& hash);
|
||||
const net::SHA256HashValue& hash,
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher);
|
||||
|
||||
DictionaryInfo(const DictionaryInfo&) = delete;
|
||||
DictionaryInfo& operator=(const DictionaryInfo&) = delete;
|
||||
@ -63,6 +65,7 @@ class SharedDictionaryStorageInMemory : public SharedDictionaryStorage {
|
||||
const scoped_refptr<net::IOBuffer>& data() const { return data_; }
|
||||
size_t size() const { return size_; }
|
||||
const net::SHA256HashValue& hash() const { return hash_; }
|
||||
const SimpleUrlPatternMatcher* matcher() const { return matcher_.get(); }
|
||||
|
||||
void set_last_used_time(base::Time last_used_time) {
|
||||
last_used_time_ = last_used_time;
|
||||
@ -77,6 +80,7 @@ class SharedDictionaryStorageInMemory : public SharedDictionaryStorage {
|
||||
scoped_refptr<net::IOBuffer> data_;
|
||||
size_t size_;
|
||||
net::SHA256HashValue hash_;
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher_;
|
||||
};
|
||||
|
||||
SharedDictionaryStorageInMemory(
|
||||
@ -127,6 +131,7 @@ class SharedDictionaryStorageInMemory : public SharedDictionaryStorage {
|
||||
base::Time response_time,
|
||||
base::TimeDelta expiration,
|
||||
const std::string& match,
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher,
|
||||
SharedDictionaryWriterInMemory::Result result,
|
||||
scoped_refptr<net::IOBuffer> data,
|
||||
size_t size,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "services/network/shared_dictionary/shared_dictionary_manager_on_disk.h"
|
||||
#include "services/network/shared_dictionary/shared_dictionary_on_disk.h"
|
||||
#include "services/network/shared_dictionary/shared_dictionary_writer_on_disk.h"
|
||||
#include "services/network/shared_dictionary/simple_url_pattern_matcher.h"
|
||||
#include "url/scheme_host_port.h"
|
||||
|
||||
namespace network {
|
||||
@ -104,6 +105,19 @@ class SharedDictionaryStorageOnDisk::WrappedSharedDictionary
|
||||
scoped_refptr<RefCountedSharedDictionary> ref_counted_shared_dictionary_;
|
||||
};
|
||||
|
||||
SharedDictionaryStorageOnDisk::DictionaryInfoWithMatcher::
|
||||
DictionaryInfoWithMatcher(net::SharedDictionaryInfo info,
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher)
|
||||
: net::SharedDictionaryInfo(std::move(info)),
|
||||
matcher_(std::move(matcher)) {}
|
||||
SharedDictionaryStorageOnDisk::DictionaryInfoWithMatcher::
|
||||
~DictionaryInfoWithMatcher() = default;
|
||||
SharedDictionaryStorageOnDisk::DictionaryInfoWithMatcher::
|
||||
DictionaryInfoWithMatcher(DictionaryInfoWithMatcher&&) = default;
|
||||
SharedDictionaryStorageOnDisk::DictionaryInfoWithMatcher&
|
||||
SharedDictionaryStorageOnDisk::DictionaryInfoWithMatcher::operator=(
|
||||
DictionaryInfoWithMatcher&&) = default;
|
||||
|
||||
SharedDictionaryStorageOnDisk::SharedDictionaryStorageOnDisk(
|
||||
base::WeakPtr<SharedDictionaryManagerOnDisk> manager,
|
||||
const net::SharedDictionaryIsolationKey& isolation_key,
|
||||
@ -197,10 +211,19 @@ SharedDictionaryStorageOnDisk::CreateWriter(const GURL& url,
|
||||
if (!manager_) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher;
|
||||
if (NeedToUseUrlPatternMatcher()) {
|
||||
auto matcher_create_result = SimpleUrlPatternMatcher::Create(match, url);
|
||||
if (!matcher_create_result.has_value()) {
|
||||
return nullptr;
|
||||
}
|
||||
matcher = std::move(matcher_create_result.value());
|
||||
}
|
||||
return manager_->CreateWriter(
|
||||
isolation_key_, url, response_time, expiration, match,
|
||||
base::BindOnce(&SharedDictionaryStorageOnDisk::OnDictionaryWritten,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
weak_factory_.GetWeakPtr(), std::move(matcher)));
|
||||
}
|
||||
|
||||
bool SharedDictionaryStorageOnDisk::IsAlreadyRegistered(
|
||||
@ -220,13 +243,24 @@ void SharedDictionaryStorageOnDisk::OnDatabaseRead(
|
||||
if (!result.has_value()) {
|
||||
return;
|
||||
}
|
||||
std::set<base::UnguessableToken> deleted_cache_tokens;
|
||||
|
||||
const bool need_matcher = NeedToUseUrlPatternMatcher();
|
||||
for (auto& info : result.value()) {
|
||||
const url::SchemeHostPort scheme_host_port =
|
||||
url::SchemeHostPort(info.url());
|
||||
const std::string match = info.match();
|
||||
(dictionary_info_map_[scheme_host_port])
|
||||
.insert(std::make_pair(match, std::move(info)));
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher;
|
||||
if (need_matcher) {
|
||||
auto matcher_create_result =
|
||||
SimpleUrlPatternMatcher::Create(match, info.url());
|
||||
if (!matcher_create_result.has_value()) {
|
||||
continue;
|
||||
}
|
||||
matcher = std::move(matcher_create_result.value());
|
||||
}
|
||||
|
||||
dictionary_info_map_[scheme_host_port].insert(std::make_pair(
|
||||
match, DictionaryInfoWithMatcher(std::move(info), std::move(matcher))));
|
||||
}
|
||||
|
||||
auto callbacks = std::move(pending_get_dictionary_tasks_);
|
||||
@ -236,11 +270,13 @@ void SharedDictionaryStorageOnDisk::OnDatabaseRead(
|
||||
}
|
||||
|
||||
void SharedDictionaryStorageOnDisk::OnDictionaryWritten(
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher,
|
||||
net::SharedDictionaryInfo info) {
|
||||
const url::SchemeHostPort scheme_host_port = url::SchemeHostPort(info.url());
|
||||
const std::string match = info.match();
|
||||
(dictionary_info_map_[scheme_host_port])
|
||||
.insert_or_assign(match, std::move(info));
|
||||
.insert_or_assign(match, DictionaryInfoWithMatcher(std::move(info),
|
||||
std::move(matcher)));
|
||||
}
|
||||
|
||||
void SharedDictionaryStorageOnDisk::OnRefCountedSharedDictionaryDeleted(
|
||||
|
@ -28,6 +28,7 @@
|
||||
namespace network {
|
||||
|
||||
class SharedDictionaryManagerOnDisk;
|
||||
class SimpleUrlPatternMatcher;
|
||||
|
||||
// A SharedDictionaryStorage which is managed by SharedDictionaryManagerOnDisk.
|
||||
class SharedDictionaryStorageOnDisk : public SharedDictionaryStorage {
|
||||
@ -71,14 +72,32 @@ class SharedDictionaryStorageOnDisk : public SharedDictionaryStorage {
|
||||
class RefCountedSharedDictionary;
|
||||
class WrappedSharedDictionary;
|
||||
|
||||
class DictionaryInfoWithMatcher : public net::SharedDictionaryInfo {
|
||||
public:
|
||||
DictionaryInfoWithMatcher(net::SharedDictionaryInfo info,
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher);
|
||||
~DictionaryInfoWithMatcher();
|
||||
DictionaryInfoWithMatcher(const DictionaryInfoWithMatcher&) = delete;
|
||||
DictionaryInfoWithMatcher& operator=(const DictionaryInfoWithMatcher&) =
|
||||
delete;
|
||||
DictionaryInfoWithMatcher(DictionaryInfoWithMatcher&&);
|
||||
DictionaryInfoWithMatcher& operator=(DictionaryInfoWithMatcher&&);
|
||||
|
||||
const SimpleUrlPatternMatcher* matcher() const { return matcher_.get(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<SimpleUrlPatternMatcher> matcher_;
|
||||
};
|
||||
|
||||
void OnDatabaseRead(
|
||||
net::SQLitePersistentSharedDictionaryStore::DictionaryListOrError result);
|
||||
void OnDictionaryWritten(net::SharedDictionaryInfo info);
|
||||
void OnDictionaryWritten(std::unique_ptr<SimpleUrlPatternMatcher> matcher,
|
||||
net::SharedDictionaryInfo info);
|
||||
void OnRefCountedSharedDictionaryDeleted(
|
||||
const base::UnguessableToken& disk_cache_key_token);
|
||||
|
||||
const std::map<url::SchemeHostPort,
|
||||
std::map<std::string, net::SharedDictionaryInfo>>&
|
||||
std::map<std::string, DictionaryInfoWithMatcher>>&
|
||||
GetDictionaryMapForTesting() {
|
||||
return dictionary_info_map_;
|
||||
}
|
||||
@ -87,7 +106,7 @@ class SharedDictionaryStorageOnDisk : public SharedDictionaryStorage {
|
||||
const net::SharedDictionaryIsolationKey isolation_key_;
|
||||
base::ScopedClosureRunner on_deleted_closure_runner_;
|
||||
std::map<url::SchemeHostPort,
|
||||
std::map<std::string, net::SharedDictionaryInfo>>
|
||||
std::map<std::string, DictionaryInfoWithMatcher>>
|
||||
dictionary_info_map_;
|
||||
std::map<base::UnguessableToken, raw_ptr<RefCountedSharedDictionary>>
|
||||
dictionaries_;
|
||||
|
Reference in New Issue
Block a user