Commit b184f4b6 authored by Maks Orlovich's avatar Maks Orlovich Committed by Commit Bot

[client hints] Refactor the "should it be sent" renderer code

This is mostly to get clarity on what this should be doing before
I change how parsing of client hints and communication from browser
works, though it's not really dependent.

Change-Id: I04e8b403a6aeae544d2616688a39c65c0e60b5bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2083449
Commit-Queue: Maksim Orlovich <morlovich@chromium.org>
Reviewed-by: default avatarYoav Weiss <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751068}
parent 0eb24038
...@@ -539,20 +539,16 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -539,20 +539,16 @@ void FrameFetchContext::AddClientHintsIfNecessary(
.GetSecurityContext() .GetSecurityContext()
.GetFeaturePolicy(); .GetFeaturePolicy();
} }
url::Origin resource_origin =
SecurityOrigin::Create(request.Url())->ToUrlOrigin();
// Sec-CH-UA is special: we always send the header to all origins that are // Sec-CH-UA is special: we always send the header to all origins that are
// eligible for client hints (e.g. secure transport, JavaScript enabled). We // eligible for client hints (e.g. secure transport, JavaScript enabled).
// alter the header's value based on whether or not the site has opted into
// additional detail.
// //
// https://github.com/WICG/ua-client-hints // https://github.com/WICG/ua-client-hints
blink::UserAgentMetadata ua = GetUserAgentMetadata(); blink::UserAgentMetadata ua = GetUserAgentMetadata();
if (RuntimeEnabledFeatures::UserAgentClientHintEnabled()) { if (RuntimeEnabledFeatures::UserAgentClientHintEnabled()) {
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kUA)], mojom::blink::WebClientHintsType::kUA)],
AddBrandVersionQuotes(ua.brand, ua.major_version)); AddBrandVersionQuotes(ua.brand, ua.major_version));
// We also send Sec-CH-UA-Mobile to all hints. It is a one-bit header // We also send Sec-CH-UA-Mobile to all hints. It is a one-bit header
...@@ -561,7 +557,7 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -561,7 +557,7 @@ void FrameFetchContext::AddClientHintsIfNecessary(
// https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html#boolean // https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html#boolean
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kUAMobile)], mojom::blink::WebClientHintsType::kUAMobile)],
ua.mobile ? "?1" : "?0"); ua.mobile ? "?1" : "?0");
} }
...@@ -569,6 +565,8 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -569,6 +565,8 @@ void FrameFetchContext::AddClientHintsIfNecessary(
if (!policy) if (!policy)
return; return;
url::Origin resource_origin =
SecurityOrigin::Create(request.Url())->ToUrlOrigin();
bool is_1p_origin = IsFirstPartyOrigin(request.Url()); bool is_1p_origin = IsFirstPartyOrigin(request.Url());
if (!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && if (!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
...@@ -586,12 +584,11 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -586,12 +584,11 @@ void FrameFetchContext::AddClientHintsIfNecessary(
// The next 4 hints should be enabled if we're allowing legacy hints to third // The next 4 hints should be enabled if we're allowing legacy hints to third
// parties, or if FeaturePolicy delegation says they are allowed. // parties, or if FeaturePolicy delegation says they are allowed.
if ((base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) || if (ShouldSendClientHint(
policy->IsFeatureEnabledForOrigin( ClientHintsMode::kLegacy, policy, resource_origin, is_1p_origin,
mojom::blink::FeaturePolicyFeature::kClientHintDeviceMemory, mojom::blink::WebClientHintsType::kDeviceMemory,
resource_origin)) && mojom::blink::FeaturePolicyFeature::kClientHintDeviceMemory,
ShouldSendClientHint(mojom::WebClientHintsType::kDeviceMemory, hints_preferences, enabled_hints)) {
hints_preferences, enabled_hints)) {
request.SetHttpHeaderField( request.SetHttpHeaderField(
"Device-Memory", "Device-Memory",
AtomicString(String::Number( AtomicString(String::Number(
...@@ -599,32 +596,28 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -599,32 +596,28 @@ void FrameFetchContext::AddClientHintsIfNecessary(
} }
float dpr = GetDevicePixelRatio(); float dpr = GetDevicePixelRatio();
if ((base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) || if (ShouldSendClientHint(ClientHintsMode::kLegacy, policy, resource_origin,
policy->IsFeatureEnabledForOrigin( is_1p_origin, mojom::blink::WebClientHintsType::kDpr,
mojom::blink::FeaturePolicyFeature::kClientHintDPR, mojom::blink::FeaturePolicyFeature::kClientHintDPR,
resource_origin)) && hints_preferences, enabled_hints)) {
ShouldSendClientHint(mojom::WebClientHintsType::kDpr, hints_preferences,
enabled_hints)) {
request.SetHttpHeaderField("DPR", AtomicString(String::Number(dpr))); request.SetHttpHeaderField("DPR", AtomicString(String::Number(dpr)));
} }
if ((base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) || if (ShouldSendClientHint(
policy->IsFeatureEnabledForOrigin( ClientHintsMode::kLegacy, policy, resource_origin, is_1p_origin,
mojom::blink::FeaturePolicyFeature::kClientHintViewportWidth, mojom::blink::WebClientHintsType::kViewportWidth,
resource_origin)) && mojom::blink::FeaturePolicyFeature::kClientHintViewportWidth,
ShouldSendClientHint(mojom::WebClientHintsType::kViewportWidth, hints_preferences, enabled_hints) &&
hints_preferences, enabled_hints) &&
!GetResourceFetcherProperties().IsDetached() && GetFrame()->View()) { !GetResourceFetcherProperties().IsDetached() && GetFrame()->View()) {
request.SetHttpHeaderField( request.SetHttpHeaderField(
"Viewport-Width", "Viewport-Width",
AtomicString(String::Number(GetFrame()->View()->ViewportWidth()))); AtomicString(String::Number(GetFrame()->View()->ViewportWidth())));
} }
if ((base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty) || if (ShouldSendClientHint(ClientHintsMode::kLegacy, policy, resource_origin,
policy->IsFeatureEnabledForOrigin( is_1p_origin,
mojom::blink::FeaturePolicyFeature::kClientHintWidth, mojom::blink::WebClientHintsType::kResourceWidth,
resource_origin)) && mojom::blink::FeaturePolicyFeature::kClientHintWidth,
ShouldSendClientHint(mojom::WebClientHintsType::kResourceWidth,
hints_preferences, enabled_hints)) { hints_preferences, enabled_hints)) {
if (resource_width.is_set) { if (resource_width.is_set) {
float physical_width = resource_width.width * dpr; float physical_width = resource_width.width * dpr;
...@@ -633,29 +626,10 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -633,29 +626,10 @@ void FrameFetchContext::AddClientHintsIfNecessary(
} }
} }
// TODO(iclelland): If feature policy control over client hints ships, remove if (ShouldSendClientHint(ClientHintsMode::kStandard, policy, resource_origin,
// the runtime flag check and the 1p origin requirement for the remaining is_1p_origin, mojom::blink::WebClientHintsType::kRtt,
// hints. Currently, even when the kAllowClientHintsToThirdParty feature is mojom::blink::FeaturePolicyFeature::kClientHintRTT,
// (and the runtime flag is *not* set,) these hints are only sent for first- hints_preferences, enabled_hints)) {
// party requests. With feature policy control, these can be sent to third
// parties as well, if correctly delegated.
// Note that if both the kAllowClientHintsToThirdParty feature and the runtime
// flag are disabled, this code will not be reached.
// True if this is a first-party resource request, and feature policy for
// client hints is *not* in use.
bool can_always_send_hints =
is_1p_origin &&
!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled();
if ((can_always_send_hints ||
(RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
policy->IsFeatureEnabledForOrigin(
mojom::blink::FeaturePolicyFeature::kClientHintRTT,
resource_origin))) &&
ShouldSendClientHint(mojom::WebClientHintsType::kRtt, hints_preferences,
enabled_hints)) {
base::Optional<base::TimeDelta> http_rtt = base::Optional<base::TimeDelta> http_rtt =
GetNetworkStateNotifier().GetWebHoldbackHttpRtt(); GetNetworkStateNotifier().GetWebHoldbackHttpRtt();
if (!http_rtt) { if (!http_rtt) {
...@@ -666,17 +640,15 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -666,17 +640,15 @@ void FrameFetchContext::AddClientHintsIfNecessary(
GetNetworkStateNotifier().RoundRtt(request.Url().Host(), http_rtt); GetNetworkStateNotifier().RoundRtt(request.Url().Host(), http_rtt);
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kRtt)], mojom::blink::WebClientHintsType::kRtt)],
AtomicString(String::Number(rtt))); AtomicString(String::Number(rtt)));
} }
if ((can_always_send_hints || if (ShouldSendClientHint(
(RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
policy->IsFeatureEnabledForOrigin( mojom::blink::WebClientHintsType::kDownlink,
mojom::blink::FeaturePolicyFeature::kClientHintDownlink, mojom::blink::FeaturePolicyFeature::kClientHintDownlink,
resource_origin))) && hints_preferences, enabled_hints)) {
ShouldSendClientHint(mojom::WebClientHintsType::kDownlink,
hints_preferences, enabled_hints)) {
base::Optional<double> throughput_mbps = base::Optional<double> throughput_mbps =
GetNetworkStateNotifier().GetWebHoldbackDownlinkThroughputMbps(); GetNetworkStateNotifier().GetWebHoldbackDownlinkThroughputMbps();
if (!throughput_mbps) { if (!throughput_mbps) {
...@@ -687,17 +659,14 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -687,17 +659,14 @@ void FrameFetchContext::AddClientHintsIfNecessary(
throughput_mbps); throughput_mbps);
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kDownlink)], mojom::blink::WebClientHintsType::kDownlink)],
AtomicString(String::Number(mbps))); AtomicString(String::Number(mbps)));
} }
if ((can_always_send_hints || if (ShouldSendClientHint(ClientHintsMode::kStandard, policy, resource_origin,
(RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && is_1p_origin, mojom::blink::WebClientHintsType::kEct,
policy->IsFeatureEnabledForOrigin( mojom::blink::FeaturePolicyFeature::kClientHintECT,
mojom::blink::FeaturePolicyFeature::kClientHintECT, hints_preferences, enabled_hints)) {
resource_origin))) &&
ShouldSendClientHint(mojom::WebClientHintsType::kEct, hints_preferences,
enabled_hints)) {
base::Optional<WebEffectiveConnectionType> holdback_ect = base::Optional<WebEffectiveConnectionType> holdback_ect =
GetNetworkStateNotifier().GetWebHoldbackEffectiveType(); GetNetworkStateNotifier().GetWebHoldbackEffectiveType();
if (!holdback_ect) if (!holdback_ect)
...@@ -705,74 +674,63 @@ void FrameFetchContext::AddClientHintsIfNecessary( ...@@ -705,74 +674,63 @@ void FrameFetchContext::AddClientHintsIfNecessary(
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kEct)], mojom::blink::WebClientHintsType::kEct)],
AtomicString(NetworkStateNotifier::EffectiveConnectionTypeToString( AtomicString(NetworkStateNotifier::EffectiveConnectionTypeToString(
holdback_ect.value()))); holdback_ect.value())));
} }
if ((can_always_send_hints || if (ShouldSendClientHint(ClientHintsMode::kStandard, policy, resource_origin,
(RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && is_1p_origin,
policy->IsFeatureEnabledForOrigin( mojom::blink::WebClientHintsType::kLang,
mojom::blink::FeaturePolicyFeature::kClientHintLang, mojom::blink::FeaturePolicyFeature::kClientHintLang,
resource_origin))) && hints_preferences, enabled_hints)) {
ShouldSendClientHint(mojom::WebClientHintsType::kLang, hints_preferences,
enabled_hints)) {
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kLang)], mojom::blink::WebClientHintsType::kLang)],
GetFrame() GetFrame()
->DomWindow() ->DomWindow()
->navigator() ->navigator()
->SerializeLanguagesForClientHintHeader()); ->SerializeLanguagesForClientHintHeader());
} }
if ((can_always_send_hints || if (ShouldSendClientHint(
(RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
policy->IsFeatureEnabledForOrigin( mojom::blink::WebClientHintsType::kUAArch,
mojom::blink::FeaturePolicyFeature::kClientHintUAArch, mojom::blink::FeaturePolicyFeature::kClientHintUAArch,
resource_origin))) && hints_preferences, enabled_hints)) {
ShouldSendClientHint(mojom::WebClientHintsType::kUAArch,
hints_preferences, enabled_hints)) {
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kUAArch)], mojom::blink::WebClientHintsType::kUAArch)],
AddQuotes(ua.architecture)); AddQuotes(ua.architecture));
} }
if ((can_always_send_hints || if (ShouldSendClientHint(
(RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
policy->IsFeatureEnabledForOrigin( mojom::blink::WebClientHintsType::kUAPlatform,
mojom::blink::FeaturePolicyFeature::kClientHintUAPlatform, mojom::blink::FeaturePolicyFeature::kClientHintUAPlatform,
resource_origin))) && hints_preferences, enabled_hints)) {
ShouldSendClientHint(mojom::WebClientHintsType::kUAPlatform,
hints_preferences, enabled_hints)) {
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kUAPlatform)], mojom::blink::WebClientHintsType::kUAPlatform)],
AddBrandVersionQuotes(ua.platform, ua.platform_version)); AddBrandVersionQuotes(ua.platform, ua.platform_version));
} }
if ((can_always_send_hints || if (ShouldSendClientHint(
(RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
policy->IsFeatureEnabledForOrigin( mojom::blink::WebClientHintsType::kUAModel,
mojom::blink::FeaturePolicyFeature::kClientHintUAModel, mojom::blink::FeaturePolicyFeature::kClientHintUAModel,
resource_origin))) && hints_preferences, enabled_hints)) {
ShouldSendClientHint(mojom::WebClientHintsType::kUAModel,
hints_preferences, enabled_hints)) {
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::WebClientHintsType::kUAModel)], mojom::blink::WebClientHintsType::kUAModel)],
AddQuotes(ua.model)); AddQuotes(ua.model));
} }
if ((can_always_send_hints || if (ShouldSendClientHint(
(RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() && ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
policy->IsFeatureEnabledForOrigin( mojom::blink::WebClientHintsType::kUAFullVersion,
mojom::blink::FeaturePolicyFeature::kClientHintUAFullVersion, mojom::blink::FeaturePolicyFeature::kClientHintUAFullVersion,
resource_origin))) && hints_preferences, enabled_hints)) {
ShouldSendClientHint(mojom::blink::WebClientHintsType::kUAFullVersion,
hints_preferences, enabled_hints)) {
request.SetHttpHeaderField( request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>( blink::kClientHintsHeaderMapping[static_cast<size_t>(
mojom::blink::WebClientHintsType::kUAFullVersion)], mojom::blink::WebClientHintsType::kUAFullVersion)],
...@@ -1025,9 +983,33 @@ float FrameFetchContext::GetDevicePixelRatio() const { ...@@ -1025,9 +983,33 @@ float FrameFetchContext::GetDevicePixelRatio() const {
} }
bool FrameFetchContext::ShouldSendClientHint( bool FrameFetchContext::ShouldSendClientHint(
mojom::WebClientHintsType type, ClientHintsMode mode,
const FeaturePolicy* policy,
const url::Origin& resource_origin,
bool is_1p_origin,
mojom::blink::WebClientHintsType type,
mojom::blink::FeaturePolicyFeature feature_policy_feature,
const ClientHintsPreferences& hints_preferences, const ClientHintsPreferences& hints_preferences,
const WebEnabledClientHints& enabled_hints) const { const WebEnabledClientHints& enabled_hints) const {
bool origin_ok;
if (mode == ClientHintsMode::kLegacy &&
base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty)) {
origin_ok = true;
} else if (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled()) {
origin_ok = (policy && policy->IsFeatureEnabledForOrigin(
feature_policy_feature, resource_origin));
} else {
origin_ok = is_1p_origin;
}
if (!origin_ok)
return false;
// |hints_preferences| is used only in case of the preload scanner;
// GetClientHintsPreferences() has things parsed for this document
// normally (whether via headers of http-equiv), and |enabled_hints| are
// previously persistent settings.
return GetClientHintsPreferences().ShouldSend(type) || return GetClientHintsPreferences().ShouldSend(type) ||
hints_preferences.ShouldSend(type) || enabled_hints.IsEnabled(type); hints_preferences.ShouldSend(type) || enabled_hints.IsEnabled(type);
} }
......
...@@ -35,6 +35,7 @@ n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ...@@ -35,6 +35,7 @@ n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink-forward.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/web_client_hints/web_client_hints_types.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/loader/base_fetch_context.h" #include "third_party/blink/renderer/core/loader/base_fetch_context.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
...@@ -168,7 +169,14 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext { ...@@ -168,7 +169,14 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
UserAgentMetadata GetUserAgentMetadata() const; UserAgentMetadata GetUserAgentMetadata() const;
const ClientHintsPreferences GetClientHintsPreferences() const; const ClientHintsPreferences GetClientHintsPreferences() const;
float GetDevicePixelRatio() const; float GetDevicePixelRatio() const;
bool ShouldSendClientHint(mojom::WebClientHintsType,
enum class ClientHintsMode { kLegacy, kStandard };
bool ShouldSendClientHint(ClientHintsMode mode,
const FeaturePolicy*,
const url::Origin& resource_origin,
bool is_1p_origin,
mojom::blink::WebClientHintsType,
mojom::blink::FeaturePolicyFeature,
const ClientHintsPreferences&, const ClientHintsPreferences&,
const WebEnabledClientHints&) const; const WebEnabledClientHints&) const;
void SetFirstPartyCookie(ResourceRequest&); void SetFirstPartyCookie(ResourceRequest&);
......
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