Skip to content

Send kUAModel and kUAPlatformVersion CHs when requested. (uplift to 1.51.x) #18263

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions browser/about_flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,14 @@
kOsAll, \
FEATURE_VALUE_TYPE(blink::features::kAllowCertainClientHints), \
}, \
{ \
"clamp-platform-version-client-hint", \
"Clamp platform version client hint", \
"Clamps the patch field of the platform version client hint", \
kOsAll, \
FEATURE_VALUE_TYPE( \
blink::features::kClampPlatformVersionClientHint), \
}, \
{ \
"brave-ntp-branded-wallpaper-demo", \
"New Tab Page Demo Branded Wallpaper", \
Expand Down
207 changes: 180 additions & 27 deletions browser/test/disabled_features/disable_client_hints_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <functional>
#include <set>
#include <vector>

#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/test/scoped_feature_list.h"
#include "brave/components/constants/brave_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
Expand All @@ -27,12 +30,15 @@
#include "third_party/blink/public/common/features.h"

namespace {
const char kNoClientHintsHeaders[] = "/simple.html";
const char kClientHints[] = "/ch.html";
const char kClientHintsDelegationMerge[] = "/ch_delegation_merge.html";
const char KClientHintsMetaHTTPEquivAcceptCH[] =
"/ch-meta-http-equiv-accept-ch.html";
const char KClientHintsMetaNameAcceptCH[] = "/ch-meta-name-accept-ch.html";

const char kPlatformVersionClientHintPatchValue[] = "x";

const std::reference_wrapper<const base::Feature> kTestFeatures[] = {
// Individual hints features
blink::features::kClientHintsDeviceMemory,
Expand Down Expand Up @@ -69,6 +75,7 @@ class ClientHintsBrowserTest

EXPECT_TRUE(https_server_.Start());

no_client_hints_headers_url_ = https_server_.GetURL(kNoClientHintsHeaders);
client_hints_url_ = https_server_.GetURL(kClientHints);
client_hints_delegation_merge_url_ =
https_server_.GetURL(kClientHintsDelegationMerge);
Expand All @@ -89,25 +96,33 @@ class ClientHintsBrowserTest

void SetUp() override {
// Test that even with CH features enabled, there is no header.
std::vector<base::test::FeatureRef> enabled_features;
std::vector<base::test::FeatureRefAndParams> enabled_features;
std::vector<base::test::FeatureRef> disabled_features;
for (const auto& feature : kTestFeatures) {
if (IsClientHintHeaderEnabled()) {
enabled_features.push_back(feature.get());
enabled_features.emplace_back(feature.get(), base::FieldTrialParams());
} else {
disabled_features.push_back(feature.get());
}
}

if (IsBraveClientHintFeatureEnabled()) {
enabled_features.push_back(blink::features::kAllowCertainClientHints);
enabled_features.emplace_back(blink::features::kAllowCertainClientHints,
base::FieldTrialParams());
base::FieldTrialParams parameters;
parameters[blink::features::kClampPlatformVersionClientHintPatchValue
.name] = kPlatformVersionClientHintPatchValue;
enabled_features.emplace_back(
blink::features::kClampPlatformVersionClientHint, parameters);
} else {
disabled_features.push_back(blink::features::kAllowCertainClientHints);
}

scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features,
disabled_features);

if (IsBraveClientHintFeatureEnabled()) {
PopulateDefaultClientHints();
PopulateAllowedClientHints();
}
InProcessBrowserTest::SetUp();
Expand All @@ -120,6 +135,10 @@ class ClientHintsBrowserTest

void TearDownOnMainThread() override {}

const GURL& no_client_hints_headers_url() const {
return no_client_hints_headers_url_;
}

const GURL& client_hints_url() const { return client_hints_url_; }

const GURL& client_hints_delegation_merge_url() const {
Expand All @@ -133,73 +152,207 @@ class ClientHintsBrowserTest
return client_hints_meta_name_accept_ch_url_;
}

size_t count_client_hints_headers_seen() const {
return count_client_hints_headers_seen_;
size_t default_client_hints_headers_seen_count() const {
return default_client_hints_headers_seen_.size();
}

size_t allowed_client_hints_headers_seen_count() const {
return allowed_client_hints_headers_seen_.size();
}

size_t client_hints_headers_seen_count() const {
return unexpected_client_hints_headers_seen_.size();
}

std::string default_client_hints_headers_seen() const {
return base::JoinString(
std::vector<std::string>(default_client_hints_headers_seen_.begin(),
default_client_hints_headers_seen_.end()),
", ");
}

std::string allowed_client_hints_headers_seen() const {
return base::JoinString(
std::vector<std::string>(allowed_client_hints_headers_seen_.begin(),
allowed_client_hints_headers_seen_.end()),
", ");
}

void reset_client_hints_headers_seen_count() {
count_client_hints_headers_seen_ = 0;
std::string unexpected_client_hints_headers_seen() const {
return base::JoinString(unexpected_client_hints_headers_seen_, ", ");
}

std::string platform_version_client_hint_value() const {
return platform_version_client_hint_value_;
}

void reset_client_hints_headers_seen() {
default_client_hints_headers_seen_.clear();
allowed_client_hints_headers_seen_.clear();
unexpected_client_hints_headers_seen_.clear();
platform_version_client_hint_value_ = "";
}

bool VerifyPlatformVersionClientHintPatchValue() const {
return base::EndsWith(
platform_version_client_hint_value_,
base::StrCat({".", kPlatformVersionClientHintPatchValue, "\""}));
}

private:
void PopulateAllowedClientHints() {
void PopulateDefaultClientHints() {
const auto& hints_map = network::GetClientHintToNameMap();
allowed_hints_.push_back(
default_hints_.push_back(
hints_map.at(network::mojom::WebClientHintsType::kUA));
allowed_hints_.push_back(
default_hints_.push_back(
hints_map.at(network::mojom::WebClientHintsType::kUAMobile));
allowed_hints_.push_back(
default_hints_.push_back(
hints_map.at(network::mojom::WebClientHintsType::kUAPlatform));
}

void PopulateAllowedClientHints() {
const auto& hints_map = network::GetClientHintToNameMap();
allowed_hints_.push_back(
hints_map.at(network::mojom::WebClientHintsType::kUAModel));
allowed_hints_.push_back(
hints_map.at(network::mojom::WebClientHintsType::kUAPlatformVersion));
}

bool IsPlatformVersionClientHintHeader(const std::string& header) const {
return header ==
network::GetClientHintToNameMap().at(
network::mojom::WebClientHintsType::kUAPlatformVersion);
}

void StorePlatformVersionClientHintHeaderValue(
const net::test_server::HttpRequest::HeaderMap& headers) {
const auto& hints_map = network::GetClientHintToNameMap();
const std::string& platform_version_header_name =
hints_map.at(network::mojom::WebClientHintsType::kUAPlatformVersion);
platform_version_client_hint_value_ =
headers.at(platform_version_header_name);
}

void MonitorResourceRequest(const net::test_server::HttpRequest& request) {
for (const auto& elem : network::GetClientHintToNameMap()) {
const auto& header = elem.second;
if (base::Contains(request.headers, header)) {
if (IsBraveClientHintFeatureEnabled() &&
base::Contains(allowed_hints_, header)) {
continue;
if (IsBraveClientHintFeatureEnabled()) {
if (base::Contains(default_hints_, header)) {
default_client_hints_headers_seen_.insert(header);
continue;
} else if (base::Contains(allowed_hints_, header)) {
allowed_client_hints_headers_seen_.insert(header);
if (IsPlatformVersionClientHintHeader(header)) {
StorePlatformVersionClientHintHeaderValue(request.headers);
}
continue;
}
}
count_client_hints_headers_seen_++;
unexpected_client_hints_headers_seen_.push_back(header);
}
}
}

net::EmbeddedTestServer https_server_;

GURL no_client_hints_headers_url_;
GURL client_hints_delegation_merge_url_;
GURL client_hints_meta_http_equiv_accept_ch_url_;
GURL client_hints_meta_name_accept_ch_url_;
GURL client_hints_url_;
size_t count_client_hints_headers_seen_ = 0;

std::set<std::string> default_client_hints_headers_seen_;
std::set<std::string> allowed_client_hints_headers_seen_;
std::vector<std::string> unexpected_client_hints_headers_seen_;

std::vector<std::string> default_hints_;
std::vector<std::string> allowed_hints_;

std::string platform_version_client_hint_value_;

base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_P(ClientHintsBrowserTest, ClientHintsDisabled) {
IN_PROC_BROWSER_TEST_P(ClientHintsBrowserTest, CheckClientHints) {
for (const auto& feature : kTestFeatures) {
EXPECT_EQ(IsClientHintHeaderEnabled(),
base::FeatureList::IsEnabled(feature));
}
EXPECT_EQ(
IsBraveClientHintFeatureEnabled(),
base::FeatureList::IsEnabled(blink::features::kAllowCertainClientHints));

const size_t expected_default_client_hints_count =
IsClientHintHeaderEnabled() && IsBraveClientHintFeatureEnabled() ? 3u
: 0u;
const size_t expected_allowed_client_hints_count =
IsClientHintHeaderEnabled() && IsBraveClientHintFeatureEnabled() ? 2u
: 0u;

ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), no_client_hints_headers_url()));
EXPECT_EQ(expected_default_client_hints_count,
default_client_hints_headers_seen_count())
<< "Default headers seen: " << default_client_hints_headers_seen();
EXPECT_EQ(0u, allowed_client_hints_headers_seen_count())
<< "Allowed headers seen: " << allowed_client_hints_headers_seen();
EXPECT_EQ(0u, client_hints_headers_seen_count())
<< "Unexpected headers: " << unexpected_client_hints_headers_seen();

reset_client_hints_headers_seen();
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), client_hints_url()));
EXPECT_EQ(0u, count_client_hints_headers_seen());
EXPECT_EQ(expected_default_client_hints_count,
default_client_hints_headers_seen_count())
<< "Default headers seen: " << default_client_hints_headers_seen();
EXPECT_EQ(expected_allowed_client_hints_count,
allowed_client_hints_headers_seen_count())
<< "Allowed headers seen: " << allowed_client_hints_headers_seen();
EXPECT_EQ(0u, client_hints_headers_seen_count())
<< "Unexpected headers: " << unexpected_client_hints_headers_seen();
if (IsClientHintHeaderEnabled() && IsBraveClientHintFeatureEnabled()) {
EXPECT_TRUE(VerifyPlatformVersionClientHintPatchValue())
<< "Expected the patch field value to be: '"
<< kPlatformVersionClientHintPatchValue << "'. "
<< "Actual platform version value: "
<< platform_version_client_hint_value();
}

reset_client_hints_headers_seen_count();
reset_client_hints_headers_seen();
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), client_hints_meta_http_equiv_accept_ch_url()));
EXPECT_EQ(0u, count_client_hints_headers_seen());

reset_client_hints_headers_seen_count();
EXPECT_EQ(expected_default_client_hints_count,
default_client_hints_headers_seen_count())
<< "Default headers seen: " << default_client_hints_headers_seen();
EXPECT_EQ(expected_allowed_client_hints_count,
allowed_client_hints_headers_seen_count())
<< "Allowed headers seen: " << allowed_client_hints_headers_seen();
EXPECT_EQ(0u, client_hints_headers_seen_count())
<< "Unexpected headers: " << unexpected_client_hints_headers_seen();

reset_client_hints_headers_seen();
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), client_hints_meta_name_accept_ch_url()));
EXPECT_EQ(0u, count_client_hints_headers_seen());

reset_client_hints_headers_seen_count();
EXPECT_EQ(expected_default_client_hints_count,
default_client_hints_headers_seen_count())
<< "Default headers seen: " << default_client_hints_headers_seen();
EXPECT_EQ(expected_allowed_client_hints_count,
allowed_client_hints_headers_seen_count())
<< "Allowed headers seen: " << allowed_client_hints_headers_seen();
EXPECT_EQ(0u, client_hints_headers_seen_count())
<< "Unexpected headers: " << unexpected_client_hints_headers_seen();

reset_client_hints_headers_seen();
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), client_hints_delegation_merge_url()));
EXPECT_EQ(0u, count_client_hints_headers_seen());
EXPECT_EQ(expected_default_client_hints_count,
default_client_hints_headers_seen_count())
<< "Default headers seen: " << default_client_hints_headers_seen();
EXPECT_EQ(expected_allowed_client_hints_count,
allowed_client_hints_headers_seen_count())
<< "Allowed headers seen: " << allowed_client_hints_headers_seen();
EXPECT_EQ(0u, client_hints_headers_seen_count())
<< "Unexpected headers: " << unexpected_client_hints_headers_seen();
}

INSTANTIATE_TEST_SUITE_P(
Expand Down
36 changes: 36 additions & 0 deletions chromium_src/components/embedder_support/user_agent_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "components/embedder_support/user_agent_utils.h"

#include "base/check_op.h"
#include "base/strings/stringprintf.h"
#include "base/version.h"
#include "third_party/blink/public/common/features.h"

namespace {

constexpr char kBraveBrandNameForCHUA[] = "Brave";
Expand All @@ -18,5 +25,34 @@ constexpr char kBraveBrandNameForCHUA[] = "Brave";
// can't use it here in the //components.
#define BRAVE_GET_USER_AGENT_BRAND_LIST brand = kBraveBrandNameForCHUA;

#define GetUserAgentMetadata GetUserAgentMetadata_ChromiumImpl
#include "src/components/embedder_support/user_agent_utils.cc"
#undef GetUserAgentMetadata
#undef BRAVE_GET_USER_AGENT_BRAND_LIST

namespace embedder_support {

blink::UserAgentMetadata GetUserAgentMetadata() {
return GetUserAgentMetadata(nullptr);
}

blink::UserAgentMetadata GetUserAgentMetadata(const PrefService* pref_service) {
blink::UserAgentMetadata metadata =
GetUserAgentMetadata_ChromiumImpl(pref_service);
if (base::FeatureList::IsEnabled(
blink::features::kClampPlatformVersionClientHint)) {
// Clamp platform version
base::Version platform_version(metadata.platform_version);
// Expect Chromium code to return `major.minor.patch` version. If that
// changes we need to re-evaluate what we want to send.
CHECK_EQ(3u, platform_version.components().size());
metadata.platform_version = base::StringPrintf(
"%d.%d.%s", platform_version.components()[0],
platform_version.components()[1],
blink::features::kClampPlatformVersionClientHintPatchValue.Get()
.c_str());
}
return metadata;
}

} // namespace embedder_support
Loading