Skip to content

Commit

Permalink
[UA-CH] Implement Sec-CH-UA-Bitness client hint header
Browse files Browse the repository at this point in the history
Intent to Implement and Ship:
https://groups.google.com/a/chromium.org/g/blink-dev/c/dafizBGwWMw
WICG/ua-client-hints#105

To be honest, the only real point of interest is
`content/common/user_agent.cc`, which is where `GetLowEntropyCpuBitness`
is implemented. Everything else is various levels of plumbing to set up
a new Client Hint header, populate it, test it, and add a new
Permissions Policy to control it.

Bug: 1199809
Change-Id: I0e7f36c8915720cb46e06452a85092a64bde8f06
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2840423
Commit-Queue: Aaron Tagliaboschi <[email protected]>
Reviewed-by: Andrey Kosyakov <[email protected]>
Reviewed-by: Alex Moshchuk <[email protected]>
Reviewed-by: Yoav Weiss <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Colin Blundell <[email protected]>
Cr-Commit-Position: refs/heads/master@{#894021}
  • Loading branch information
amtunlimited authored and Chromium LUCI CQ committed Jun 18, 2021
1 parent a7194e8 commit 1649e10
Show file tree
Hide file tree
Showing 38 changed files with 128 additions and 49 deletions.
2 changes: 1 addition & 1 deletion chrome/browser/client_hints/client_hints_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@

namespace {

const unsigned expected_client_hints_number = 13u;
const unsigned expected_client_hints_number = 14u;
const int32_t uma_histogram_max_value = 1471228928;

// An interceptor that records count of fetches and client hint headers for
Expand Down
2 changes: 2 additions & 0 deletions chrome/browser/sessions/session_service_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,8 @@ TEST_F(SessionServiceTest, PersistUserAgentOverrides) {
client_hints_override.full_version = "18.0.1025.45";
client_hints_override.platform = "Linux";
client_hints_override.architecture = "x86_64";
// Doesn't have to match, just needs to be different than the default
client_hints_override.bitness = "8";

SerializedNavigationEntry nav1 =
ContentTestHelper::CreateNavigation("http://google.com", "abc");
Expand Down
1 change: 1 addition & 0 deletions chrome/browser/sessions/tab_restore_service_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class TabRestoreServiceImplTest : public ChromeRenderViewHostTestHarness {
user_agent_override_.ua_metadata_override->full_version = "18.0.1025.45";
user_agent_override_.ua_metadata_override->platform = "Linux";
user_agent_override_.ua_metadata_override->architecture = "x86_64";
user_agent_override_.ua_metadata_override->bitness = "32";
}

~TabRestoreServiceImplTest() override {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
HTTP/1.1 200 OK
Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme
Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme,sec-ch-ua-bitness
Accept-CH-Lifetime: 3600
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
HTTP/1.1 200 OK
Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme
Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme,sec-ch-ua-bitness
Accept-CH-Lifetime: 1
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
HTTP/1.1 200 OK
Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme
Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme,sec-ch-ua-bitness
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
HTTP/1.1 200 OK
Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme
Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme,sec-ch-ua-bitness
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!-- This is split in two since data from header may round trip quickly
enough from browser to be used, so this makes sure we actually merge -->
<meta http-equiv="Accept-CH" content="lang,sec-ch-ua-arch,sec-ch-ua-platform">
<meta http-equiv="Accept-CH" content="sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme">
<meta http-equiv="Accept-CH" content="sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme,sec-ch-ua-bitness">
<link rel="icon" href="data:;base64,=">
<!-- A subresource! -->
<img src="non-existing-image.jpg"></img>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<html>
<meta http-equiv="Accept-CH" content="dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-model,sec-ch-ua-full-version">
<meta http-equiv="Accept-CH" content="dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-ua-bitness">
<meta http-equiv="Accept-CH-Lifetime" content="3600">
<link rel="icon" href="data:;base64,=">
</html>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<html>
<meta http-equiv="Accept-CH" content="dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-model,sec-ch-ua-full-version">
<meta http-equiv="Accept-CH" content="dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-ua-bitness">
<link rel="icon" href="data:;base64,=">
<head></head>
Empty file which uses link-rel to disable favicon fetches. The corresponding
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<html>
<meta http-equiv="Accept-CH" content="dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme">
<meta http-equiv="Accept-CH" content="dpr,device-memory,viewport-width,rtt,downlink,ect,lang,sec-ch-ua-arch,sec-ch-ua-platform,sec-ch-ua-platform-version,sec-ch-ua-model,sec-ch-ua-full-version,sec-ch-prefers-color-scheme,sec-ch-ua-bitness">
<link rel="icon" href="data:;base64,=">
<head></head>
Empty file which uses link-rel to disable favicon fetches. The corresponding
Expand Down
11 changes: 9 additions & 2 deletions components/embedder_support/user_agent_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ blink::UserAgentMetadata GetUserAgentMetadata() {
metadata.platform = GetPlatformForUAMetadata();
metadata.architecture = content::GetLowEntropyCpuArchitecture();
metadata.model = content::BuildModelInfo();

metadata.mobile = false;
#if defined(OS_ANDROID)
metadata.mobile = base::CommandLine::ForCurrentProcess()->HasSwitch(
Expand All @@ -153,6 +152,11 @@ blink::UserAgentMetadata GetUserAgentMetadata() {
base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix);
metadata.platform_version =
base::StringPrintf("%d.%d.%d", major, minor, bugfix);
// These methods use the same information as the User-Agent string, but are
// "low entropy" in that they reduce the number of options for output to a
// set number. For more information, see the respective headers.
metadata.architecture = content::GetLowEntropyCpuArchitecture();
metadata.bitness = content::GetLowEntropyCpuBitness();

return metadata;
}
Expand All @@ -171,9 +175,12 @@ void SetDesktopUserAgentOverride(content::WebContents* web_contents,
spoofed_ua.ua_metadata_override->platform = "Linux";
spoofed_ua.ua_metadata_override->platform_version =
std::string(); // match content::GetOSVersion(false) on Linux
spoofed_ua.ua_metadata_override->architecture = "x86";
spoofed_ua.ua_metadata_override->model = std::string();
spoofed_ua.ua_metadata_override->mobile = false;
// Match the above "CpuInfo" string, which is also the most common Linux
// CPU architecture and bitness.`
spoofed_ua.ua_metadata_override->architecture = "x86";
spoofed_ua.ua_metadata_override->bitness = "64";

web_contents->SetUserAgentOverride(spoofed_ua, override_in_new_tabs);
}
Expand Down
1 change: 1 addition & 0 deletions components/embedder_support/user_agent_utils_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ TEST(UserAgentUtilsTest, UserAgentMetadata) {
#endif
EXPECT_EQ(metadata.architecture, content::GetLowEntropyCpuArchitecture());
EXPECT_EQ(metadata.model, content::BuildModelInfo());
EXPECT_EQ(metadata.bitness, content::GetLowEntropyCpuBitness());
}

TEST(UserAgentUtilsTest, GenerateBrandVersionList) {
Expand Down
9 changes: 8 additions & 1 deletion content/browser/client_hints/client_hints.cc
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,11 @@ void UpdateNavigationRequestClientUaHeadersImpl(
AddUAHeader(headers, network::mojom::WebClientHintsType::kUAModel,
SerializeHeaderString(ua_metadata->model));
}
if (ShouldAddClientHint(data,
network::mojom::WebClientHintsType::kUABitness)) {
AddUAHeader(headers, network::mojom::WebClientHintsType::kUABitness,
SerializeHeaderString(ua_metadata->bitness));
}
} else if (call_type == ClientUaHeaderCallType::kAfterCreated) {
RemoveClientHintHeader(network::mojom::WebClientHintsType::kUA, headers);
RemoveClientHintHeader(network::mojom::WebClientHintsType::kUAMobile,
Expand All @@ -570,6 +575,8 @@ void UpdateNavigationRequestClientUaHeadersImpl(
network::mojom::WebClientHintsType::kUAPlatformVersion, headers);
RemoveClientHintHeader(network::mojom::WebClientHintsType::kUAModel,
headers);
RemoveClientHintHeader(network::mojom::WebClientHintsType::kUABitness,
headers);
}
}

Expand Down Expand Up @@ -678,7 +685,7 @@ void AddRequestClientHintsHeaders(
// If possible, logic should be added above so that the request headers for
// the newly added client hint can be added to the request.
static_assert(
network::mojom::WebClientHintsType::kPrefersColorScheme ==
network::mojom::WebClientHintsType::kUABitness ==
network::mojom::WebClientHintsType::kMaxValue,
"Consider adding client hint request headers from the browser process");

Expand Down
22 changes: 17 additions & 5 deletions content/common/user_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <stdint.h>

#include "base/containers/contains.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
Expand Down Expand Up @@ -125,11 +126,7 @@ std::string GetLowEntropyCpuArchitecture() {
return "arm";
}
#elif defined(OS_POSIX) && !defined(OS_ANDROID)
// This extra cpu_info_str variable is required to make sure the compiler
// doesn't optimize the copy away and have the StringPiece point at the
// internal std::string, resulting in a memory violation.
std::string cpu_info_str = BuildCpuInfo();
base::StringPiece cpu_info = cpu_info_str;
std::string cpu_info = BuildCpuInfo();
if (base::StartsWith(cpu_info, "arm") ||
base::StartsWith(cpu_info, "aarch")) {
return "arm";
Expand All @@ -142,6 +139,21 @@ std::string GetLowEntropyCpuArchitecture() {
return std::string();
}

std::string GetLowEntropyCpuBitness() {
#if defined(OS_WIN)
return (base::win::OSInfo::GetInstance()->GetArchitecture() ==
base::win::OSInfo::X86_ARCHITECTURE)
? "32"
: "64";
#elif defined(OS_MAC)
return "64";
#elif defined(OS_POSIX) && !defined(OS_ANDROID)
return base::Contains(BuildCpuInfo(), "64") ? "64" : "32";
#else
return std::string();
#endif
}

std::string GetOSVersion(IncludeAndroidBuildNumber include_android_build_number,
IncludeAndroidModel include_android_model) {
std::string os_version;
Expand Down
1 change: 1 addition & 0 deletions content/public/common/common_param_traits_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ IPC_STRUCT_TRAITS_BEGIN(blink::UserAgentMetadata)
IPC_STRUCT_TRAITS_MEMBER(architecture)
IPC_STRUCT_TRAITS_MEMBER(model)
IPC_STRUCT_TRAITS_MEMBER(mobile)
IPC_STRUCT_TRAITS_MEMBER(bitness)
IPC_STRUCT_TRAITS_END()

IPC_STRUCT_TRAITS_BEGIN(blink::UserAgentOverride)
Expand Down
4 changes: 4 additions & 0 deletions content/public/common/user_agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ CONTENT_EXPORT std::string BuildCpuInfo();
// most common cases.
CONTENT_EXPORT std::string GetLowEntropyCpuArchitecture();

// Takes the cpu info (see BuildCpuInfo()) and extracts the CPU bitness for
// most common cases.
CONTENT_EXPORT std::string GetLowEntropyCpuBitness();

// Builds a User-agent compatible string that describes the OS and CPU type.
// On Android, the string will only include the build number and model if
// relevant enums indicate they should be included.
Expand Down
2 changes: 2 additions & 0 deletions content/shell/browser/shell_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ blink::UserAgentMetadata GetShellUserAgentMetadata() {
metadata.architecture = BuildCpuInfo();
metadata.model = BuildModelInfo();

metadata.bitness = GetLowEntropyCpuBitness();

return metadata;
}

Expand Down
3 changes: 2 additions & 1 deletion services/network/public/cpp/client_hints.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const char* const kClientHintsNameMapping[] = {"device-memory",
"sec-ch-ua-mobile",
"sec-ch-ua-full-version",
"sec-ch-ua-platform-version",
"sec-ch-prefers-color-scheme"};
"sec-ch-prefers-color-scheme",
"sec-ch-ua-bitness"};

const size_t kClientHintsMappingsCount = base::size(kClientHintsNameMapping);

Expand Down
1 change: 1 addition & 0 deletions services/network/public/cpp/cors/cors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ bool IsCorsSafelistedHeader(const std::string& name, const std::string& value) {
//
// https://tomayac.github.io/user-preference-media-features-headers/#sec-ch-prefers-color-scheme
"sec-ch-prefers-color-scheme",
"sec-ch-ua-bitness",
};
if (std::find(std::begin(safe_names), std::end(safe_names), lower_name) ==
std::end(safe_names))
Expand Down
1 change: 1 addition & 0 deletions services/network/public/mojom/web_client_hints_types.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum WebClientHintsType {
kUAFullVersion = 13,
kUAPlatformVersion = 14,
kPrefersColorScheme = 15,
kUABitness = 16,

// Warning: Before adding a new client hint, read the warning at the top.
};
37 changes: 19 additions & 18 deletions third_party/blink/common/client_hints/client_hints.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,23 @@

namespace blink {

const char* const kClientHintsHeaderMapping[] = {
"device-memory",
"dpr",
"width",
"viewport-width",
"rtt",
"downlink",
"ect",
"sec-ch-lang",
"sec-ch-ua",
"sec-ch-ua-arch",
"sec-ch-ua-platform",
"sec-ch-ua-model",
"sec-ch-ua-mobile",
"sec-ch-ua-full-version",
"sec-ch-ua-platform-version",
"sec-ch-prefers-color-scheme",
};
const char* const kClientHintsHeaderMapping[] = {"device-memory",
"dpr",
"width",
"viewport-width",
"rtt",
"downlink",
"ect",
"sec-ch-lang",
"sec-ch-ua",
"sec-ch-ua-arch",
"sec-ch-ua-platform",
"sec-ch-ua-model",
"sec-ch-ua-mobile",
"sec-ch-ua-full-version",
"sec-ch-ua-platform-version",
"sec-ch-prefers-color-scheme",
"sec-ch-ua-bitness"};

const unsigned kClientHintsNumberOfLegacyHints = 4;

Expand All @@ -60,6 +59,7 @@ const mojom::PermissionsPolicyFeature kClientHintsPermissionsPolicyMapping[] = {
mojom::PermissionsPolicyFeature::kClientHintUAFullVersion,
mojom::PermissionsPolicyFeature::kClientHintUAPlatformVersion,
mojom::PermissionsPolicyFeature::kClientHintPrefersColorScheme,
mojom::PermissionsPolicyFeature::kClientHintUABitness,
};

const size_t kClientHintsMappingsCount = base::size(kClientHintsHeaderMapping);
Expand Down Expand Up @@ -117,6 +117,7 @@ absl::optional<std::vector<network::mojom::WebClientHintsType>> FilterAcceptCH(
case network::mojom::WebClientHintsType::kUAModel:
case network::mojom::WebClientHintsType::kUAMobile:
case network::mojom::WebClientHintsType::kUAFullVersion:
case network::mojom::WebClientHintsType::kUABitness:
if (permit_ua_hints)
result.push_back(hint);
break;
Expand Down
24 changes: 12 additions & 12 deletions third_party/blink/common/client_hints/client_hints_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ TEST(ClientHintsTest, FindClientHintsToRemoveLegacy) {
std::vector<std::string> removed_headers;
FindClientHintsToRemove(nullptr, GURL(), &removed_headers);
EXPECT_THAT(removed_headers,
UnorderedElementsAre("rtt", "downlink", "ect", "sec-ch-lang",
"sec-ch-ua-arch", "sec-ch-ua-platform",
"sec-ch-ua-model", "sec-ch-ua-full-version",
"sec-ch-ua-platform-version",
"sec-ch-prefers-color-scheme"));
UnorderedElementsAre(
"rtt", "downlink", "ect", "sec-ch-lang", "sec-ch-ua-arch",
"sec-ch-ua-platform", "sec-ch-ua-model",
"sec-ch-ua-full-version", "sec-ch-ua-platform-version",
"sec-ch-prefers-color-scheme", "sec-ch-ua-bitness"));
}

// Checks that the removed header list includes legacy headers but not the
Expand All @@ -142,12 +142,12 @@ TEST(ClientHintsTest, FindClientHintsToRemoveNoLegacy) {
features::kAllowClientHintsToThirdParty);
std::vector<std::string> removed_headers;
FindClientHintsToRemove(nullptr, GURL(), &removed_headers);
EXPECT_THAT(
removed_headers,
UnorderedElementsAre(
"device-memory", "dpr", "width", "viewport-width", "rtt", "downlink",
"ect", "sec-ch-lang", "sec-ch-ua-arch", "sec-ch-ua-platform",
"sec-ch-ua-model", "sec-ch-ua-full-version",
"sec-ch-ua-platform-version", "sec-ch-prefers-color-scheme"));
EXPECT_THAT(removed_headers,
UnorderedElementsAre(
"device-memory", "dpr", "width", "viewport-width", "rtt",
"downlink", "ect", "sec-ch-lang", "sec-ch-ua-arch",
"sec-ch-ua-platform", "sec-ch-ua-model",
"sec-ch-ua-full-version", "sec-ch-ua-platform-version",
"sec-ch-prefers-color-scheme", "sec-ch-ua-bitness"));
}
} // namespace blink
5 changes: 4 additions & 1 deletion third_party/blink/common/user_agent/user_agent_metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ absl::optional<std::string> UserAgentMetadata::Marshal(
out.WriteString(in->architecture);
out.WriteString(in->model);
out.WriteBool(in->mobile);
out.WriteString(in->bitness);
return std::string(reinterpret_cast<const char*>(out.data()), out.size());
}

Expand Down Expand Up @@ -102,6 +103,8 @@ absl::optional<UserAgentMetadata> UserAgentMetadata::Demarshal(
return absl::nullopt;
if (!in.ReadBool(&out.mobile))
return absl::nullopt;
if (!in.ReadString(&out.bitness))
return absl::nullopt;
return absl::make_optional(std::move(out));
}

Expand All @@ -114,7 +117,7 @@ bool operator==(const UserAgentMetadata& a, const UserAgentMetadata& b) {
a.full_version == b.full_version && a.platform == b.platform &&
a.platform_version == b.platform_version &&
a.architecture == b.architecture && a.model == b.model &&
a.mobile == b.mobile;
a.mobile == b.mobile && a.bitness == b.bitness;
}

bool operator==(const UserAgentOverride& a, const UserAgentOverride& b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ blink::UserAgentMetadata MakeToEncode() {
to_encode.architecture = "Z80";
to_encode.model = "unofficial";
to_encode.mobile = false;
to_encode.bitness = "8";
return to_encode;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ bool StructTraits<blink::mojom::UserAgentMetadataDataView,
out->model = string;
out->mobile = data.mobile();

if (!data.ReadBitness(&string))
return false;
out->bitness = string;

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct BLINK_COMMON_EXPORT UserAgentMetadata {
std::string architecture;
std::string model;
bool mobile = false;
std::string bitness;
};

// Used when customizing the sent User-Agent and Sec-CH-UA-* for
Expand Down
Loading

0 comments on commit 1649e10

Please sign in to comment.