0

Add race-network-and-cache source to SW router rule mojo and database class.

This CL adds a new race-network-and-cache source to ServiceWorker router
rule mojo and to service worker database class for read/write.

This CL also changes ServiceWorkerRouterSource design by removing
ServiceWorkerRouterRaceSourceEnum and rename RaceSource to
RaceNetworkAndFetchEventSource and SW DB proto accordingly to avoid
confusion with the RaceSource enum.

To support race-network-and-cache source in
https://github.com/WICG/service-worker-static-routing-api/blob/main/final-form.md#race-network-and-cache-storage

Future CLs include changes to ServiceWorker evaluator, resource loaders,
IDL and DevTools.

Bug: 370844790
Change-Id: I13269bcfe6a453fe6dbb89df10b814ee5ef1a125
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6374322
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Liang Zhao <lzhao@microsoft.com>
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
Commit-Queue: Monica Chintala <monicach@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1444967}
This commit is contained in:
Monica Chintala
2025-04-09 14:55:17 -07:00
committed by Chromium LUCI CQ
parent fe934d032f
commit 2b0c5e35c7
24 changed files with 296 additions and 259 deletions

@@ -148,6 +148,8 @@ namespace {
// set a low write buffer size to trigger compaction more often. // set a low write buffer size to trigger compaction more often.
constexpr size_t kWriteBufferSize = 512 * 1024; constexpr size_t kWriteBufferSize = 512 * 1024;
using RouterSourceType = network::mojom::ServiceWorkerRouterSourceType;
class ServiceWorkerEnv : public leveldb_env::ChromiumEnv { class ServiceWorkerEnv : public leveldb_env::ChromiumEnv {
public: public:
ServiceWorkerEnv() : ChromiumEnv(storage::CreateFilesystemProxy()) {} ServiceWorkerEnv() : ChromiumEnv(storage::CreateFilesystemProxy()) {}
@@ -2788,40 +2790,22 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseRegistrationData(
return Status::kErrorCorrupted; return Status::kErrorCorrupted;
case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source:: case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source::
kNetworkSource: kNetworkSource:
source.type = source.type = RouterSourceType::kNetwork;
network::mojom::ServiceWorkerRouterSourceType::kNetwork;
source.network_source.emplace(); source.network_source.emplace();
break; break;
case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source:: case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source::
kRaceSource: { kRaceNetworkAndFetchEventSource:
source.type = network::mojom::ServiceWorkerRouterSourceType::kRace; source.type = RouterSourceType::kRaceNetworkAndFetchEvent;
blink::ServiceWorkerRouterRaceSource race_source; source.race_network_and_fetch_event_source.emplace();
if (s.race_source().has_target()) {
switch (s.race_source().target()) {
case ServiceWorkerRegistrationData::RouterRules::RuleV1::
Source::RaceSource::kNetworkAndFetchHandler:
race_source.target = blink::ServiceWorkerRouterRaceSource::
TargetEnum::kNetworkAndFetchHandler;
break;
}
} else {
// This happens when reading an old registration.
// It means kNetworkAndFetchHandler.
race_source.target = blink::ServiceWorkerRouterRaceSource::
TargetEnum::kNetworkAndFetchHandler;
}
source.race_source = race_source;
break; break;
}
case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source:: case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source::
kFetchEventSource: kFetchEventSource:
source.type = source.type = RouterSourceType::kFetchEvent;
network::mojom::ServiceWorkerRouterSourceType::kFetchEvent;
source.fetch_event_source.emplace(); source.fetch_event_source.emplace();
break; break;
case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source:: case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source::
kCacheSource: { kCacheSource: {
source.type = network::mojom::ServiceWorkerRouterSourceType::kCache; source.type = RouterSourceType::kCache;
blink::ServiceWorkerRouterCacheSource cache_source; blink::ServiceWorkerRouterCacheSource cache_source;
if (s.cache_source().has_cache_name()) { if (s.cache_source().has_cache_name()) {
cache_source.cache_name = s.cache_source().cache_name(); cache_source.cache_name = s.cache_source().cache_name();
@@ -2829,6 +2813,21 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseRegistrationData(
source.cache_source = cache_source; source.cache_source = cache_source;
break; break;
} }
case ServiceWorkerRegistrationData::RouterRules::RuleV1::Source::
kRaceNetworkAndCacheSource: {
source.type = RouterSourceType::kRaceNetworkAndCache;
source.race_network_and_cache_source.emplace();
const auto& cache_source =
s.race_network_and_cache_source().cache_source();
blink::ServiceWorkerRouterCacheSource cache_source_data;
if (cache_source.has_cache_name()) {
cache_source_data.cache_name = cache_source.cache_name();
}
source.race_network_and_cache_source->cache_source =
cache_source_data;
break;
}
} }
router_rule.sources.emplace_back(source); router_rule.sources.emplace_back(source);
} }
@@ -3028,31 +3027,33 @@ void ServiceWorkerDatabase::WriteRegistrationDataInBatch(
ServiceWorkerRegistrationData::RouterRules::RuleV1::Source* source = ServiceWorkerRegistrationData::RouterRules::RuleV1::Source* source =
v1->add_source(); v1->add_source();
switch (s.type) { switch (s.type) {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case RouterSourceType::kNetwork:
source->mutable_network_source(); source->mutable_network_source();
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kRace: { case RouterSourceType::kRaceNetworkAndFetchEvent:
auto* race_source = source->mutable_race_source(); source->mutable_race_network_and_fetch_event_source();
switch (s.race_source->target) {
case blink::ServiceWorkerRouterRaceSource::TargetEnum::
kNetworkAndFetchHandler:
race_source->set_target(
ServiceWorkerRegistrationData::RouterRules::RuleV1::Source::
RaceSource::kNetworkAndFetchHandler);
break;
}
break; break;
} case RouterSourceType::kFetchEvent:
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
source->mutable_fetch_event_source(); source->mutable_fetch_event_source();
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kCache: { case RouterSourceType::kCache: {
auto* cache_source = source->mutable_cache_source(); auto* cache_source = source->mutable_cache_source();
if (s.cache_source->cache_name) { if (s.cache_source->cache_name) {
cache_source->set_cache_name(*s.cache_source->cache_name); cache_source->set_cache_name(*s.cache_source->cache_name);
} }
break; break;
} }
case RouterSourceType::kRaceNetworkAndCache: {
auto* race_network_and_cache_source =
source->mutable_race_network_and_cache_source();
auto* cache_source =
race_network_and_cache_source->mutable_cache_source();
if (s.race_network_and_cache_source->cache_source.cache_name) {
cache_source->set_cache_name(
*s.race_network_and_cache_source->cache_source.cache_name);
}
break;
}
} }
} }
} }

@@ -207,21 +207,24 @@ message ServiceWorkerRegistrationData {
} }
message Source { message Source {
message NetworkSource {} message NetworkSource {}
message RaceSource { message RaceNetworkAndFetchEventSource {
enum Target { reserved 1; // Deprecated
kNetworkAndFetchHandler = 0; reserved "target"; // Deprecated
}
optional Target target = 1;
} }
message FetchEventSource {} message FetchEventSource {}
message CacheSource { message CacheSource {
optional string cache_name = 1; optional string cache_name = 1;
} }
message RaceNetworkAndCacheSource {
required CacheSource cache_source = 1;
}
oneof source { oneof source {
NetworkSource network_source = 1; NetworkSource network_source = 1;
RaceSource race_source = 2; RaceNetworkAndFetchEventSource race_network_and_fetch_event_source =
2;
FetchEventSource fetch_event_source = 3; FetchEventSource fetch_event_source = 3;
CacheSource cache_source = 4; CacheSource cache_source = 4;
RaceNetworkAndCacheSource race_network_and_cache_source = 5;
} }
} }
repeated Condition condition = 1; repeated Condition condition = 1;

@@ -3827,13 +3827,9 @@ TEST(ServiceWorkerDatabaseTest, RouterRulesStoreRestore) {
} }
{ {
blink::ServiceWorkerRouterSource source; blink::ServiceWorkerRouterSource source;
source.type = network::mojom::ServiceWorkerRouterSourceType::kRace; source.type = network::mojom::ServiceWorkerRouterSourceType::
{ kRaceNetworkAndFetchEvent;
blink::ServiceWorkerRouterRaceSource race_source; source.race_network_and_fetch_event_source.emplace();
race_source.target = blink::ServiceWorkerRouterRaceSource::TargetEnum::
kNetworkAndFetchHandler;
source.race_source = race_source;
}
rule.sources.push_back(source); rule.sources.push_back(source);
} }
{ {
@@ -3856,6 +3852,31 @@ TEST(ServiceWorkerDatabaseTest, RouterRulesStoreRestore) {
source.cache_source = cache_source; source.cache_source = cache_source;
rule.sources.push_back(source); rule.sources.push_back(source);
} }
{
// Race network and cache without cache_name.
blink::ServiceWorkerRouterSource source;
source.type =
network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache;
source.race_network_and_cache_source.emplace();
blink::ServiceWorkerRouterCacheSource cache_source;
source.race_network_and_cache_source->cache_source = cache_source;
rule.sources.push_back(source);
}
{
// Race network and cache with cache_name.
blink::ServiceWorkerRouterSource source;
source.type =
network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache;
source.race_network_and_cache_source.emplace();
blink::ServiceWorkerRouterCacheSource cache_source;
cache_source.cache_name = "example_cache_name";
source.race_network_and_cache_source->cache_source = cache_source;
rule.sources.push_back(source);
}
router_rules.rules.emplace_back(rule); router_rules.rules.emplace_back(rule);
store_and_restore(router_rules); store_and_restore(router_rules);
@@ -3958,57 +3979,4 @@ TEST(ServiceWorkerDatabaseTest, RouterRulesLegacyPathname) {
} }
} }
TEST(ServiceWorkerDatabaseTest, EnsureNetworkAndFetchHandlerSet) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
ServiceWorkerRegistrationData data;
data.set_registration_id(1);
data.set_scope_url("https://example.com");
data.set_script_url("https://example.com/sw");
data.set_version_id(1);
data.set_is_active(true);
data.set_has_fetch_handler(true);
data.set_last_update_check_time(
base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
database->next_avail_registration_id_ = 2;
database->next_avail_version_id_ = 2;
blink::StorageKey key =
blink::StorageKey::CreateFromStringForTesting(data.scope_url());
{
{
auto* rules = data.mutable_router_rules();
// service_worker_internals::kRouterRuleVersion
// in service_worker_database.cc
rules->set_version(1);
auto* v1 = rules->add_v1();
auto* condition = v1->add_condition();
auto* request = condition->mutable_request();
request->set_method("GET");
auto* source = v1->add_source();
source->mutable_race_source();
}
// Write the serialization.
std::string value;
ASSERT_TRUE(data.SerializeToString(&value));
// Parse the serialized data.
RegistrationDataPtr registration;
ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
database->ParseRegistrationData(value, key, &registration));
EXPECT_FALSE(registration->router_rules->rules.empty());
// RaceSource should have kNetworkAndFetchHandler target if nothing
// defined.
blink::ServiceWorkerRouterRaceSource race_source;
race_source.target = blink::ServiceWorkerRouterRaceSource::TargetEnum::
kNetworkAndFetchHandler;
EXPECT_EQ(race_source,
registration->router_rules->rules[0].sources[0].race_source);
}
}
} // namespace storage } // namespace storage

@@ -2095,13 +2095,17 @@ String BuildServiceWorkerRouterSourceType(
switch (type) { switch (type) {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
return protocol::Network::ServiceWorkerRouterSourceEnum::Network; return protocol::Network::ServiceWorkerRouterSourceEnum::Network;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent:
return protocol::Network::ServiceWorkerRouterSourceEnum:: return protocol::Network::ServiceWorkerRouterSourceEnum::
RaceNetworkAndFetchHandler; RaceNetworkAndFetchHandler;
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
return protocol::Network::ServiceWorkerRouterSourceEnum::FetchEvent; return protocol::Network::ServiceWorkerRouterSourceEnum::FetchEvent;
case network::mojom::ServiceWorkerRouterSourceType::kCache: case network::mojom::ServiceWorkerRouterSourceType::kCache:
return protocol::Network::ServiceWorkerRouterSourceEnum::Cache; return protocol::Network::ServiceWorkerRouterSourceEnum::Cache;
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
return protocol::Network::ServiceWorkerRouterSourceEnum::
RaceNetworkAndCache;
} }
} }

@@ -5231,8 +5231,8 @@ IN_PROC_BROWSER_TEST_P(
ukm::TestAutoSetUkmRecorder::ExpectEntryMetric( ukm::TestAutoSetUkmRecorder::ExpectEntryMetric(
entry, entry,
MainResourceLoadCompletedUkmEntry::kMatchedFirstRouterSourceTypeName, MainResourceLoadCompletedUkmEntry::kMatchedFirstRouterSourceTypeName,
static_cast<std::int64_t>( static_cast<std::int64_t>(network::mojom::ServiceWorkerRouterSourceType::
network::mojom::ServiceWorkerRouterSourceType::kRace)); kRaceNetworkAndFetchEvent));
ukm::TestAutoSetUkmRecorder::ExpectEntryMetric( ukm::TestAutoSetUkmRecorder::ExpectEntryMetric(
entry, MainResourceLoadCompletedUkmEntry::kActualRouterSourceTypeName, entry, MainResourceLoadCompletedUkmEntry::kActualRouterSourceTypeName,
@@ -5606,8 +5606,8 @@ IN_PROC_BROWSER_TEST_P(
ukm::TestAutoSetUkmRecorder::ExpectEntryMetric( ukm::TestAutoSetUkmRecorder::ExpectEntryMetric(
entry, entry,
MainResourceLoadCompletedUkmEntry::kMatchedFirstRouterSourceTypeName, MainResourceLoadCompletedUkmEntry::kMatchedFirstRouterSourceTypeName,
static_cast<std::int64_t>( static_cast<std::int64_t>(network::mojom::ServiceWorkerRouterSourceType::
network::mojom::ServiceWorkerRouterSourceType::kRace)); kRaceNetworkAndFetchEvent));
ukm::TestAutoSetUkmRecorder::ExpectEntryMetric( ukm::TestAutoSetUkmRecorder::ExpectEntryMetric(
entry, MainResourceLoadCompletedUkmEntry::kActualRouterSourceTypeName, entry, MainResourceLoadCompletedUkmEntry::kActualRouterSourceTypeName,

@@ -253,7 +253,6 @@ void ServiceWorkerMainResourceLoader::StartRequest(
RaceNetworkRequestMode race_network_request_mode = RaceNetworkRequestMode race_network_request_mode =
RaceNetworkRequestMode::kDefault; RaceNetworkRequestMode::kDefault;
std::optional<blink::ServiceWorkerRouterRaceSource> race_source;
// Check if registered static router rules match the request. // Check if registered static router rules match the request.
if (active_worker->router_evaluator()) { if (active_worker->router_evaluator()) {
CHECK(active_worker->router_evaluator()->IsValid()); CHECK(active_worker->router_evaluator()->IsValid());
@@ -328,9 +327,9 @@ void ServiceWorkerMainResourceLoader::StartRequest(
} }
return; return;
} }
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent:
race_network_request_mode = RaceNetworkRequestMode::kForced; race_network_request_mode = RaceNetworkRequestMode::kForced;
race_source = sources[0].race_source;
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
race_network_request_mode = RaceNetworkRequestMode::kSkipped; race_network_request_mode = RaceNetworkRequestMode::kSkipped;
@@ -364,6 +363,10 @@ void ServiceWorkerMainResourceLoader::StartRequest(
}, },
active_worker)); active_worker));
return; return;
case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndCache:
// TODO(crbug.com/370844790): implement race network and cache
break;
} }
} }
} }
@@ -384,8 +387,6 @@ void ServiceWorkerMainResourceLoader::StartRequest(
} }
if (race_network_request_mode == RaceNetworkRequestMode::kForced) { if (race_network_request_mode == RaceNetworkRequestMode::kForced) {
CHECK_EQ(race_source->target, blink::ServiceWorkerRouterRaceSource::
TargetEnum::kNetworkAndFetchHandler);
if (base::FeatureList::IsEnabled( if (base::FeatureList::IsEnabled(
features:: features::
kServiceWorkerStaticRouterRaceNetworkRequestPerformanceImprovement)) { kServiceWorkerStaticRouterRaceNetworkRequestPerformanceImprovement)) {
@@ -944,7 +945,8 @@ void ServiceWorkerMainResourceLoader::DidDispatchFetchEvent(
if (auto* route_info = response_head_->service_worker_router_info.get()) { if (auto* route_info = response_head_->service_worker_router_info.get()) {
if (route_info->matched_source_type && if (route_info->matched_source_type &&
*route_info->matched_source_type == *route_info->matched_source_type ==
network::mojom::ServiceWorkerRouterSourceType::kRace) { network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent) {
route_info->actual_source_type = route_info->actual_source_type =
network::mojom::ServiceWorkerRouterSourceType::kFetchEvent; network::mojom::ServiceWorkerRouterSourceType::kFetchEvent;
} else { } else {
@@ -1221,7 +1223,8 @@ void ServiceWorkerMainResourceLoader::SetCommitResponsibility(
if (response_head_ && response_head_->service_worker_router_info && if (response_head_ && response_head_->service_worker_router_info &&
response_head_->service_worker_router_info->matched_source_type && response_head_->service_worker_router_info->matched_source_type &&
*response_head_->service_worker_router_info->matched_source_type == *response_head_->service_worker_router_info->matched_source_type ==
network::mojom::ServiceWorkerRouterSourceType::kRace && network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent &&
fetch_response_from == FetchResponseFrom::kWithoutServiceWorker) { fetch_response_from == FetchResponseFrom::kWithoutServiceWorker) {
response_head_->service_worker_router_info->actual_source_type = response_head_->service_worker_router_info->actual_source_type =
network::mojom::ServiceWorkerRouterSourceType::kNetwork; network::mojom::ServiceWorkerRouterSourceType::kNetwork;

@@ -617,14 +617,19 @@ class ServiceWorkerMainResourceLoaderTest : public testing::Test {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
source.network_source.emplace(); source.network_source.emplace();
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
source.race_source.emplace(); kRaceNetworkAndFetchEvent:
source.race_network_and_fetch_event_source.emplace();
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kCache: case network::mojom::ServiceWorkerRouterSourceType::kCache: {
blink::ServiceWorkerRouterCacheSource cache_source; blink::ServiceWorkerRouterCacheSource cache_source;
cache_source.cache_name = kTestCacheName; cache_source.cache_name = kTestCacheName;
source.cache_source = cache_source; source.cache_source = cache_source;
break; break;
}
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
// TODO(crbug.com/370844790): implement race network and cache
break;
} }
rule.sources.emplace_back(source); rule.sources.emplace_back(source);
rules.rules.emplace_back(rule); rules.rules.emplace_back(rule);
@@ -1536,7 +1541,8 @@ TEST_F(ServiceWorkerMainResourceLoaderTest, StaticRoutingNetwork) {
TEST_F(ServiceWorkerMainResourceLoaderTest, StaticRoutingRaceNetworkWin) { TEST_F(ServiceWorkerMainResourceLoaderTest, StaticRoutingRaceNetworkWin) {
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
SetupStaticRoutingRules(network::mojom::ServiceWorkerRouterSourceType::kRace); SetupStaticRoutingRules(
network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndFetchEvent);
service_worker_->DeferResponse(); service_worker_->DeferResponse();
SetupNetworkResponse(); SetupNetworkResponse();
@@ -1559,7 +1565,7 @@ TEST_F(ServiceWorkerMainResourceLoaderTest, StaticRoutingRaceNetworkWin) {
auto expected_info = CreateResponseInfoFromServiceWorker(); auto expected_info = CreateResponseInfoFromServiceWorker();
expected_info->was_fetched_via_service_worker = false; expected_info->was_fetched_via_service_worker = false;
auto expected_router_info = CreateExpectedMatchingServiceWorkerRouterInfo( auto expected_router_info = CreateExpectedMatchingServiceWorkerRouterInfo(
network::mojom::ServiceWorkerRouterSourceType::kRace); network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndFetchEvent);
expected_router_info->actual_source_type = expected_router_info->actual_source_type =
network::mojom::ServiceWorkerRouterSourceType::kNetwork; network::mojom::ServiceWorkerRouterSourceType::kNetwork;
expected_info->service_worker_router_info = std::move(expected_router_info); expected_info->service_worker_router_info = std::move(expected_router_info);
@@ -1587,7 +1593,8 @@ TEST_F(ServiceWorkerMainResourceLoaderTest, StaticRoutingRaceNetworkWin) {
TEST_F(ServiceWorkerMainResourceLoaderTest, StaticRoutingRaceFetchWin) { TEST_F(ServiceWorkerMainResourceLoaderTest, StaticRoutingRaceFetchWin) {
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
SetupStaticRoutingRules(network::mojom::ServiceWorkerRouterSourceType::kRace); SetupStaticRoutingRules(
network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndFetchEvent);
SetupErrorNetworkResponse(); SetupErrorNetworkResponse();
@@ -1603,7 +1610,7 @@ TEST_F(ServiceWorkerMainResourceLoaderTest, StaticRoutingRaceFetchWin) {
EXPECT_EQ(200, info->headers->response_code()); EXPECT_EQ(200, info->headers->response_code());
auto expected_info = CreateResponseInfoFromServiceWorker(); auto expected_info = CreateResponseInfoFromServiceWorker();
auto expected_router_info = CreateExpectedMatchingServiceWorkerRouterInfo( auto expected_router_info = CreateExpectedMatchingServiceWorkerRouterInfo(
network::mojom::ServiceWorkerRouterSourceType::kRace); network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndFetchEvent);
expected_router_info->actual_source_type = expected_router_info->actual_source_type =
network::mojom::ServiceWorkerRouterSourceType::kFetchEvent; network::mojom::ServiceWorkerRouterSourceType::kFetchEvent;
expected_info->service_worker_router_info = std::move(expected_router_info); expected_info->service_worker_router_info = std::move(expected_router_info);

@@ -92,8 +92,10 @@ bool ServiceWorkerResourceLoader::ShouldRecordServiceWorkerFetchStart() {
switch (*matched_router_source_type_) { switch (*matched_router_source_type_) {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
case network::mojom::ServiceWorkerRouterSourceType::kCache: case network::mojom::ServiceWorkerRouterSourceType::kCache:
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
return false; return false;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent:
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
// These source should start ServiceWorker and trigger fetch-event. // These source should start ServiceWorker and trigger fetch-event.
return true; return true;

@@ -243,8 +243,9 @@ bool IsValidSources(
return false; return false;
} }
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
if (!s.race_source) { kRaceNetworkAndFetchEvent:
if (!s.race_network_and_fetch_event_source) {
RecordSetupError( RecordSetupError(
ServiceWorkerRouterEvaluatorErrorEnums::kInvalidSource); ServiceWorkerRouterEvaluatorErrorEnums::kInvalidSource);
return false; return false;
@@ -264,6 +265,13 @@ bool IsValidSources(
return false; return false;
} }
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
if (!s.race_network_and_cache_source) {
RecordSetupError(
ServiceWorkerRouterEvaluatorErrorEnums::kInvalidSource);
return false;
}
break;
} }
} }
return true; return true;
@@ -733,9 +741,8 @@ void ServiceWorkerRouterEvaluator::Compile() {
(s.type == (s.type ==
network::mojom::ServiceWorkerRouterSourceType::kFetchEvent); network::mojom::ServiceWorkerRouterSourceType::kFetchEvent);
bool has_race_network_and_fetch_event = bool has_race_network_and_fetch_event =
(s.type == network::mojom::ServiceWorkerRouterSourceType::kRace && (s.type == network::mojom::ServiceWorkerRouterSourceType::
s.race_source->target == blink::ServiceWorkerRouterRaceSource:: kRaceNetworkAndFetchEvent);
TargetEnum::kNetworkAndFetchHandler);
require_fetch_handler_ |= require_fetch_handler_ |=
(has_fetch_event | has_race_network_and_fetch_event); (has_fetch_event | has_race_network_and_fetch_event);
has_non_fetch_event_source_ |= !has_fetch_event; has_non_fetch_event_source_ |= !has_fetch_event;
@@ -795,10 +802,8 @@ base::Value ServiceWorkerRouterEvaluator::ToValue() const {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
source.Append("network"); source.Append("network");
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
CHECK_EQ(s.race_source->target, kRaceNetworkAndFetchEvent:
blink::ServiceWorkerRouterRaceSource::TargetEnum::
kNetworkAndFetchHandler);
source.Append("race-network-and-fetch-handler"); source.Append("race-network-and-fetch-handler");
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
@@ -813,6 +818,10 @@ base::Value ServiceWorkerRouterEvaluator::ToValue() const {
source.Append("cache"); source.Append("cache");
} }
break; break;
case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndCache:
// TODO(crbug.com/370844790): implement race network and cache
break;
} }
} }
rule.Set("condition", std::move(condition)); rule.Set("condition", std::move(condition));

@@ -280,8 +280,9 @@ TEST(ServiceWorkerRouterEvaluator, ChooseMatchedRoute) {
} }
{ {
blink::ServiceWorkerRouterSource source; blink::ServiceWorkerRouterSource source;
source.type = network::mojom::ServiceWorkerRouterSourceType::kRace; source.type = network::mojom::ServiceWorkerRouterSourceType::
source.race_source.emplace(); kRaceNetworkAndFetchEvent;
source.race_network_and_fetch_event_source.emplace();
rule.sources.push_back(source); rule.sources.push_back(source);
} }
rules.rules.push_back(rule); rules.rules.push_back(rule);
@@ -299,8 +300,9 @@ TEST(ServiceWorkerRouterEvaluator, ChooseMatchedRoute) {
// Four sources rule should match because of *.css URLPattern. // Four sources rule should match because of *.css URLPattern.
EXPECT_TRUE(eval_result.has_value()); EXPECT_TRUE(eval_result.has_value());
EXPECT_EQ(1U, eval_result->sources.size()); EXPECT_EQ(1U, eval_result->sources.size());
EXPECT_EQ(network::mojom::ServiceWorkerRouterSourceType::kRace, EXPECT_EQ(
eval_result->sources[0].type); network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndFetchEvent,
eval_result->sources[0].type);
} }
TEST(ServiceWorkerRouterEvaluator, SimpleHostnameMatch) { TEST(ServiceWorkerRouterEvaluator, SimpleHostnameMatch) {
@@ -1356,8 +1358,9 @@ TEST(ServiceWorkerRouterEvaluator, ToValueBasicSimpleRule) {
} }
{ {
blink::ServiceWorkerRouterSource source; blink::ServiceWorkerRouterSource source;
source.type = network::mojom::ServiceWorkerRouterSourceType::kRace; source.type = network::mojom::ServiceWorkerRouterSourceType::
source.race_source.emplace(); kRaceNetworkAndFetchEvent;
source.race_network_and_fetch_event_source.emplace();
rule.sources.push_back(source); rule.sources.push_back(source);
} }
{ {

@@ -392,7 +392,6 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
kForced, kForced,
kSkipped kSkipped
} race_network_request_mode = kDefault; } race_network_request_mode = kDefault;
std::optional<blink::ServiceWorkerRouterRaceSource> race_source;
if (controller_connector_->router_evaluator()) { if (controller_connector_->router_evaluator()) {
response_head_->service_worker_router_info = response_head_->service_worker_router_info =
@@ -422,9 +421,9 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
OnFallback(std::nullopt, std::move(timing)); OnFallback(std::nullopt, std::move(timing));
} }
return; return;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent:
race_network_request_mode = kForced; race_network_request_mode = kForced;
race_source = sources[0].race_source;
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
race_network_request_mode = kSkipped; race_network_request_mode = kSkipped;
@@ -437,6 +436,10 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
&ServiceWorkerSubresourceLoader::DidCacheStorageMatch, &ServiceWorkerSubresourceLoader::DidCacheStorageMatch,
weak_factory_.GetWeakPtr(), base::TimeTicks::Now())); weak_factory_.GetWeakPtr(), base::TimeTicks::Now()));
return; return;
case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndCache:
// TODO(crbug.com/370844790): implement race network and cache
break;
} }
} }
} }
@@ -490,8 +493,6 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
switch (race_network_request_mode) { switch (race_network_request_mode) {
case kForced: case kForced:
CHECK_EQ(race_source->target, blink::ServiceWorkerRouterRaceSource::
TargetEnum::kNetworkAndFetchHandler);
if (StartRaceNetworkRequest()) { if (StartRaceNetworkRequest()) {
SetDispatchedPreloadType(DispatchedPreloadType::kRaceNetworkRequest); SetDispatchedPreloadType(DispatchedPreloadType::kRaceNetworkRequest);
} }
@@ -1367,7 +1368,8 @@ void ServiceWorkerSubresourceLoader::SetCommitResponsibility(
if (response_head_ && response_head_->service_worker_router_info && if (response_head_ && response_head_->service_worker_router_info &&
response_head_->service_worker_router_info->matched_source_type && response_head_->service_worker_router_info->matched_source_type &&
*response_head_->service_worker_router_info->matched_source_type == *response_head_->service_worker_router_info->matched_source_type ==
network::mojom::ServiceWorkerRouterSourceType::kRace && network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent &&
fetch_response_from == FetchResponseFrom::kWithoutServiceWorker) { fetch_response_from == FetchResponseFrom::kWithoutServiceWorker) {
response_head_->service_worker_router_info->actual_source_type = response_head_->service_worker_router_info->actual_source_type =
network::mojom::ServiceWorkerRouterSourceType::kNetwork; network::mojom::ServiceWorkerRouterSourceType::kNetwork;

@@ -13,11 +13,13 @@ enum ServiceWorkerRouterSourceType {
// Network is used as a source. // Network is used as a source.
kNetwork = 0, kNetwork = 0,
// Race network and fetch handler. // Race network and fetch handler.
kRace = 1, kRaceNetworkAndFetchEvent = 1,
// Fetch Event is used as a source. // Fetch Event is used as a source.
kFetchEvent = 2, kFetchEvent = 2,
// Cache is used as a source. // Cache is used as a source.
kCache = 3, kCache = 3,
// Race network and cache.
kRaceNetworkAndCache = 4,
}; };
// The initial status of service worker on navigation request. // The initial status of service worker on navigation request.

@@ -49,16 +49,6 @@ bool ServiceWorkerRouterCondition::operator==(
return get() == other.get(); return get() == other.get();
} }
bool ServiceWorkerRouterRaceSource::operator==(
const ServiceWorkerRouterRaceSource& other) const {
return target == other.target;
}
bool ServiceWorkerRouterCacheSource::operator==(
const ServiceWorkerRouterCacheSource& other) const {
return cache_name == other.cache_name;
}
bool ServiceWorkerRouterSource::operator==( bool ServiceWorkerRouterSource::operator==(
const ServiceWorkerRouterSource& other) const { const ServiceWorkerRouterSource& other) const {
if (type != other.type) { if (type != other.type) {
@@ -67,12 +57,17 @@ bool ServiceWorkerRouterSource::operator==(
switch (type) { switch (type) {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
return network_source == other.network_source; return network_source == other.network_source;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
return race_source == other.race_source; kRaceNetworkAndFetchEvent:
return race_network_and_fetch_event_source ==
other.race_network_and_fetch_event_source;
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
return fetch_event_source == other.fetch_event_source; return fetch_event_source == other.fetch_event_source;
case network::mojom::ServiceWorkerRouterSourceType::kCache: case network::mojom::ServiceWorkerRouterSourceType::kCache:
return cache_source == other.cache_source; return cache_source == other.cache_source;
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
return race_network_and_cache_source ==
other.race_network_and_cache_source;
} }
} }

@@ -83,16 +83,6 @@ bool StructTraits<blink::mojom::ServiceWorkerRouterConditionDataView,
return true; return true;
} }
bool StructTraits<blink::mojom::ServiceWorkerRouterRaceSourceDataView,
blink::ServiceWorkerRouterRaceSource>::
Read(blink::mojom::ServiceWorkerRouterRaceSourceDataView data,
blink::ServiceWorkerRouterRaceSource* out) {
if (!data.ReadTarget(&out->target)) {
return false;
}
return true;
}
bool StructTraits<blink::mojom::ServiceWorkerRouterCacheSourceDataView, bool StructTraits<blink::mojom::ServiceWorkerRouterCacheSourceDataView,
blink::ServiceWorkerRouterCacheSource>:: blink::ServiceWorkerRouterCacheSource>::
Read(blink::mojom::ServiceWorkerRouterCacheSourceDataView data, Read(blink::mojom::ServiceWorkerRouterCacheSourceDataView data,
@@ -103,6 +93,18 @@ bool StructTraits<blink::mojom::ServiceWorkerRouterCacheSourceDataView,
return true; return true;
} }
bool StructTraits<
blink::mojom::ServiceWorkerRouterRaceNetworkAndCacheSourceDataView,
blink::ServiceWorkerRouterRaceNetworkAndCacheSource>::
Read(
blink::mojom::ServiceWorkerRouterRaceNetworkAndCacheSourceDataView data,
blink::ServiceWorkerRouterRaceNetworkAndCacheSource* out) {
if (!data.ReadCacheSource(&out->cache_source)) {
return false;
}
return true;
}
blink::mojom::ServiceWorkerRouterSourceDataView::Tag blink::mojom::ServiceWorkerRouterSourceDataView::Tag
UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView, UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView,
blink::ServiceWorkerRouterSource>:: blink::ServiceWorkerRouterSource>::
@@ -110,12 +112,17 @@ UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView,
switch (data.type) { switch (data.type) {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
return blink::mojom::ServiceWorkerRouterSource::Tag::kNetworkSource; return blink::mojom::ServiceWorkerRouterSource::Tag::kNetworkSource;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
return blink::mojom::ServiceWorkerRouterSource::Tag::kRaceSource; kRaceNetworkAndFetchEvent:
return blink::mojom::ServiceWorkerRouterSource::Tag::
kRaceNetworkAndFetchEventSource;
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
return blink::mojom::ServiceWorkerRouterSource::Tag::kFetchEventSource; return blink::mojom::ServiceWorkerRouterSource::Tag::kFetchEventSource;
case network::mojom::ServiceWorkerRouterSourceType::kCache: case network::mojom::ServiceWorkerRouterSourceType::kCache:
return blink::mojom::ServiceWorkerRouterSource::Tag::kCacheSource; return blink::mojom::ServiceWorkerRouterSource::Tag::kCacheSource;
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
return blink::mojom::ServiceWorkerRouterSource::Tag::
kRaceNetworkAndCacheSource;
} }
} }
@@ -128,9 +135,11 @@ bool UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView,
out->type = network::mojom::ServiceWorkerRouterSourceType::kNetwork; out->type = network::mojom::ServiceWorkerRouterSourceType::kNetwork;
out->network_source.emplace(); out->network_source.emplace();
return true; return true;
case blink::mojom::ServiceWorkerRouterSource::Tag::kRaceSource: case blink::mojom::ServiceWorkerRouterSource::Tag::
out->type = network::mojom::ServiceWorkerRouterSourceType::kRace; kRaceNetworkAndFetchEventSource:
out->race_source.emplace(); out->type = network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent;
out->race_network_and_fetch_event_source.emplace();
return true; return true;
case blink::mojom::ServiceWorkerRouterSource::Tag::kFetchEventSource: case blink::mojom::ServiceWorkerRouterSource::Tag::kFetchEventSource:
out->type = network::mojom::ServiceWorkerRouterSourceType::kFetchEvent; out->type = network::mojom::ServiceWorkerRouterSourceType::kFetchEvent;
@@ -142,6 +151,15 @@ bool UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView,
return false; return false;
} }
return true; return true;
case blink::mojom::ServiceWorkerRouterSource::Tag::
kRaceNetworkAndCacheSource:
out->type =
network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache;
if (!data.ReadRaceNetworkAndCacheSource(
&out->race_network_and_cache_source)) {
return false;
}
return true;
} }
return false; return false;
} }

@@ -78,8 +78,9 @@ TEST(ServiceWorkerRouterRulesTest, SimpleRoundTrip) {
} }
{ {
blink::ServiceWorkerRouterSource source; blink::ServiceWorkerRouterSource source;
source.type = network::mojom::ServiceWorkerRouterSourceType::kRace; source.type = network::mojom::ServiceWorkerRouterSourceType::
source.race_source.emplace(); kRaceNetworkAndFetchEvent;
source.race_network_and_fetch_event_source.emplace();
rule.sources.push_back(source); rule.sources.push_back(source);
} }
{ {
@@ -102,6 +103,25 @@ TEST(ServiceWorkerRouterRulesTest, SimpleRoundTrip) {
source.cache_source = cache_source; source.cache_source = cache_source;
rule.sources.push_back(source); rule.sources.push_back(source);
} }
{
blink::ServiceWorkerRouterSource source;
source.type =
network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache;
source.race_network_and_cache_source.emplace();
blink::ServiceWorkerRouterCacheSource cache_source;
source.race_network_and_cache_source->cache_source = cache_source;
rule.sources.push_back(source);
}
{
blink::ServiceWorkerRouterSource source;
source.type =
network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache;
source.race_network_and_cache_source.emplace();
blink::ServiceWorkerRouterCacheSource cache_source;
cache_source.cache_name = "example cache name";
source.race_network_and_cache_source->cache_source = cache_source;
rule.sources.push_back(source);
}
rules.rules.push_back(rule); rules.rules.push_back(rule);
} }
TestRoundTrip(rules); TestRoundTrip(rules);

@@ -198,27 +198,20 @@ class BLINK_COMMON_EXPORT ServiceWorkerRouterCondition {
// Network source structure. // Network source structure.
// TODO(crbug.com/1371756): implement fields in the proposal. // TODO(crbug.com/1371756): implement fields in the proposal.
struct BLINK_COMMON_EXPORT ServiceWorkerRouterNetworkSource { struct BLINK_COMMON_EXPORT ServiceWorkerRouterNetworkSource {
bool operator==(const ServiceWorkerRouterNetworkSource& other) const { bool operator==(const ServiceWorkerRouterNetworkSource& other) const =
return true; default;
}
}; };
// Race two sources. // Race network and fetch event sources.
struct BLINK_COMMON_EXPORT ServiceWorkerRouterRaceSource { struct BLINK_COMMON_EXPORT ServiceWorkerRouterRaceNetworkAndFetchEventSource {
// Enum to explain which sources race. bool operator==(const ServiceWorkerRouterRaceNetworkAndFetchEventSource&
enum class TargetEnum { other) const = default;
kNetworkAndFetchHandler = 0,
};
TargetEnum target = TargetEnum::kNetworkAndFetchHandler;
bool operator==(const ServiceWorkerRouterRaceSource& other) const;
}; };
// Fetch handler source structure. // Fetch handler source structure.
struct BLINK_COMMON_EXPORT ServiceWorkerRouterFetchEventSource { struct BLINK_COMMON_EXPORT ServiceWorkerRouterFetchEventSource {
bool operator==(const ServiceWorkerRouterFetchEventSource& other) const { bool operator==(const ServiceWorkerRouterFetchEventSource& other) const =
return true; default;
}
}; };
// Cache source structure. // Cache source structure.
@@ -228,7 +221,15 @@ struct BLINK_COMMON_EXPORT ServiceWorkerRouterCacheSource {
// tracks are used for matching as if CacheStorage.match(). // tracks are used for matching as if CacheStorage.match().
std::optional<std::string> cache_name; std::optional<std::string> cache_name;
bool operator==(const ServiceWorkerRouterCacheSource& other) const; bool operator==(const ServiceWorkerRouterCacheSource& other) const = default;
};
// Race network and cache sources.
struct BLINK_COMMON_EXPORT ServiceWorkerRouterRaceNetworkAndCacheSource {
ServiceWorkerRouterCacheSource cache_source;
bool operator==(const ServiceWorkerRouterRaceNetworkAndCacheSource& other)
const = default;
}; };
// This represents a source of the router rule. // This represents a source of the router rule.
@@ -237,9 +238,12 @@ struct BLINK_COMMON_EXPORT ServiceWorkerRouterSource {
network::mojom::ServiceWorkerRouterSourceType type; network::mojom::ServiceWorkerRouterSourceType type;
std::optional<ServiceWorkerRouterNetworkSource> network_source; std::optional<ServiceWorkerRouterNetworkSource> network_source;
std::optional<ServiceWorkerRouterRaceSource> race_source; std::optional<ServiceWorkerRouterRaceNetworkAndFetchEventSource>
race_network_and_fetch_event_source;
std::optional<ServiceWorkerRouterFetchEventSource> fetch_event_source; std::optional<ServiceWorkerRouterFetchEventSource> fetch_event_source;
std::optional<ServiceWorkerRouterCacheSource> cache_source; std::optional<ServiceWorkerRouterCacheSource> cache_source;
std::optional<ServiceWorkerRouterRaceNetworkAndCacheSource>
race_network_and_cache_source;
bool operator==(const ServiceWorkerRouterSource& other) const; bool operator==(const ServiceWorkerRouterSource& other) const;
}; };

@@ -183,43 +183,13 @@ struct BLINK_COMMON_EXPORT
}; };
template <> template <>
struct BLINK_COMMON_EXPORT struct BLINK_COMMON_EXPORT StructTraits<
EnumTraits<blink::mojom::ServiceWorkerRouterRaceSourceEnum, blink::mojom::ServiceWorkerRouterRaceNetworkAndFetchEventSourceDataView,
blink::ServiceWorkerRouterRaceSource::TargetEnum> { blink::ServiceWorkerRouterRaceNetworkAndFetchEventSource> {
static blink::mojom::ServiceWorkerRouterRaceSourceEnum ToMojom( static bool Read(
blink::ServiceWorkerRouterRaceSource::TargetEnum input) { blink::mojom::ServiceWorkerRouterRaceNetworkAndFetchEventSourceDataView
switch (input) { data,
case blink::ServiceWorkerRouterRaceSource::TargetEnum:: blink::ServiceWorkerRouterRaceNetworkAndFetchEventSource* out);
kNetworkAndFetchHandler:
return blink::mojom::ServiceWorkerRouterRaceSourceEnum::
kNetworkAndFetchHandler;
}
}
static bool FromMojom(
blink::mojom::ServiceWorkerRouterRaceSourceEnum input,
blink::ServiceWorkerRouterRaceSource::TargetEnum* output) {
switch (input) {
case blink::mojom::ServiceWorkerRouterRaceSourceEnum::
kNetworkAndFetchHandler:
*output = blink::ServiceWorkerRouterRaceSource::TargetEnum::
kNetworkAndFetchHandler;
break;
}
return true;
}
};
template <>
struct BLINK_COMMON_EXPORT
StructTraits<blink::mojom::ServiceWorkerRouterRaceSourceDataView,
blink::ServiceWorkerRouterRaceSource> {
static blink::ServiceWorkerRouterRaceSource::TargetEnum target(
const blink::ServiceWorkerRouterRaceSource& data) {
return data.target;
}
static bool Read(blink::mojom::ServiceWorkerRouterRaceSourceDataView data,
blink::ServiceWorkerRouterRaceSource* out);
}; };
template <> template <>
@@ -246,6 +216,20 @@ struct BLINK_COMMON_EXPORT
blink::ServiceWorkerRouterCacheSource* out); blink::ServiceWorkerRouterCacheSource* out);
}; };
template <>
struct BLINK_COMMON_EXPORT StructTraits<
blink::mojom::ServiceWorkerRouterRaceNetworkAndCacheSourceDataView,
blink::ServiceWorkerRouterRaceNetworkAndCacheSource> {
static const blink::ServiceWorkerRouterCacheSource& cache_source(
const blink::ServiceWorkerRouterRaceNetworkAndCacheSource& data) {
return data.cache_source;
}
static bool Read(
blink::mojom::ServiceWorkerRouterRaceNetworkAndCacheSourceDataView data,
blink::ServiceWorkerRouterRaceNetworkAndCacheSource* out);
};
template <> template <>
struct BLINK_COMMON_EXPORT struct BLINK_COMMON_EXPORT
UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView, UnionTraits<blink::mojom::ServiceWorkerRouterSourceDataView,
@@ -258,9 +242,10 @@ struct BLINK_COMMON_EXPORT
return *data.network_source; return *data.network_source;
} }
static const blink::ServiceWorkerRouterRaceSource& race_source( static const blink::ServiceWorkerRouterRaceNetworkAndFetchEventSource&
race_network_and_fetch_event_source(
const blink::ServiceWorkerRouterSource& data) { const blink::ServiceWorkerRouterSource& data) {
return *data.race_source; return *data.race_network_and_fetch_event_source;
} }
static const blink::ServiceWorkerRouterFetchEventSource& fetch_event_source( static const blink::ServiceWorkerRouterFetchEventSource& fetch_event_source(
@@ -273,6 +258,11 @@ struct BLINK_COMMON_EXPORT
return *data.cache_source; return *data.cache_source;
} }
static const blink::ServiceWorkerRouterRaceNetworkAndCacheSource&
race_network_and_cache_source(const blink::ServiceWorkerRouterSource& data) {
return *data.race_network_and_cache_source;
}
static bool Read(blink::mojom::ServiceWorkerRouterSourceDataView data, static bool Read(blink::mojom::ServiceWorkerRouterSourceDataView data,
blink::ServiceWorkerRouterSource* out); blink::ServiceWorkerRouterSource* out);
}; };

@@ -6334,6 +6334,7 @@ domain Network
cache cache
fetch-event fetch-event
race-network-and-fetch-handler race-network-and-fetch-handler
race-network-and-cache
experimental type ServiceWorkerRouterInfo extends object experimental type ServiceWorkerRouterInfo extends object
properties properties

@@ -91,29 +91,13 @@ struct ServiceWorkerRouterCondition {
struct ServiceWorkerRouterNetworkSource { struct ServiceWorkerRouterNetworkSource {
}; };
// Enum to represent the race targets.
// We aim to implement other race-* sources, which are not in the specification
// yet. race-network-and-fetch-event has already been in the specification.
// https://w3c.github.io/ServiceWorker/#dom-routersourceenum-race-network-and-fetch-handler
// race-cache-and-network has already been proposed.
// https://github.com/WICG/service-worker-static-routing-api/pull/34.
// However, it can technically be expanded to race arbitrary two or three of
// "network", "fetch-event", or "cache". Please stay tuned.
enum ServiceWorkerRouterRaceSourceEnum {
// Race network source and the fetch handler.
// https://w3c.github.io/ServiceWorker/#dom-routersourceenum-race-network-and-fetch-handler
kNetworkAndFetchHandler = 0,
};
// This source is used when the browser should allow a network source and // This source is used when the browser should allow a network source and
// the fetch handler to race, allowing the first one to respond to service // the fetch handler to race, allowing the first one to respond to service
// the request. // the request.
// https://w3c.github.io/ServiceWorker/#dom-routersourceenum-race-network-and-fetch-handler
// TODO(crbug.com/1371756): implement fields in the full picture. // TODO(crbug.com/1371756): implement fields in the full picture.
// https://github.com/WICG/service-worker-static-routing-api // https://github.com/WICG/service-worker-static-routing-api
struct ServiceWorkerRouterRaceSource { struct ServiceWorkerRouterRaceNetworkAndFetchEventSource {
// Target to race.
ServiceWorkerRouterRaceSourceEnum target;
}; };
// This is used for explicitly running the fetch event listeners. // This is used for explicitly running the fetch event listeners.
@@ -132,15 +116,25 @@ struct ServiceWorkerRouterCacheSource {
string? cache_name; string? cache_name;
}; };
// This source is used when the browser should allow a network source and
// the response should be retrieved from the cache storage to race, allowing
// the first one to respond to service the request.
// https://github.com/WICG/service-worker-static-routing-api
struct ServiceWorkerRouterRaceNetworkAndCacheSource {
// Cache source information.
ServiceWorkerRouterCacheSource cache_source;
};
// This represents a source of the router rule. // This represents a source of the router rule.
// https://w3c.github.io/ServiceWorker/#typedefdef-routersource // https://w3c.github.io/ServiceWorker/#typedefdef-routersource
// TODO(crbug.com/1371756): implement other sources in the full picture. // TODO(crbug.com/1371756): implement other sources in the full picture.
// https://github.com/WICG/service-worker-static-routing-api // https://github.com/WICG/service-worker-static-routing-api
union ServiceWorkerRouterSource { union ServiceWorkerRouterSource {
ServiceWorkerRouterNetworkSource network_source; ServiceWorkerRouterNetworkSource network_source;
ServiceWorkerRouterRaceSource race_source; ServiceWorkerRouterRaceNetworkAndFetchEventSource race_network_and_fetch_event_source;
ServiceWorkerRouterFetchEventSource fetch_event_source; ServiceWorkerRouterFetchEventSource fetch_event_source;
ServiceWorkerRouterCacheSource cache_source; ServiceWorkerRouterCacheSource cache_source;
ServiceWorkerRouterRaceNetworkAndCacheSource race_network_and_cache_source;
}; };
// This represents a ServiceWorker static routing API's router rule. // This represents a ServiceWorker static routing API's router rule.

@@ -628,13 +628,17 @@ String BuildServiceWorkerRouterSourceType(
switch (type) { switch (type) {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
return protocol::Network::ServiceWorkerRouterSourceEnum::Network; return protocol::Network::ServiceWorkerRouterSourceEnum::Network;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent:
return protocol::Network::ServiceWorkerRouterSourceEnum:: return protocol::Network::ServiceWorkerRouterSourceEnum::
RaceNetworkAndFetchHandler; RaceNetworkAndFetchHandler;
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
return protocol::Network::ServiceWorkerRouterSourceEnum::FetchEvent; return protocol::Network::ServiceWorkerRouterSourceEnum::FetchEvent;
case network::mojom::ServiceWorkerRouterSourceType::kCache: case network::mojom::ServiceWorkerRouterSourceType::kCache:
return protocol::Network::ServiceWorkerRouterSourceEnum::Cache; return protocol::Network::ServiceWorkerRouterSourceEnum::Cache;
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
return protocol::Network::ServiceWorkerRouterSourceEnum::
RaceNetworkAndCache;
} }
} }

@@ -293,10 +293,9 @@ std::optional<ServiceWorkerRouterSource> RouterSourceEnumToBlink(
return std::nullopt; return std::nullopt;
} }
ServiceWorkerRouterSource source; ServiceWorkerRouterSource source;
source.type = network::mojom::ServiceWorkerRouterSourceType::kRace; source.type = network::mojom::ServiceWorkerRouterSourceType::
source.race_source.emplace(); kRaceNetworkAndFetchEvent;
source.race_source->target = blink::ServiceWorkerRouterRaceSource:: source.race_network_and_fetch_event_source.emplace();
TargetEnum::kNetworkAndFetchHandler;
return source; return source;
} }
case V8RouterSourceEnum::Enum::kFetchEvent: { case V8RouterSourceEnum::Enum::kFetchEvent: {

@@ -417,8 +417,9 @@ TEST(ServiceWorkerRouterTypeConverterTest, Race) {
expected_rule.condition = expected_rule.condition =
blink::ServiceWorkerRouterCondition::WithUrlPattern(expected_url_pattern); blink::ServiceWorkerRouterCondition::WithUrlPattern(expected_url_pattern);
blink::ServiceWorkerRouterSource expected_source; blink::ServiceWorkerRouterSource expected_source;
expected_source.type = network::mojom::ServiceWorkerRouterSourceType::kRace; expected_source.type =
expected_source.race_source.emplace(); network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndFetchEvent;
expected_source.race_network_and_fetch_event_source.emplace();
expected_rule.sources.emplace_back(expected_source); expected_rule.sources.emplace_back(expected_source);
V8TestingScope scope; V8TestingScope scope;

@@ -3541,9 +3541,13 @@ void ResourceFetcher::UpdateServiceWorkerSubresourceMetrics(
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
metrics.matched_network_router_source_count++; metrics.matched_network_router_source_count++;
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent:
metrics.matched_race_network_and_fetch_router_source_count++; metrics.matched_race_network_and_fetch_router_source_count++;
break; break;
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
// TODO(crbug.com/370844790): implement race network and cache
break;
} }
} }

@@ -20,12 +20,15 @@ String ServiceWorkerRouterInfo::GetRouterSourceTypeString(
switch (source) { switch (source) {
case network::mojom::ServiceWorkerRouterSourceType::kNetwork: case network::mojom::ServiceWorkerRouterSourceType::kNetwork:
return "network"; return "network";
case network::mojom::ServiceWorkerRouterSourceType::kRace: case network::mojom::ServiceWorkerRouterSourceType::
kRaceNetworkAndFetchEvent:
return "race-network-and-fetch-handler"; return "race-network-and-fetch-handler";
case network::mojom::ServiceWorkerRouterSourceType::kCache: case network::mojom::ServiceWorkerRouterSourceType::kCache:
return "cache"; return "cache";
case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent: case network::mojom::ServiceWorkerRouterSourceType::kFetchEvent:
return "fetch-event"; return "fetch-event";
case network::mojom::ServiceWorkerRouterSourceType::kRaceNetworkAndCache:
return "race-network-and-cache";
} }
} }