Skip to content

Commit

Permalink
fix: make navigator.userAgentData non-empty (#34524)
Browse files Browse the repository at this point in the history
fix: make navigator.userAgentData non-empty (#34481)

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
  • Loading branch information
trop[bot] and nornagon committed Jun 13, 2022
1 parent dd1a692 commit e174aac
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 13 deletions.
1 change: 1 addition & 0 deletions BUILD.gn
Expand Up @@ -371,6 +371,7 @@ source_set("electron_lib") {
"//chrome/app/resources:platform_locale_settings",
"//components/autofill/core/common:features",
"//components/certificate_transparency",
"//components/embedder_support:browser_util",
"//components/language/core/browser",
"//components/net_log",
"//components/network_hints/browser",
Expand Down
26 changes: 16 additions & 10 deletions shell/browser/api/electron_api_web_contents.cc
Expand Up @@ -28,6 +28,7 @@
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/views/eye_dropper/eye_dropper.h"
#include "chrome/common/pref_names.h"
#include "components/embedder_support/user_agent_utils.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/security_state/content/content_utils.h"
Expand Down Expand Up @@ -659,9 +660,10 @@ WebContents::WebContents(v8::Isolate* isolate,
auto session = Session::CreateFrom(isolate, GetBrowserContext());
session_.Reset(isolate, session.ToV8());

web_contents->SetUserAgentOverride(blink::UserAgentOverride::UserAgentOnly(
GetBrowserContext()->GetUserAgent()),
false);
absl::optional<std::string> user_agent_override =
GetBrowserContext()->GetUserAgentOverride();
if (user_agent_override)
SetUserAgent(*user_agent_override);
web_contents->SetUserData(kElectronApiWebContentsKey,
std::make_unique<UserDataLink>(GetWeakPtr()));
InitZoomController(web_contents, gin::Dictionary::CreateEmpty(isolate));
Expand Down Expand Up @@ -867,9 +869,10 @@ void WebContents::InitWithSessionAndOptions(

AutofillDriverFactory::CreateForWebContents(web_contents());

web_contents()->SetUserAgentOverride(blink::UserAgentOverride::UserAgentOnly(
GetBrowserContext()->GetUserAgent()),
false);
absl::optional<std::string> user_agent_override =
GetBrowserContext()->GetUserAgentOverride();
if (user_agent_override)
SetUserAgent(*user_agent_override);

if (IsGuest()) {
NativeWindow* owner_window = nullptr;
Expand Down Expand Up @@ -2150,8 +2153,7 @@ void WebContents::LoadURL(const GURL& url,

std::string user_agent;
if (options.Get("userAgent", &user_agent))
web_contents()->SetUserAgentOverride(
blink::UserAgentOverride::UserAgentOnly(user_agent), false);
SetUserAgent(user_agent);

std::string extra_headers;
if (options.Get("extraHeaders", &extra_headers))
Expand Down Expand Up @@ -2366,8 +2368,12 @@ void WebContents::ForcefullyCrashRenderer() {
}

void WebContents::SetUserAgent(const std::string& user_agent) {
web_contents()->SetUserAgentOverride(
blink::UserAgentOverride::UserAgentOnly(user_agent), false);
blink::UserAgentOverride ua_override;
ua_override.ua_string_override = user_agent;
if (!user_agent.empty())
ua_override.ua_metadata_override = embedder_support::GetUserAgentMetadata();

web_contents()->SetUserAgentOverride(ua_override, false);
}

std::string WebContents::GetUserAgent() {
Expand Down
5 changes: 5 additions & 0 deletions shell/browser/electron_browser_client.cc
Expand Up @@ -30,6 +30,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version.h"
#include "components/embedder_support/user_agent_utils.h"
#include "components/net_log/chrome_net_log.h"
#include "components/network_hints/common/network_hints.mojom.h"
#include "content/browser/keyboard_lock/keyboard_lock_service_impl.h" // nogncheck
Expand Down Expand Up @@ -1159,6 +1160,10 @@ void ElectronBrowserClient::SetUserAgent(const std::string& user_agent) {
user_agent_override_ = user_agent;
}

blink::UserAgentMetadata ElectronBrowserClient::GetUserAgentMetadata() {
return embedder_support::GetUserAgentMetadata();
}

void ElectronBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
int frame_tree_node_id,
ukm::SourceIdObj ukm_source_id,
Expand Down
1 change: 1 addition & 0 deletions shell/browser/electron_browser_client.h
Expand Up @@ -93,6 +93,7 @@ class ElectronBrowserClient : public content::ContentBrowserClient,

std::string GetUserAgent() override;
void SetUserAgent(const std::string& user_agent);
blink::UserAgentMetadata GetUserAgentMetadata() override;

content::SerialDelegate* GetSerialDelegate() override;

Expand Down
7 changes: 5 additions & 2 deletions shell/browser/electron_browser_context.cc
Expand Up @@ -107,8 +107,6 @@ ElectronBrowserContext::ElectronBrowserContext(const std::string& partition,
protocol_registry_(base::WrapUnique(new ProtocolRegistry)),
in_memory_(in_memory),
ssl_config_(network::mojom::SSLConfig::New()) {
user_agent_ = ElectronBrowserClient::Get()->GetUserAgent();

// Read options.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
use_cache_ = !command_line->HasSwitch(switches::kDisableHttpCache);
Expand Down Expand Up @@ -305,6 +303,11 @@ ElectronBrowserContext::GetSpecialStoragePolicy() {
}

std::string ElectronBrowserContext::GetUserAgent() const {
return user_agent_.value_or(ElectronBrowserClient::Get()->GetUserAgent());
}

absl::optional<std::string> ElectronBrowserContext::GetUserAgentOverride()
const {
return user_agent_;
}

Expand Down
3 changes: 2 additions & 1 deletion shell/browser/electron_browser_context.h
Expand Up @@ -85,6 +85,7 @@ class ElectronBrowserContext : public content::BrowserContext {

void SetUserAgent(const std::string& user_agent);
std::string GetUserAgent() const;
absl::optional<std::string> GetUserAgentOverride() const;
bool CanUseHttpCache() const;
int GetMaxCacheSize() const;
ResolveProxyHelper* GetResolveProxyHelper();
Expand Down Expand Up @@ -170,7 +171,7 @@ class ElectronBrowserContext : public content::BrowserContext {
std::unique_ptr<predictors::PreconnectManager> preconnect_manager_;
std::unique_ptr<ProtocolRegistry> protocol_registry_;

std::string user_agent_;
absl::optional<std::string> user_agent_;
base::FilePath path_;
bool in_memory_ = false;
bool use_cache_ = true;
Expand Down
62 changes: 62 additions & 0 deletions spec-main/chromium-spec.ts
Expand Up @@ -1508,6 +1508,68 @@ describe('chromium features', () => {
expect(focus).to.be.false();
});
});

describe('navigator.userAgentData', () => {
// These tests are done on an http server because navigator.userAgentData
// requires a secure context.
let server: http.Server;
let serverUrl: string;
before(async () => {
server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.end('');
});
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve));
serverUrl = `http://localhost:${(server.address() as any).port}`;
});
after(() => {
server.close();
});

describe('is not empty', () => {
it('by default', async () => {
const w = new BrowserWindow({ show: false });
await w.loadURL(serverUrl);
const platform = await w.webContents.executeJavaScript('navigator.userAgentData.platform');
expect(platform).not.to.be.empty();
});

it('when there is a session-wide UA override', async () => {
const ses = session.fromPartition(`${Math.random()}`);
ses.setUserAgent('foobar');
const w = new BrowserWindow({ show: false, webPreferences: { session: ses } });
await w.loadURL(serverUrl);
const platform = await w.webContents.executeJavaScript('navigator.userAgentData.platform');
expect(platform).not.to.be.empty();
});

it('when there is a WebContents-specific UA override', async () => {
const w = new BrowserWindow({ show: false });
w.webContents.setUserAgent('foo');
await w.loadURL(serverUrl);
const platform = await w.webContents.executeJavaScript('navigator.userAgentData.platform');
expect(platform).not.to.be.empty();
});

it('when there is a WebContents-specific UA override at load time', async () => {
const w = new BrowserWindow({ show: false });
await w.loadURL(serverUrl, {
userAgent: 'foo'
});
const platform = await w.webContents.executeJavaScript('navigator.userAgentData.platform');
expect(platform).not.to.be.empty();
});
});

describe('brand list', () => {
it('contains chromium', async () => {
const w = new BrowserWindow({ show: false });
await w.loadURL(serverUrl);
const brands = await w.webContents.executeJavaScript('navigator.userAgentData.brands');
expect(brands.map((b: any) => b.brand)).to.include('Chromium');
});
});
});
});

describe('font fallback', () => {
Expand Down

0 comments on commit e174aac

Please sign in to comment.