Browse Source

feat: allow setting of global fallback user agent (#18016)

* feat: allow setting of global fallback user agent

* spec: add tests for app.set/getUserAgentFallback
Samuel Attard 6 years ago
parent
commit
d4f5ebefe6

+ 10 - 0
atom/browser/api/atom_api_app.cc

@@ -1271,6 +1271,14 @@ void App::EnableSandbox(mate::Arguments* args) {
   command_line->AppendSwitch(switches::kEnableSandbox);
 }
 
+void App::SetUserAgentFallback(const std::string& user_agent) {
+  AtomBrowserClient::Get()->SetUserAgent(user_agent);
+}
+
+std::string App::GetUserAgentFallback() {
+  return AtomBrowserClient::Get()->GetUserAgent();
+}
+
 #if defined(OS_MACOSX)
 bool App::MoveToApplicationsFolder(mate::Arguments* args) {
   return ui::cocoa::AtomBundleMover::Move(args);
@@ -1450,6 +1458,8 @@ void App::BuildPrototype(v8::Isolate* isolate,
 #if defined(OS_MACOSX)
       .SetProperty("dock", &App::GetDockAPI)
 #endif
+      .SetProperty("userAgentFallback", &App::GetUserAgentFallback,
+                   &App::SetUserAgentFallback)
       .SetMethod("enableSandbox", &App::EnableSandbox);
 }
 

+ 2 - 0
atom/browser/api/atom_api_app.h

@@ -210,6 +210,8 @@ class App : public AtomBrowserClient::Delegate,
   v8::Local<v8::Promise> GetGPUInfo(v8::Isolate* isolate,
                                     const std::string& info_type);
   void EnableSandbox(mate::Arguments* args);
+  void SetUserAgentFallback(const std::string& user_agent);
+  std::string GetUserAgentFallback();
 
 #if defined(OS_MACOSX)
   bool MoveToApplicationsFolder(mate::Arguments* args);

+ 7 - 1
atom/browser/atom_browser_client.cc

@@ -924,7 +924,13 @@ std::string AtomBrowserClient::GetProduct() const {
 }
 
 std::string AtomBrowserClient::GetUserAgent() const {
-  return GetApplicationUserAgent();
+  if (user_agent_override_.empty())
+    return GetApplicationUserAgent();
+  return user_agent_override_;
+}
+
+void AtomBrowserClient::SetUserAgent(const std::string& user_agent) {
+  user_agent_override_ = user_agent;
 }
 
 void AtomBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(

+ 5 - 1
atom/browser/atom_browser_client.h

@@ -64,6 +64,9 @@ class AtomBrowserClient : public content::ContentBrowserClient,
   // content::ContentBrowserClient:
   bool ShouldEnableStrictSiteIsolation() override;
 
+  std::string GetUserAgent() const override;
+  void SetUserAgent(const std::string& user_agent);
+
  protected:
   void RenderProcessWillLaunch(
       content::RenderProcessHost* host,
@@ -157,7 +160,6 @@ class AtomBrowserClient : public content::ContentBrowserClient,
   std::vector<base::FilePath> GetNetworkContextsParentDirectory() override;
   bool ShouldBypassCORB(int render_process_id) const override;
   std::string GetProduct() const override;
-  std::string GetUserAgent() const override;
   void RegisterNonNetworkNavigationURLLoaderFactories(
       int frame_tree_node_id,
       NonNetworkURLLoaderFactoryMap* factories) override;
@@ -236,6 +238,8 @@ class AtomBrowserClient : public content::ContentBrowserClient,
   mutable base::Lock process_preferences_lock_;
   std::map<int, ProcessPreferences> process_preferences_;
 
+  std::string user_agent_override_ = "";
+
   DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
 };
 

+ 2 - 1
atom/browser/atom_browser_context.cc

@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "atom/browser/atom_blob_reader.h"
+#include "atom/browser/atom_browser_client.h"
 #include "atom/browser/atom_browser_main_parts.h"
 #include "atom/browser/atom_download_manager_delegate.h"
 #include "atom/browser/atom_paths.h"
@@ -67,7 +68,7 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
       storage_policy_(new SpecialStoragePolicy),
       in_memory_(in_memory),
       weak_factory_(this) {
-  user_agent_ = GetApplicationUserAgent();
+  user_agent_ = AtomBrowserClient::Get()->GetUserAgent();
 
   // Read options.
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();

+ 3 - 1
atom/browser/net/system_network_context_manager.cc

@@ -7,6 +7,7 @@
 #include <string>
 #include <utility>
 
+#include "atom/browser/atom_browser_client.h"
 #include "atom/browser/io_thread.h"
 #include "atom/common/application_info.h"
 #include "atom/common/options_switches.h"
@@ -245,7 +246,8 @@ SystemNetworkContextManager::CreateNetworkContextParams() {
 
   network_context_params->context_name = std::string("system");
 
-  network_context_params->user_agent = atom::GetApplicationUserAgent();
+  network_context_params->user_agent =
+      atom::AtomBrowserClient::Get()->GetUserAgent();
 
   network_context_params->http_cache_enabled = false;
 

+ 9 - 0
docs/api/app.md

@@ -1354,6 +1354,15 @@ On macOS, setting this with any nonzero integer shows on the dock icon. On Linux
 **Note:** Unity launcher requires the existence of a `.desktop` file to work,
 for more information please read [Desktop Environment Integration][unity-requirement].
 
+### `app.userAgentFallback`
+
+A `String` which is the user agent string Electron will use as a global fallback.
+
+This is the user agent that will be used when no user agent is set at the
+`webContents` or `session` level.  Useful for ensuring your entire
+app has the same user agent.  Set to a custom value as early as possible
+in your apps initialization to ensure that your overridden value is used.
+
 ### `app.isPackaged`
 
 A `Boolean` property that returns  `true` if the app is packaged, `false` otherwise. For many apps, this property can be used to distinguish development and production environments.

+ 24 - 0
spec-main/api-app-spec.ts

@@ -1296,6 +1296,30 @@ describe('default behavior', () => {
       expect(result).to.equal(true)
     })
   })
+
+  describe('user agent fallback', () => {
+    let initialValue: string
+
+    before(() => {
+      initialValue = app.userAgentFallback!
+    })
+
+    it('should have a reasonable default', () => {
+      expect(initialValue).to.include(`Electron/${process.versions.electron}`)
+      expect(initialValue).to.include(`Chrome/${process.versions.chrome}`)
+    })
+
+    it('should be overridable', () => {
+      app.userAgentFallback = 'test-agent/123'
+      expect(app.userAgentFallback).to.equal('test-agent/123')
+    })
+
+    it('should be restorable', () => {
+      app.userAgentFallback = 'test-agent/123'
+      app.userAgentFallback = ''
+      expect(app.userAgentFallback).to.equal(initialValue)
+    })
+  })
 })
 
 async function runTestApp (name: string, ...args: any[]) {

+ 1 - 1
spec-main/index.js

@@ -80,6 +80,6 @@ app.whenReady().then(() => {
         process.exit(runner.failures)
       })
     }
-    const runner = (isCI) ? mocha.run(cb) : mocha.forbidOnly().run(cb) 
+    const runner = (isCI) ? mocha.forbidOnly().run(cb) : mocha.run(cb)
   })
 })