Commit 088b8d24 authored by Tsuyoshi Horo's avatar Tsuyoshi Horo Committed by Commit Bot

Don't use PrefetchedSignedExchangeCache if related features are not enabled.

crrev.com/c/1681309 accidentally enabled
SignedExchangePrefetchCacheForNavigations feature. Prefetched SXGs are stored to
PrefetchedSignedExchangeCache even if both
SignedExchangePrefetchCacheForNavigations and SignedExchangeSubresourcePrefetch
are disabled. This is unintentional. Prefetched SXGs should no be stored to the
cache. This CL fix this.

SignedExchangePrefetchCacheForNavigations feature can be enabled only by flags.
But SignedExchangeSubresourcePrefetch feature can be enabled by both flags and
OriginTrial token which is checked in the renderer process.
So we need |is_signed_exchange_prefetch_cache_enabled| flag in ResourceRequest
to let the PrefetchURLLoader in the browser process whether the prefetched SXG
should be stored to PrefetchedSignedExchangeCache.

This CL adds the flag in blink::FetchParameters, blink::ResourceRequest,
bink::WebURLRequest, network::ResourceRequest and network::mojom::URLRequest,
and sets the flag in PreloadHelper::PrefetchIfNeeded() if
SignedExchangePrefetchCacheForNavigations feature or
SignedExchangeSubresourcePrefetch feature is enabled.

Change-Id: I719dbbd1093e05c30b6b0075ad87f56289f00ac7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1703687Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarKunihiko Sakamoto <ksakamoto@chromium.org>
Commit-Queue: Tsuyoshi Horo <horo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#678545}
parent b836034a
......@@ -63,8 +63,8 @@ PrefetchURLLoader::PrefetchURLLoader(
// (https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#internet-media-type-applicationsigned-exchange).
resource_request_.headers.SetHeader(
network::kAcceptHeader, kSignedExchangeEnabledAcceptHeaderForPrefetch);
if (prefetched_signed_exchange_cache) {
if (prefetched_signed_exchange_cache &&
resource_request.is_signed_exchange_prefetch_cache_enabled) {
prefetched_signed_exchange_cache_adapter_ =
std::make_unique<PrefetchedSignedExchangeCacheAdapter>(
std::move(prefetched_signed_exchange_cache),
......
......@@ -197,6 +197,7 @@ class NavigationHandleSXGAttributeObserver : public WebContentsObserver {
class SignedExchangePrefetchBrowserTest
: public testing::WithParamInterface<
std::tuple<bool /* network_service_enabled */,
bool /* sxg_prefetch_cache_for_navigations_enabled */,
bool /* sxg_subresource_prefetch_enabled */>>,
public PrefetchBrowserTestBase {
public:
......@@ -209,9 +210,11 @@ class SignedExchangePrefetchBrowserTest
void SetUp() override {
bool network_service_enabled;
bool sxg_prefetch_cache_for_navigations_enabled;
bool sxg_subresource_prefetch_enabled;
std::tie(network_service_enabled, sxg_subresource_prefetch_enabled) =
GetParam();
std::tie(network_service_enabled,
sxg_prefetch_cache_for_navigations_enabled,
sxg_subresource_prefetch_enabled) = GetParam();
std::vector<base::Feature> enable_features;
std::vector<base::Feature> disabled_features;
......@@ -224,12 +227,17 @@ class SignedExchangePrefetchBrowserTest
} else {
disabled_features.push_back(network::features::kNetworkService);
}
if (sxg_prefetch_cache_for_navigations_enabled) {
enable_features.push_back(
features::kSignedExchangePrefetchCacheForNavigations);
} else {
disabled_features.push_back(
features::kSignedExchangePrefetchCacheForNavigations);
}
if (sxg_subresource_prefetch_enabled) {
enable_features.push_back(features::kSignedExchangeSubresourcePrefetch);
} else {
disabled_features.push_back(features::kSignedExchangeSubresourcePrefetch);
enable_features.push_back(
features::kSignedExchangePrefetchCacheForNavigations);
}
feature_list_.InitWithFeatures(enable_features, disabled_features);
PrefetchBrowserTestBase::SetUp();
......@@ -248,6 +256,13 @@ class SignedExchangePrefetchBrowserTest
static constexpr uint64_t kTestBlobStorageMinFileSizeBytes = 10;
static constexpr uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
static bool IsSignedExchangePrefetchCacheEnabled() {
return base::FeatureList::IsEnabled(
features::kSignedExchangePrefetchCacheForNavigations) ||
base::FeatureList::IsEnabled(
features::kSignedExchangeSubresourcePrefetch);
}
void SetBlobLimits() {
scoped_refptr<ChromeBlobStorageContext> blob_context =
ChromeBlobStorageContext::GetFor(
......@@ -281,6 +296,36 @@ class SignedExchangePrefetchBrowserTest
const GURL inner_url =
embedded_test_server()->GetURL(inner_url_hostname, inner_url_path);
if (!IsSignedExchangePrefetchCacheEnabled()) {
EXPECT_TRUE(GetCachedExchanges(shell()).empty());
// Shutdown the server.
EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
// Need to setup MockSignedExchangeHandlerFactory because the SXG is
// loaded from HTTPCache.
MockSignedExchangeHandlerFactory factory({MockSignedExchangeHandlerParams(
sxg_url, SignedExchangeLoadResult::kSuccess, net::OK, inner_url,
"text/html", {}, header_integrity,
base::Time() /* signature_expire_time */)});
ScopedSignedExchangeHandlerFactory scoped_factory(&factory);
base::HistogramTester histograms;
// Subsequent navigation to the target URL wouldn't hit the network for
// the target URL. The target content should still be read correctly.
// The content is loaded from HTTPCache.
NavigateToURLAndWaitTitle(sxg_url, "Prefetch Target (SXG)");
EXPECT_EQ(1, sxg_request_counter->GetRequestCount());
histograms.ExpectTotalCount("PrefetchedSignedExchangeCache.Count", 0);
histograms.ExpectTotalCount("PrefetchedSignedExchangeCache.BodySize", 0);
histograms.ExpectTotalCount("PrefetchedSignedExchangeCache.BodySizeTotal",
0);
histograms.ExpectTotalCount(
"PrefetchedSignedExchangeCache.HeadersSizeTotal", 0);
return;
}
const auto cached_exchanges = GetCachedExchanges(shell());
EXPECT_EQ(1u, cached_exchanges.size());
const auto it = cached_exchanges.find(sxg_url);
......@@ -483,7 +528,8 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
// The signed exchange which response header has "vary: accept-encoding"
// header should be stored to the cache.
const auto cached_exchanges = GetCachedExchanges(shell());
EXPECT_EQ(1u, cached_exchanges.size());
EXPECT_EQ(IsSignedExchangePrefetchCacheEnabled() ? 1u : 0u,
cached_exchanges.size());
}
IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
......@@ -507,7 +553,8 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
const GURL inner_url =
embedded_test_server()->GetURL(hostname, inner_url_path);
EXPECT_EQ(1u, GetCachedExchanges(shell()).size());
EXPECT_EQ(IsSignedExchangePrefetchCacheEnabled() ? 1u : 0u,
GetCachedExchanges(shell()).size());
MockClock::Get().Advance(base::TimeDelta::FromSeconds(
net::HttpCache::kPrefetchReuseMins * 60 + 1));
......@@ -535,11 +582,11 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
"<head><title>Prefetch Target (SXG)</title></head>";
auto sxg_request_counter =
RequestCounter::CreateAndMonitor(embedded_test_server(), sxg_path);
const auto header_integrity = net::SHA256HashValue({{0x01}});
LoadPrefetchMainResourceSXGTestPage(
hostname, "/prefetch.html" /* prefetch_page_path */, hostname, sxg_path,
hostname, inner_url_path,
net::SHA256HashValue({{0x01}}) /* header_integrity */, content,
hostname, inner_url_path, header_integrity, content,
{{"cache-control",
base::StringPrintf("public, max-age=%d",
net::HttpCache::kPrefetchReuseMins * 3 *
......@@ -550,11 +597,24 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
const GURL inner_url =
embedded_test_server()->GetURL(hostname, inner_url_path);
EXPECT_EQ(1u, GetCachedExchanges(shell()).size());
EXPECT_EQ(IsSignedExchangePrefetchCacheEnabled() ? 1u : 0u,
GetCachedExchanges(shell()).size());
MockClock::Get().Advance(base::TimeDelta::FromSeconds(
net::HttpCache::kPrefetchReuseMins * 2 * 60));
NavigateToURLAndWaitTitle(sxg_url, "Prefetch Target (SXG)");
if (IsSignedExchangePrefetchCacheEnabled()) {
NavigateToURLAndWaitTitle(sxg_url, "Prefetch Target (SXG)");
} else {
// Need to setup MockSignedExchangeHandlerFactory because the SXG is loaded
// from HTTPCache.
MockSignedExchangeHandlerFactory factory({MockSignedExchangeHandlerParams(
sxg_url, SignedExchangeLoadResult::kSuccess, net::OK, inner_url,
"text/html", {}, header_integrity,
base::Time() /* signature_expire_time */)});
ScopedSignedExchangeHandlerFactory scoped_factory(&factory);
NavigateToURLAndWaitTitle(sxg_url, "Prefetch Target (SXG)");
}
// SXG must Not be fetched again.
EXPECT_EQ(1, sxg_request_counter->GetRequestCount());
......@@ -584,7 +644,8 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
const GURL inner_url =
embedded_test_server()->GetURL(hostname, inner_url_path);
EXPECT_EQ(1u, GetCachedExchanges(shell()).size());
EXPECT_EQ(IsSignedExchangePrefetchCacheEnabled() ? 1u : 0u,
GetCachedExchanges(shell()).size());
MockClock::Get().Advance(base::TimeDelta::FromSeconds(
net::HttpCache::kPrefetchReuseMins * 3 * 60 + 1));
......@@ -626,7 +687,8 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
const GURL inner_url =
embedded_test_server()->GetURL(hostname, inner_url_path);
EXPECT_EQ(1u, GetCachedExchanges(shell()).size());
EXPECT_EQ(IsSignedExchangePrefetchCacheEnabled() ? 1u : 0u,
GetCachedExchanges(shell()).size());
MockClock::Get().Advance(
base::TimeDelta::FromMinutes(net::HttpCache::kPrefetchReuseMins * 3));
......@@ -667,6 +729,8 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
const char* script_sxg_path = "/script_js.sxg";
const char* script_inner_url_path = "/script.js";
auto page_sxg_request_counter =
RequestCounter::CreateAndMonitor(embedded_test_server(), page_sxg_path);
auto script_sxg_request_counter =
RequestCounter::CreateAndMonitor(embedded_test_server(), script_sxg_path);
auto script_request_counter = RequestCounter::CreateAndMonitor(
......@@ -734,6 +798,7 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
WaitUntilLoaded(inner_url_script_url);
}
EXPECT_EQ(1, page_sxg_request_counter->GetRequestCount());
if (base::FeatureList::IsEnabled(
features::kSignedExchangeSubresourcePrefetch)) {
EXPECT_EQ(1, script_sxg_request_counter->GetRequestCount());
......@@ -749,37 +814,42 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
int64_t expected_body_size_total = 0u;
int64_t expected_headers_size_total = 0u;
if (base::FeatureList::IsEnabled(
features::kSignedExchangeSubresourcePrefetch)) {
EXPECT_EQ(2u, cached_exchanges.size());
if (IsSignedExchangePrefetchCacheEnabled()) {
if (base::FeatureList::IsEnabled(
features::kSignedExchangeSubresourcePrefetch)) {
EXPECT_EQ(2u, cached_exchanges.size());
const auto script_it = cached_exchanges.find(sxg_script_url);
ASSERT_TRUE(script_it != cached_exchanges.end());
const auto script_it = cached_exchanges.find(sxg_script_url);
ASSERT_TRUE(script_it != cached_exchanges.end());
const std::unique_ptr<const PrefetchedSignedExchangeCache::Entry>&
script_exchange = script_it->second;
EXPECT_EQ(sxg_script_url, script_exchange->outer_url());
EXPECT_EQ(inner_url_script_url, script_exchange->inner_url());
EXPECT_EQ(script_header_integrity, *script_exchange->header_integrity());
expected_body_size_total += script_sxg_content.size();
expected_headers_size_total +=
script_exchange->outer_response()->headers->raw_headers().size() +
script_exchange->inner_response()->headers->raw_headers().size();
} else {
DCHECK(base::FeatureList::IsEnabled(
features::kSignedExchangePrefetchCacheForNavigations));
EXPECT_EQ(1u, cached_exchanges.size());
}
const auto page_it = cached_exchanges.find(sxg_page_url);
ASSERT_TRUE(page_it != cached_exchanges.end());
const std::unique_ptr<const PrefetchedSignedExchangeCache::Entry>&
script_exchange = script_it->second;
EXPECT_EQ(sxg_script_url, script_exchange->outer_url());
EXPECT_EQ(inner_url_script_url, script_exchange->inner_url());
EXPECT_EQ(script_header_integrity, *script_exchange->header_integrity());
expected_body_size_total += script_sxg_content.size();
page_exchange = page_it->second;
EXPECT_EQ(sxg_page_url, page_exchange->outer_url());
EXPECT_EQ(inner_url_page_url, page_exchange->inner_url());
EXPECT_EQ(page_header_integrity, *page_exchange->header_integrity());
expected_body_size_total += page_sxg_content.size();
expected_headers_size_total +=
script_exchange->outer_response()->headers->raw_headers().size() +
script_exchange->inner_response()->headers->raw_headers().size();
page_exchange->outer_response()->headers->raw_headers().size() +
page_exchange->inner_response()->headers->raw_headers().size();
} else {
EXPECT_EQ(1u, cached_exchanges.size());
EXPECT_EQ(0u, cached_exchanges.size());
}
const auto page_it = cached_exchanges.find(sxg_page_url);
ASSERT_TRUE(page_it != cached_exchanges.end());
const std::unique_ptr<const PrefetchedSignedExchangeCache::Entry>&
page_exchange = page_it->second;
EXPECT_EQ(sxg_page_url, page_exchange->outer_url());
EXPECT_EQ(inner_url_page_url, page_exchange->inner_url());
EXPECT_EQ(page_header_integrity, *page_exchange->header_integrity());
expected_body_size_total += page_sxg_content.size();
expected_headers_size_total +=
page_exchange->outer_response()->headers->raw_headers().size() +
page_exchange->inner_response()->headers->raw_headers().size();
base::HistogramTester histograms;
if (base::FeatureList::IsEnabled(
......@@ -789,34 +859,55 @@ IN_PROC_BROWSER_TEST_P(SignedExchangePrefetchBrowserTest,
// The content is loaded from PrefetchedSignedExchangeCache. And the script
// is also loaded from PrefetchedSignedExchangeCache.
NavigateToURLAndWaitTitle(sxg_page_url, "done");
EXPECT_EQ(1, script_sxg_request_counter->GetRequestCount());
EXPECT_EQ(0, script_request_counter->GetRequestCount());
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.Count", 2, 1);
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.BodySize",
page_sxg_content.size(), 1);
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.BodySize",
script_sxg_content.size(), 1);
} else {
// Subsequent navigation to the target URL wouldn't hit the network for
// the target URL. The target content should still be read correctly.
// The content is loaded from PrefetchedSignedExchangeCache. But the script
// is loaded from the server.
// The content is loaded from PrefetchedSignedExchangeCache when
// SignedExchangePrefetchCacheForNavigations is enabled, otherwise from
// HTTPCache. But the script is loaded from the server.
NavigateToURLAndWaitTitle(sxg_page_url, "from server");
EXPECT_EQ(0, script_sxg_request_counter->GetRequestCount());
EXPECT_EQ(1, script_request_counter->GetRequestCount());
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.Count", 1, 1);
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.BodySize",
page_sxg_content.size(), 1);
}
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.BodySizeTotal",
expected_body_size_total, 1);
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.HeadersSizeTotal",
expected_headers_size_total, 1);
EXPECT_EQ(1, page_sxg_request_counter->GetRequestCount());
if (IsSignedExchangePrefetchCacheEnabled()) {
if (base::FeatureList::IsEnabled(
features::kSignedExchangeSubresourcePrefetch)) {
EXPECT_EQ(1, script_sxg_request_counter->GetRequestCount());
EXPECT_EQ(0, script_request_counter->GetRequestCount());
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.Count", 2, 1);
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.BodySize",
page_sxg_content.size(), 1);
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.BodySize",
script_sxg_content.size(), 1);
} else {
DCHECK(base::FeatureList::IsEnabled(
features::kSignedExchangePrefetchCacheForNavigations));
EXPECT_EQ(0, script_sxg_request_counter->GetRequestCount());
EXPECT_EQ(1, script_request_counter->GetRequestCount());
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.Count", 1, 1);
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.BodySize",
page_sxg_content.size(), 1);
}
histograms.ExpectBucketCount("PrefetchedSignedExchangeCache.BodySizeTotal",
expected_body_size_total, 1);
histograms.ExpectBucketCount(
"PrefetchedSignedExchangeCache.HeadersSizeTotal",
expected_headers_size_total, 1);
} else {
histograms.ExpectTotalCount("PrefetchedSignedExchangeCache.Count", 0);
histograms.ExpectTotalCount("PrefetchedSignedExchangeCache.BodySize", 0);
histograms.ExpectTotalCount("PrefetchedSignedExchangeCache.BodySizeTotal",
0);
histograms.ExpectTotalCount(
"PrefetchedSignedExchangeCache.HeadersSizeTotal", 0);
}
}
INSTANTIATE_TEST_SUITE_P(SignedExchangePrefetchBrowserTest,
SignedExchangePrefetchBrowserTest,
::testing::Combine(::testing::Bool(),
::testing::Bool(),
::testing::Bool()));
class SignedExchangeSubresourcePrefetchBrowserTest
......
......@@ -498,6 +498,9 @@ void SetIndividualRuntimeFeatures(
if (base::FeatureList::IsEnabled(features::kUserAgentClientHint))
WebRuntimeFeatures::EnableFeatureFromString("UserAgentClientHint", true);
WebRuntimeFeatures::EnableSignedExchangePrefetchCacheForNavigations(
base::FeatureList::IsEnabled(
features::kSignedExchangePrefetchCacheForNavigations));
WebRuntimeFeatures::EnableSignedExchangeSubresourcePrefetch(
base::FeatureList::IsEnabled(
features::kSignedExchangeSubresourcePrefetch));
......
......@@ -822,6 +822,11 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
static_cast<int>(ResourceType::kPluginResource)) {
resource_request->corb_excluded = true;
}
if (request.IsSignedExchangePrefetchCacheEnabled()) {
DCHECK_EQ(static_cast<int>(ResourceType::kPrefetch),
resource_request->resource_type);
resource_request->is_signed_exchange_prefetch_cache_enabled = true;
}
auto throttles = extra_data->TakeURLLoaderThrottles();
// The frame request blocker is only for a frame's subresources.
......
......@@ -73,7 +73,9 @@ bool ResourceRequest::EqualsForTesting(const ResourceRequest& request) const {
custom_proxy_use_alternate_proxy_list ==
request.custom_proxy_use_alternate_proxy_list &&
fetch_window_id == request.fetch_window_id &&
devtools_request_id == request.devtools_request_id;
devtools_request_id == request.devtools_request_id &&
is_signed_exchange_prefetch_cache_enabled ==
request.is_signed_exchange_prefetch_cache_enabled;
}
bool ResourceRequest::SendsCookies() const {
......
......@@ -95,6 +95,7 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) ResourceRequest {
bool custom_proxy_use_alternate_proxy_list = false;
base::Optional<base::UnguessableToken> fetch_window_id;
base::Optional<std::string> devtools_request_id;
bool is_signed_exchange_prefetch_cache_enabled = false;
};
} // namespace network
......
......@@ -215,6 +215,8 @@ bool StructTraits<
out->is_revalidating = data.is_revalidating();
out->should_also_use_factory_bound_origin_for_cors =
data.should_also_use_factory_bound_origin_for_cors();
out->is_signed_exchange_prefetch_cache_enabled =
data.is_signed_exchange_prefetch_cache_enabled();
return true;
}
......
......@@ -237,6 +237,10 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE)
const network::ResourceRequest& request) {
return request.devtools_request_id;
}
static bool is_signed_exchange_prefetch_cache_enabled(
const network::ResourceRequest& request) {
return request.is_signed_exchange_prefetch_cache_enabled;
}
static bool Read(network::mojom::URLRequestDataView data,
network::ResourceRequest* out);
......
......@@ -358,6 +358,12 @@ struct URLRequest {
// renderer process and is only present when DevTools is enabled in the
// renderer.
string? devtools_request_id;
// True for prefetch requests when SignedExchangePrefetchCacheForNavigations
// feature is enabled by flags or SignedExchangeSubresourcePrefetch feature is
// enabled by flags, or OriginTrial. TODO(horo): Remove this when these
// features are enabled by default.
bool is_signed_exchange_prefetch_cache_enabled;
};
// URLRequestBody represents body (i.e. upload data) of a HTTP request.
......
......@@ -233,6 +233,8 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableShadowDOMV0(bool);
BLINK_PLATFORM_EXPORT static void EnableCustomElementsV0(bool);
BLINK_PLATFORM_EXPORT static void EnableHTMLImports(bool);
BLINK_PLATFORM_EXPORT static void
EnableSignedExchangePrefetchCacheForNavigations(bool);
BLINK_PLATFORM_EXPORT static void EnableSignedExchangeSubresourcePrefetch(
bool);
BLINK_PLATFORM_EXPORT static void EnableIdleDetection(bool);
......
......@@ -388,6 +388,8 @@ class WebURLRequest {
BLINK_PLATFORM_EXPORT bool IsFromOriginDirtyStyleSheet() const;
BLINK_PLATFORM_EXPORT bool IsSignedExchangePrefetchCacheEnabled() const;
#if INSIDE_BLINK
BLINK_PLATFORM_EXPORT ResourceRequest& ToMutableResourceRequest();
BLINK_PLATFORM_EXPORT const ResourceRequest& ToResourceRequest() const;
......
......@@ -480,6 +480,11 @@ Resource* PreloadHelper::PrefetchIfNeeded(const LinkLoadParameters& params,
link_fetch_params.SetCrossOriginAccessControl(
document.GetSecurityOrigin(), params.cross_origin);
}
link_fetch_params.SetSignedExchangePrefetchCacheEnabled(
RuntimeEnabledFeatures::
SignedExchangePrefetchCacheForNavigationsEnabled() ||
RuntimeEnabledFeatures::SignedExchangeSubresourcePrefetchEnabled(
&document));
return LinkFetchResource::Fetch(ResourceType::kLinkPrefetch,
link_fetch_params, document.Fetcher());
}
......
......@@ -653,6 +653,12 @@ void WebRuntimeFeatures::EnableHTMLImports(bool enable) {
RuntimeEnabledFeatures::SetHTMLImportsOnlyChromeEnabled(enable);
}
void WebRuntimeFeatures::EnableSignedExchangePrefetchCacheForNavigations(
bool enable) {
RuntimeEnabledFeatures::SetSignedExchangePrefetchCacheForNavigationsEnabled(
enable);
}
void WebRuntimeFeatures::EnableSignedExchangeSubresourcePrefetch(bool enable) {
RuntimeEnabledFeatures::SetSignedExchangeSubresourcePrefetchEnabled(enable);
}
......
......@@ -500,6 +500,10 @@ bool WebURLRequest::IsFromOriginDirtyStyleSheet() const {
return resource_request_->IsFromOriginDirtyStyleSheet();
}
bool WebURLRequest::IsSignedExchangePrefetchCacheEnabled() const {
return resource_request_->IsSignedExchangePrefetchCacheEnabled();
}
WebURLRequest::WebURLRequest(ResourceRequest& r) : resource_request_(&r) {}
} // namespace blink
......@@ -201,6 +201,10 @@ class PLATFORM_EXPORT FetchParameters {
is_from_origin_dirty_style_sheet_ = dirty;
}
void SetSignedExchangePrefetchCacheEnabled(bool enabled) {
resource_request_.SetSignedExchangePrefetchCacheEnabled(enabled);
}
private:
ResourceRequest resource_request_;
// |decoder_options_|'s ContentType is set to |kPlainTextContent| in
......
......@@ -131,6 +131,8 @@ std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest(
request->SetUkmSourceId(GetUkmSourceId());
request->SetInspectorId(InspectorId());
request->SetFromOriginDirtyStyleSheet(IsFromOriginDirtyStyleSheet());
request->SetSignedExchangePrefetchCacheEnabled(
IsSignedExchangePrefetchCacheEnabled());
return request;
}
......
......@@ -504,6 +504,13 @@ class PLATFORM_EXPORT ResourceRequest final {
is_from_origin_dirty_style_sheet_ = dirty;
}
bool IsSignedExchangePrefetchCacheEnabled() const {
return is_signed_exchange_prefetch_cache_enabled_;
}
void SetSignedExchangePrefetchCacheEnabled(bool enabled) {
is_signed_exchange_prefetch_cache_enabled_ = enabled;
}
private:
using SharableExtraData =
base::RefCountedData<std::unique_ptr<WebURLRequest::ExtraData>>;
......@@ -593,6 +600,8 @@ class PLATFORM_EXPORT ResourceRequest final {
uint64_t inspector_id_ = 0;
bool is_from_origin_dirty_style_sheet_ = false;
bool is_signed_exchange_prefetch_cache_enabled_ = false;
};
} // namespace blink
......
......@@ -1434,6 +1434,10 @@
origin_trial_feature_name: "SignatureBasedIntegrity",
status: "experimental",
},
{
name: "SignedExchangePrefetchCacheForNavigations",
status: "experimental",
},
{
name: "SignedExchangeSubresourcePrefetch",
origin_trial_feature_name: "SignedExchangeSubresourcePrefetchM77",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment