Skip to content

Commit

Permalink
Send kUAModel and kUAPlatformVersion CHs when requested. (uplift to 1…
Browse files Browse the repository at this point in the history
….51.x) (#18263)

Uplift of #18154 (squashed) to beta
  • Loading branch information
brave-builds authored Apr 28, 2023
1 parent 545fa57 commit f7f8042
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 50 deletions.
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

0 comments on commit f7f8042

Please sign in to comment.