[ServiceWorker+Prefetch] Implement serving side
Design doc:
https://docs.google.com/document/d/1kbs8YJuh93F_K6JqW84YSsjVWcAeU41Mj9nwPr6IXRs/edit?tab=t.0#heading=h.9fuqzdmgb6kv
After this CL, the primary cases for ServiceWorker-controlled prefetches
should work behind the flag (as shown in `basic.sub.https.html`), while
TODOs are still to be fixed.
Bug: 40947546
Change-Id: I86fc3f0ceaed0eda8aa67842cb23d29e796020eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6021277
Commit-Queue: Hiroshige Hayashizaki <hiroshige@chromium.org>
Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org>
Reviewed-by: Ken Okada <kenoss@chromium.org>
Reviewed-by: Taiyo Mizuhashi <taiyo@chromium.org>
Reviewed-by: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1433678}
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 6c34877..549abc0 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -39,6 +39,7 @@
#include "content/browser/loader/subresource_proxying_url_loader_service.h"
#include "content/browser/loader/url_loader_factory_utils.h"
#include "content/browser/navigation_subresource_loader_params.h"
+#include "content/browser/preloading/prefetch/prefetch_features.h"
#include "content/browser/preloading/prefetch/prefetch_url_loader_interceptor.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_request.h"
@@ -670,6 +671,18 @@
// The interceptor may not be created in certain cases (e.g., the origin
// is not secure).
if (service_worker_interceptor) {
+ if (base::FeatureList::IsEnabled(features::kPrefetchServiceWorker)) {
+ // Set up an interceptor for ServiceWorker-controlled prefetches. This
+ // is needed before the ServiceWorkerMainResourceLoaderInterceptor which
+ // would also intercept the request for ServiceWorker-controlled URLs.
+ // See the design docs at https://crbug.com/40947546.
+ interceptors_.push_back(std::make_unique<PrefetchURLLoaderInterceptor>(
+ PrefetchServiceWorkerState::kControlled,
+ service_worker_handle_->AsWeakPtr(), frame_tree_node_id_,
+ request_info_->initiator_document_token,
+ request_info_->prefetch_serving_page_metrics_container));
+ }
+
interceptors_.push_back(std::move(service_worker_interceptor));
}
}
@@ -682,8 +695,14 @@
}
// Set up an interceptor for prefetch.
+ // When `features::kPrefetchServiceWorker` is enabled, we intentionally add
+ // two `PrefetchURLLoaderInterceptor`s, one for ServiceWorker-controlled
+ // prefetches above, and one for non-ServiceWorker-controlled prefetches here.
+ // See the design docs at https://crbug.com/40947546.
interceptors_.push_back(std::make_unique<PrefetchURLLoaderInterceptor>(
- frame_tree_node_id_, request_info_->initiator_document_token,
+ PrefetchServiceWorkerState::kDisallowed,
+ /*service_worker_handle=*/nullptr, frame_tree_node_id_,
+ request_info_->initiator_document_token,
request_info_->prefetch_serving_page_metrics_container));
// See if embedders want to add interceptors.
diff --git a/content/browser/preloading/prefetch/prefetch_match_resolver.cc b/content/browser/preloading/prefetch/prefetch_match_resolver.cc
index 3eb4354d9..2d67fbe 100644
--- a/content/browser/preloading/prefetch/prefetch_match_resolver.cc
+++ b/content/browser/preloading/prefetch/prefetch_match_resolver.cc
@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/preloading/prefetch/prefetch_container.h"
+#include "content/browser/preloading/prefetch/prefetch_features.h"
#include "content/browser/preloading/prefetch/prefetch_params.h"
#include "content/browser/preloading/prefetch/prefetch_service.h"
#include "content/browser/preloading/prerender/prerender_features.h"
@@ -44,11 +45,23 @@
PrefetchMatchResolver::PrefetchMatchResolver(
PrefetchContainer::Key navigated_key,
+ PrefetchServiceWorkerState expected_service_worker_state,
base::WeakPtr<PrefetchService> prefetch_service,
Callback callback)
: navigated_key_(std::move(navigated_key)),
+ expected_service_worker_state_(expected_service_worker_state),
prefetch_service_(std::move(prefetch_service)),
- callback_(std::move(callback)) {}
+ callback_(std::move(callback)) {
+ switch (expected_service_worker_state_) {
+ case PrefetchServiceWorkerState::kAllowed:
+ NOTREACHED();
+ case PrefetchServiceWorkerState::kControlled:
+ CHECK(base::FeatureList::IsEnabled(features::kPrefetchServiceWorker));
+ break;
+ case PrefetchServiceWorkerState::kDisallowed:
+ break;
+ }
+}
PrefetchMatchResolver::~PrefetchMatchResolver() = default;
@@ -64,6 +77,7 @@
// static
void PrefetchMatchResolver::FindPrefetch(
PrefetchContainer::Key navigated_key,
+ PrefetchServiceWorkerState expected_service_worker_state,
bool is_nav_prerender,
PrefetchService& prefetch_service,
base::WeakPtr<PrefetchServingPageMetricsContainer>
@@ -72,8 +86,8 @@
TRACE_EVENT0("loading", "PrefetchMatchResolver::FindPrefetch");
// See the comment of `self_`.
auto prefetch_match_resolver = base::WrapUnique(new PrefetchMatchResolver(
- std::move(navigated_key), prefetch_service.GetWeakPtr(),
- std::move(callback)));
+ std::move(navigated_key), expected_service_worker_state,
+ prefetch_service.GetWeakPtr(), std::move(callback)));
PrefetchMatchResolver& ref = *prefetch_match_resolver.get();
ref.self_ = std::move(prefetch_match_resolver);
@@ -91,7 +105,20 @@
std::move(serving_page_metrics_container));
// Consume `candidates`.
for (auto& prefetch_container : candidates) {
- RegisterCandidate(*prefetch_container);
+ // Register the candidate only if `PrefetchServiceWorkerState` is matching.
+ if (prefetch_container->service_worker_state() ==
+ expected_service_worker_state_) {
+ RegisterCandidate(*prefetch_container);
+ } else if (prefetch_container->service_worker_state() ==
+ PrefetchServiceWorkerState::kAllowed) {
+ // Also register the candidate if `PrefetchServiceWorkerState::kAllowed`,
+ // so that we anyway start BlockUntilHead (if eligible) before service
+ // worker controller check is done, and remove the candidate later (in
+ // `OnDeterminedHead()`) if the final `PrefetchServiceWorkerState` turns
+ // not matching.
+ CHECK(base::FeatureList::IsEnabled(features::kPrefetchServiceWorker));
+ RegisterCandidate(*prefetch_container);
+ }
}
// Backward compatibility to the behavior of `PrefetchMatchResolver`: If it
@@ -244,6 +271,25 @@
// Note that `OnDeterimnedHead()` is called even if `PrefetchContainer` is in
// failure `PrefetchState`. See, for example, https://crbug.com/375333786.
+
+ // Remove the candidate if the final `PrefetchServiceWorkerState` is not
+ // matching, i.e. we started speculatively BlockUntilHead on the candidate
+ // when `PrefetchServiceWorkerState::kAllowed`, but the final
+ // `PrefetchServiceWorkerState` found not matching here. At the time of
+ // `OnDeterminedHead()`, service worker controller check is always done and
+ // thus the final `PrefetchServiceWorkerState` is already determined here.
+ //
+ // TODO(https://crbug.com/40947546): Maybe we could unblock earlier when
+ // `PrefetchServiceWorkerState` is transitioned from `kAllowed`.
+ CHECK_NE(prefetch_container.service_worker_state(),
+ PrefetchServiceWorkerState::kAllowed);
+ if (prefetch_container.service_worker_state() !=
+ expected_service_worker_state_) {
+ CHECK(base::FeatureList::IsEnabled(features::kPrefetchServiceWorker));
+ MaybeUnblockForUnmatch(prefetch_container.key());
+ return;
+ }
+
switch (prefetch_container.GetServableState(PrefetchCacheableDuration())) {
case PrefetchContainer::ServableState::kShouldBlockUntilEligibilityGot:
// All callsites of `PrefetchContainer::OnDeterminedHead()` are
@@ -309,6 +355,9 @@
CHECK(candidate_data->prefetch_container);
PrefetchContainer& prefetch_container = *candidate_data->prefetch_container;
+ CHECK_EQ(prefetch_container.service_worker_state(),
+ expected_service_worker_state_);
+
UnregisterCandidate(prefetch_key, /*is_served=*/true);
// Unregister remaining candidates as not served.
diff --git a/content/browser/preloading/prefetch/prefetch_match_resolver.h b/content/browser/preloading/prefetch/prefetch_match_resolver.h
index b04139b..4ca5a499 100644
--- a/content/browser/preloading/prefetch/prefetch_match_resolver.h
+++ b/content/browser/preloading/prefetch/prefetch_match_resolver.h
@@ -55,12 +55,17 @@
//
// This method is async. `callback` will be called when it is done.
// `bool(reader)` is true iff a matching servable prefetch is found.
- static void FindPrefetch(PrefetchContainer::Key navigated_key,
- bool is_nav_prerender,
- PrefetchService& prefetch_service,
- base::WeakPtr<PrefetchServingPageMetricsContainer>
- serving_page_metrics_container,
- Callback callback);
+ //
+ // Matches prefetches only if its final PrefetchServiceWorkerState is
+ // `expected_service_worker_state` (either `kControlled` or `kDisallowed`).
+ static void FindPrefetch(
+ PrefetchContainer::Key navigated_key,
+ PrefetchServiceWorkerState expected_service_worker_state,
+ bool is_nav_prerender,
+ PrefetchService& prefetch_service,
+ base::WeakPtr<PrefetchServingPageMetricsContainer>
+ serving_page_metrics_container,
+ Callback callback);
private:
struct CandidateData final {
@@ -71,9 +76,11 @@
std::unique_ptr<base::OneShotTimer> timeout_timer;
};
- explicit PrefetchMatchResolver(PrefetchContainer::Key navigated_key,
- base::WeakPtr<PrefetchService>,
- Callback callback);
+ explicit PrefetchMatchResolver(
+ PrefetchContainer::Key navigated_key,
+ PrefetchServiceWorkerState expected_service_worker_state,
+ base::WeakPtr<PrefetchService>,
+ Callback callback);
// Returns blocked duration. Returns null iff it's not blocked yet.
std::optional<base::TimeDelta> GetBlockedDuration() const;
@@ -138,6 +145,7 @@
std::unique_ptr<PrefetchMatchResolver> self_;
const PrefetchContainer::Key navigated_key_;
+ const PrefetchServiceWorkerState expected_service_worker_state_;
base::WeakPtr<PrefetchService> prefetch_service_;
Callback callback_;
std::map<PrefetchContainer::Key, std::unique_ptr<CandidateData>> candidates_;
diff --git a/content/browser/preloading/prefetch/prefetch_service.cc b/content/browser/preloading/prefetch/prefetch_service.cc
index 816485c7..db1c5f2192 100644
--- a/content/browser/preloading/prefetch/prefetch_service.cc
+++ b/content/browser/preloading/prefetch/prefetch_service.cc
@@ -786,13 +786,11 @@
NOTREACHED();
case PrefetchServiceWorkerState::kControlled:
- // Currently we disallow redirects for ServiceWorker-controlled
+ // Currently we disallow redirects from ServiceWorker-controlled
// prefetches.
- // TODO(https://crbug.com/40947546): Supply an appropriate eligibility
- // value if needed.
OnGotEligibility(std::move(prefetch_container),
std::move(redirect_data),
- PreloadingEligibility::kUserHasServiceWorker);
+ PreloadingEligibility::kRedirectFromServiceWorker);
return;
}
} else {
diff --git a/content/browser/preloading/prefetch/prefetch_service_unittest.cc b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
index e7297a4..c3e1156 100644
--- a/content/browser/preloading/prefetch/prefetch_service_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
@@ -830,7 +830,8 @@
BrowserContextImpl::From(browser_context())->GetPrefetchService();
auto key = PrefetchContainer::Key(initiator_document_token, url);
PrefetchMatchResolver::FindPrefetch(
- std::move(key), /*is_nav_prerender=*/false, *prefetch_service,
+ std::move(key), PrefetchServiceWorkerState::kDisallowed,
+ /*is_nav_prerender=*/false, *prefetch_service,
GetServingPageMetricsContainerForMostRecentNavigation(),
std::move(callback));
}
@@ -916,7 +917,8 @@
BrowserContextImpl::From(browser_context())->GetPrefetchService();
auto key = PrefetchContainer::Key(initiator_document_token, url);
PrefetchMatchResolver::FindPrefetch(
- std::move(key), is_nav_prerender, *prefetch_service,
+ std::move(key), PrefetchServiceWorkerState::kDisallowed,
+ is_nav_prerender, *prefetch_service,
std::move(serving_page_metrics_container), std::move(callback));
return res;
diff --git a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.cc b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.cc
index 49e9b57..df6baa2 100644
--- a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.cc
+++ b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.cc
@@ -21,6 +21,8 @@
#include "content/browser/preloading/prerender/prerender_host_registry.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_request.h"
+#include "content/browser/service_worker/service_worker_client.h"
+#include "content/browser/service_worker/service_worker_main_resource_handle.h"
#include "content/public/browser/web_contents.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/single_request_url_loader_factory.h"
@@ -58,14 +60,25 @@
}
PrefetchURLLoaderInterceptor::PrefetchURLLoaderInterceptor(
+ PrefetchServiceWorkerState expected_service_worker_state,
+ base::WeakPtr<ServiceWorkerMainResourceHandle>
+ service_worker_handle_for_navigation,
FrameTreeNodeId frame_tree_node_id,
std::optional<blink::DocumentToken> initiator_document_token,
base::WeakPtr<PrefetchServingPageMetricsContainer>
serving_page_metrics_container)
- : frame_tree_node_id_(frame_tree_node_id),
+ : expected_service_worker_state_(expected_service_worker_state),
+ service_worker_handle_for_navigation_(
+ std::move(service_worker_handle_for_navigation)),
+ frame_tree_node_id_(frame_tree_node_id),
initiator_document_token_(std::move(initiator_document_token)),
serving_page_metrics_container_(
- std::move(serving_page_metrics_container)) {}
+ std::move(serving_page_metrics_container)) {
+ if (!base::FeatureList::IsEnabled(features::kPrefetchServiceWorker)) {
+ CHECK_EQ(expected_service_worker_state_,
+ PrefetchServiceWorkerState::kDisallowed);
+ }
+}
PrefetchURLLoaderInterceptor::~PrefetchURLLoaderInterceptor() = default;
@@ -97,7 +110,8 @@
OnGotPrefetchToServe(
frame_tree_node_id_, tentative_resource_request.url,
base::BindOnce(&PrefetchURLLoaderInterceptor::OnGetPrefetchComplete,
- weak_factory_.GetWeakPtr()),
+ weak_factory_.GetWeakPtr(),
+ tentative_resource_request.url),
std::move(redirect_reader_));
return;
}
@@ -123,10 +137,10 @@
return;
}
- GetPrefetch(
- tentative_resource_request,
- base::BindOnce(&PrefetchURLLoaderInterceptor::OnGetPrefetchComplete,
- weak_factory_.GetWeakPtr()));
+ GetPrefetch(tentative_resource_request,
+ base::BindOnce(
+ &PrefetchURLLoaderInterceptor::OnGetPrefetchComplete,
+ weak_factory_.GetWeakPtr(), tentative_resource_request.url));
}
void PrefetchURLLoaderInterceptor::GetPrefetch(
@@ -171,11 +185,13 @@
}();
PrefetchMatchResolver::FindPrefetch(
- std::move(key), is_nav_prerender, *prefetch_service,
- serving_page_metrics_container_, std::move(callback));
+ std::move(key), expected_service_worker_state_, is_nav_prerender,
+ *prefetch_service, serving_page_metrics_container_,
+ std::move(callback));
}
void PrefetchURLLoaderInterceptor::OnGetPrefetchComplete(
+ GURL navigation_url,
PrefetchContainer::Reader reader) {
TRACE_EVENT0("loading",
"PrefetchURLLoaderInterceptor::OnGetPrefetchComplete");
@@ -186,6 +202,21 @@
reader.CreateRequestHandler();
}
+ if (expected_service_worker_state_ ==
+ PrefetchServiceWorkerState::kControlled &&
+ request_handler) {
+ // ServiceWorker-controlled prefetch should be always non-redirecting.
+ CHECK(reader.IsEnd());
+
+ if (service_worker_handle_for_navigation_ && client_for_prefetch) {
+ service_worker_handle_for_navigation_->service_worker_client()
+ ->InheritControllerFromPrefetch(*client_for_prefetch, navigation_url);
+ } else {
+ // Do not intercept the request.
+ request_handler = PrefetchRequestHandler();
+ }
+ }
+
if (!request_handler) {
// Do not intercept the request.
redirect_reader_ = PrefetchContainer::Reader();
@@ -211,6 +242,8 @@
}
redirect_reader_ = PrefetchContainer::Reader();
} else {
+ CHECK_EQ(expected_service_worker_state_,
+ PrefetchServiceWorkerState::kDisallowed);
redirect_reader_ = std::move(reader);
}
diff --git a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.h b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.h
index c8f8cab7..29cb3966 100644
--- a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.h
+++ b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.h
@@ -21,6 +21,7 @@
class BrowserContext;
class PrefetchContainer;
+class ServiceWorkerMainResourceHandle;
using PrefetchCompleteCallbackForTesting =
base::RepeatingCallback<void(PrefetchContainer*)>;
@@ -30,6 +31,9 @@
: public NavigationLoaderInterceptor {
public:
PrefetchURLLoaderInterceptor(
+ PrefetchServiceWorkerState expected_service_worker_state,
+ base::WeakPtr<ServiceWorkerMainResourceHandle>
+ service_worker_handle_for_navigation,
FrameTreeNodeId frame_tree_node_id,
std::optional<blink::DocumentToken> initiator_document_token,
base::WeakPtr<PrefetchServingPageMetricsContainer>
@@ -65,7 +69,18 @@
base::OnceCallback<void(PrefetchContainer::Reader)>
get_prefetch_callback) const;
- void OnGetPrefetchComplete(PrefetchContainer::Reader reader);
+ void OnGetPrefetchComplete(GURL navigation_url,
+ PrefetchContainer::Reader reader);
+
+ // Matches prefetches only if its final PrefetchServiceWorkerState is
+ // `expected_service_worker_state_`, either `kControlled` or `kDisallowed`.
+ const PrefetchServiceWorkerState expected_service_worker_state_;
+
+ // `ServiceWorkerMainResourceHandle` used for the navigation to be intercepted
+ // (i.e. NOT the handle used for prefetch). This is used only for the
+ // `kControlled` case and can be null for `kDisallowed` case.
+ const base::WeakPtr<ServiceWorkerMainResourceHandle>
+ service_worker_handle_for_navigation_;
// The frame tree node |this| is associated with, used to retrieve
// |PrefetchService|.
diff --git a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc
index 487ad75b..a8ee0fd 100644
--- a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor_unittest.cc
@@ -247,6 +247,8 @@
void CreateInterceptor(
std::optional<blink::DocumentToken> initiator_document_token) {
interceptor_ = std::make_unique<PrefetchURLLoaderInterceptor>(
+ PrefetchServiceWorkerState::kDisallowed,
+ /*service_worker_handle=*/nullptr,
web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId(),
std::move(initiator_document_token),
/*serving_page_metrics_container=*/nullptr);
diff --git a/content/browser/service_worker/service_worker_client.cc b/content/browser/service_worker/service_worker_client.cc
index 83fa5d7..b43d09a 100644
--- a/content/browser/service_worker/service_worker_client.cc
+++ b/content/browser/service_worker/service_worker_client.cc
@@ -17,6 +17,7 @@
#include "base/uuid.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/loader/navigation_url_loader_impl.h"
+#include "content/browser/preloading/prefetch/prefetch_features.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/service_worker/service_worker_container_host.h"
@@ -1158,6 +1159,28 @@
creator_host.SetInherited();
}
+void ServiceWorkerClient::InheritControllerFromPrefetch(
+ ServiceWorkerClient& client_for_prefetch,
+ const GURL& navigation_url) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ CHECK(base::FeatureList::IsEnabled(features::kPrefetchServiceWorker));
+ CHECK(IsContainerForWindowClient());
+ CHECK(client_for_prefetch.IsContainerForWindowClient());
+
+ UpdateUrls(navigation_url, client_for_prefetch.top_frame_origin(),
+ client_for_prefetch.key());
+
+ // Inherit the controller used for prefetching from `client_for_prefetch`.
+ if (client_for_prefetch.controller_registration()) {
+ AddMatchingRegistration(client_for_prefetch.controller_registration());
+ // `client_for_prefetch` shouldn't be in back forward cache because it's for
+ // prefetch.
+ CHECK(!client_for_prefetch.is_in_back_forward_cache());
+ SetControllerRegistration(client_for_prefetch.controller_registration(),
+ false /* notify_controllerchange */);
+ }
+}
+
mojo::PendingReceiver<blink::mojom::ServiceWorkerRunningStatusCallback>
ServiceWorkerClient::GetRunningStatusCallbackReceiver() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/content/browser/service_worker/service_worker_client.h b/content/browser/service_worker/service_worker_client.h
index c498a872..9f686512 100644
--- a/content/browser/service_worker/service_worker_client.h
+++ b/content/browser/service_worker/service_worker_client.h
@@ -355,6 +355,13 @@
void InheritControllerFrom(ServiceWorkerClient& creator_host,
const GURL& client_url);
+ // For Window service worker clients served by ServiceWorker-controlled
+ // prefetch. Inherits the controller used for prefetching from
+ // `client_for_prefetch`, while setting `navigation_url`, similar to
+ // `InheritControllerFrom()`.
+ void InheritControllerFromPrefetch(ServiceWorkerClient& client_for_prefetch,
+ const GURL& navigation_url);
+
void SetContainerReady();
bool is_inherited() const { return is_inherited_; }
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html
index 9420088..e4c10353 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html
@@ -25,10 +25,6 @@
const swOption = new URL(location.href).searchParams.get('sw');
promise_test(async t => {
- // Current Chromium's expected behavior: prefetch only works when there
- // are no controlling service worker.
- const expectsPrefetch = swOption === 'no-controller';
-
const hostname = originOption === 'cross-site' ? '{{hosts[alt][www]}}'
: undefined;
const win = await spawnWindow(t, { protocol: 'https', hostname: hostname });
@@ -62,7 +58,12 @@
return requestHeaders;
}, []);
- if (expectsPrefetch) {
+ // Current Chromium's expected behavior:
+ // prefetch works when
+ // - there are no controlling service worker, or
+ // - same-origin prefetches with controlling service worker.
+ if (swOption === 'no-controller' ||
+ originOption === 'same-site') {
assert_prefetched(headers, "Prefetched result should be served.");
assert_equals(requestCount.prefetch, 1,
'a prefetch request should be sent to the server.');
diff --git a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt
new file mode 100644
index 0000000..a093960
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Prefetch with ServiceWorker (fetch-handler)
+ assert_in_array: Prefetched result should be served. value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt
new file mode 100644
index 0000000..41879b7
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Prefetch with ServiceWorker (fetch-handler-to-fallback)
+ assert_in_array: Prefetched result should be served. value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt
new file mode 100644
index 0000000..1dd9caa
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Prefetch with ServiceWorker (no-fetch-handler)
+ assert_in_array: Prefetched result should be served. value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt b/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt
deleted file mode 100644
index 53e39304..0000000
--- a/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] Prefetch with ServiceWorker (fetch-handler)
- assert_equals: prefetch requests should not be sent to the server. expected 0 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt b/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt
deleted file mode 100644
index b66b9a20..0000000
--- a/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] Prefetch with ServiceWorker (fetch-handler-to-fallback)
- assert_equals: prefetch requests should not be sent to the server. expected 0 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt b/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt
deleted file mode 100644
index 1bd90be..0000000
--- a/third_party/blink/web_tests/virtual/prefetch-serviceworker/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] Prefetch with ServiceWorker (no-fetch-handler)
- assert_equals: prefetch requests should not be sent to the server. expected 0 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt
new file mode 100644
index 0000000..a093960
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Prefetch with ServiceWorker (fetch-handler)
+ assert_in_array: Prefetched result should be served. value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt
new file mode 100644
index 0000000..41879b7
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=fetch-handler-to-fallback-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Prefetch with ServiceWorker (fetch-handler-to-fallback)
+ assert_in_array: Prefetched result should be served. value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt
new file mode 100644
index 0000000..1dd9caa
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/tentative/service-worker/basic.sub.https_origin=same-site_sw=no-fetch-handler-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Prefetch with ServiceWorker (no-fetch-handler)
+ assert_in_array: Prefetched result should be served. value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
+Harness: the test ran to completion.
+