feat: add support for configuring system network context proxies (#41335)
* feat: add support for configuring system network context proxies * chore: add specs * chore: fix lint * fix: address review feedback
This commit is contained in:
parent
136762b45f
commit
26131b23b8
13 changed files with 391 additions and 113 deletions
|
@ -26,6 +26,9 @@
|
|||
#include "chrome/browser/icon_manager.h"
|
||||
#include "chrome/common/chrome_features.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "components/proxy_config/proxy_config_dictionary.h"
|
||||
#include "components/proxy_config/proxy_config_pref_names.h"
|
||||
#include "components/proxy_config/proxy_prefs.h"
|
||||
#include "content/browser/gpu/compositor_util.h" // nogncheck
|
||||
#include "content/browser/gpu/gpu_data_manager_impl.h" // nogncheck
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
|
@ -1472,6 +1475,98 @@ void App::EnableSandbox(gin_helper::ErrorThrower thrower) {
|
|||
command_line->AppendSwitch(switches::kEnableSandbox);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> App::SetProxy(gin::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
gin_helper::Promise<void> promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
gin_helper::Dictionary options;
|
||||
args->GetNext(&options);
|
||||
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
promise.RejectWithErrorMessage(
|
||||
"app.setProxy() can only be called after app is ready.");
|
||||
return handle;
|
||||
}
|
||||
|
||||
if (!g_browser_process->local_state()) {
|
||||
promise.RejectWithErrorMessage(
|
||||
"app.setProxy() failed due to internal error.");
|
||||
return handle;
|
||||
}
|
||||
|
||||
std::string mode, proxy_rules, bypass_list, pac_url;
|
||||
|
||||
options.Get("pacScript", &pac_url);
|
||||
options.Get("proxyRules", &proxy_rules);
|
||||
options.Get("proxyBypassRules", &bypass_list);
|
||||
|
||||
ProxyPrefs::ProxyMode proxy_mode = ProxyPrefs::MODE_FIXED_SERVERS;
|
||||
if (!options.Get("mode", &mode)) {
|
||||
// pacScript takes precedence over proxyRules.
|
||||
if (!pac_url.empty()) {
|
||||
proxy_mode = ProxyPrefs::MODE_PAC_SCRIPT;
|
||||
}
|
||||
} else if (!ProxyPrefs::StringToProxyMode(mode, &proxy_mode)) {
|
||||
promise.RejectWithErrorMessage(
|
||||
"Invalid mode, must be one of direct, auto_detect, pac_script, "
|
||||
"fixed_servers or system");
|
||||
return handle;
|
||||
}
|
||||
|
||||
base::Value::Dict proxy_config;
|
||||
switch (proxy_mode) {
|
||||
case ProxyPrefs::MODE_DIRECT:
|
||||
proxy_config = ProxyConfigDictionary::CreateDirect();
|
||||
break;
|
||||
case ProxyPrefs::MODE_SYSTEM:
|
||||
proxy_config = ProxyConfigDictionary::CreateSystem();
|
||||
break;
|
||||
case ProxyPrefs::MODE_AUTO_DETECT:
|
||||
proxy_config = ProxyConfigDictionary::CreateAutoDetect();
|
||||
break;
|
||||
case ProxyPrefs::MODE_PAC_SCRIPT:
|
||||
proxy_config = ProxyConfigDictionary::CreatePacScript(pac_url, true);
|
||||
break;
|
||||
case ProxyPrefs::MODE_FIXED_SERVERS:
|
||||
proxy_config =
|
||||
ProxyConfigDictionary::CreateFixedServers(proxy_rules, bypass_list);
|
||||
break;
|
||||
default:
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
static_cast<BrowserProcessImpl*>(g_browser_process)
|
||||
->in_memory_pref_store()
|
||||
->SetValue(proxy_config::prefs::kProxy,
|
||||
base::Value{std::move(proxy_config)},
|
||||
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
||||
|
||||
g_browser_process->system_network_context_manager()
|
||||
->GetContext()
|
||||
->ForceReloadProxyConfig(base::BindOnce(
|
||||
gin_helper::Promise<void>::ResolvePromise, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> App::ResolveProxy(gin::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
gin_helper::Promise<std::string> promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
GURL url;
|
||||
args->GetNext(&url);
|
||||
|
||||
static_cast<BrowserProcessImpl*>(g_browser_process)
|
||||
->GetResolveProxyHelper()
|
||||
->ResolveProxy(
|
||||
url, base::BindOnce(gin_helper::Promise<std::string>::ResolvePromise,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void App::SetUserAgentFallback(const std::string& user_agent) {
|
||||
ElectronBrowserClient::Get()->SetUserAgent(user_agent);
|
||||
}
|
||||
|
@ -1776,7 +1871,9 @@ gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) {
|
|||
.SetProperty("userAgentFallback", &App::GetUserAgentFallback,
|
||||
&App::SetUserAgentFallback)
|
||||
.SetMethod("configureHostResolver", &ConfigureHostResolver)
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox);
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox)
|
||||
.SetMethod("setProxy", &App::SetProxy)
|
||||
.SetMethod("resolveProxy", &App::ResolveProxy);
|
||||
}
|
||||
|
||||
const char* App::GetTypeName() {
|
||||
|
|
|
@ -222,6 +222,8 @@ class App : public ElectronBrowserClient::Delegate,
|
|||
void EnableSandbox(gin_helper::ErrorThrower thrower);
|
||||
void SetUserAgentFallback(const std::string& user_agent);
|
||||
std::string GetUserAgentFallback();
|
||||
v8::Local<v8::Promise> SetProxy(gin::Arguments* args);
|
||||
v8::Local<v8::Promise> ResolveProxy(gin::Arguments* args);
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
void SetActivationPolicy(gin_helper::ErrorThrower thrower,
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "net/proxy_resolution/proxy_config_with_annotation.h"
|
||||
#include "services/device/public/cpp/geolocation/geolocation_manager.h"
|
||||
#include "services/network/public/cpp/network_switches.h"
|
||||
#include "shell/browser/net/resolve_proxy_helper.h"
|
||||
#include "shell/common/electron_paths.h"
|
||||
#include "shell/common/thread_restrictions.h"
|
||||
|
||||
|
@ -100,9 +101,9 @@ void BrowserProcessImpl::PostEarlyInitialization() {
|
|||
OSCrypt::RegisterLocalPrefs(pref_registry.get());
|
||||
#endif
|
||||
|
||||
auto pref_store = base::MakeRefCounted<ValueMapPrefStore>();
|
||||
ApplyProxyModeFromCommandLine(pref_store.get());
|
||||
prefs_factory.set_command_line_prefs(std::move(pref_store));
|
||||
in_memory_pref_store_ = base::MakeRefCounted<ValueMapPrefStore>();
|
||||
ApplyProxyModeFromCommandLine(in_memory_pref_store());
|
||||
prefs_factory.set_command_line_prefs(in_memory_pref_store());
|
||||
|
||||
// Only use a persistent prefs store when cookie encryption is enabled as that
|
||||
// is the only key that needs it
|
||||
|
@ -316,6 +317,14 @@ const std::string& BrowserProcessImpl::GetSystemLocale() const {
|
|||
return system_locale_;
|
||||
}
|
||||
|
||||
electron::ResolveProxyHelper* BrowserProcessImpl::GetResolveProxyHelper() {
|
||||
if (!resolve_proxy_helper_) {
|
||||
resolve_proxy_helper_ = base::MakeRefCounted<electron::ResolveProxyHelper>(
|
||||
system_network_context_manager()->GetContext());
|
||||
}
|
||||
return resolve_proxy_helper_.get();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
void BrowserProcessImpl::SetLinuxStorageBackend(
|
||||
os_crypt::SelectedLinuxBackend selected_backend) {
|
||||
|
|
|
@ -31,6 +31,10 @@ namespace printing {
|
|||
class PrintJobManager;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
class ResolveProxyHelper;
|
||||
}
|
||||
|
||||
// Empty definition for std::unique_ptr, rather than a forward declaration
|
||||
class BackgroundModeManager {};
|
||||
|
||||
|
@ -53,9 +57,9 @@ class BrowserProcessImpl : public BrowserProcess {
|
|||
void PreMainMessageLoopRun();
|
||||
void PostDestroyThreads() {}
|
||||
void PostMainMessageLoopRun();
|
||||
|
||||
void SetSystemLocale(const std::string& locale);
|
||||
const std::string& GetSystemLocale() const;
|
||||
electron::ResolveProxyHelper* GetResolveProxyHelper();
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
void SetLinuxStorageBackend(os_crypt::SelectedLinuxBackend selected_backend);
|
||||
|
@ -123,6 +127,10 @@ class BrowserProcessImpl : public BrowserProcess {
|
|||
printing::PrintJobManager* print_job_manager() override;
|
||||
StartupData* startup_data() override;
|
||||
|
||||
ValueMapPrefStore* in_memory_pref_store() const {
|
||||
return in_memory_pref_store_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateNetworkQualityObserver();
|
||||
void CreateOSCryptAsync();
|
||||
|
@ -139,6 +147,8 @@ class BrowserProcessImpl : public BrowserProcess {
|
|||
#endif
|
||||
embedder_support::OriginTrialsSettingsStorage origin_trials_settings_storage_;
|
||||
|
||||
scoped_refptr<ValueMapPrefStore> in_memory_pref_store_;
|
||||
scoped_refptr<electron::ResolveProxyHelper> resolve_proxy_helper_;
|
||||
std::unique_ptr<network::NetworkQualityTracker> network_quality_tracker_;
|
||||
std::unique_ptr<
|
||||
network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver>
|
||||
|
|
|
@ -535,7 +535,8 @@ ElectronBrowserContext::GetReduceAcceptLanguageControllerDelegate() {
|
|||
|
||||
ResolveProxyHelper* ElectronBrowserContext::GetResolveProxyHelper() {
|
||||
if (!resolve_proxy_helper_) {
|
||||
resolve_proxy_helper_ = base::MakeRefCounted<ResolveProxyHelper>(this);
|
||||
resolve_proxy_helper_ = base::MakeRefCounted<ResolveProxyHelper>(
|
||||
GetDefaultStoragePartition()->GetNetworkContext());
|
||||
}
|
||||
return resolve_proxy_helper_.get();
|
||||
}
|
||||
|
|
|
@ -8,19 +8,17 @@
|
|||
|
||||
#include "base/functional/bind.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "net/base/network_anonymization_key.h"
|
||||
#include "net/proxy_resolution/proxy_info.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace electron {
|
||||
|
||||
ResolveProxyHelper::ResolveProxyHelper(ElectronBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {}
|
||||
ResolveProxyHelper::ResolveProxyHelper(
|
||||
network::mojom::NetworkContext* network_context)
|
||||
: network_context_(network_context) {}
|
||||
|
||||
ResolveProxyHelper::~ResolveProxyHelper() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
@ -54,11 +52,9 @@ void ResolveProxyHelper::StartPendingRequest() {
|
|||
receiver_.set_disconnect_handler(
|
||||
base::BindOnce(&ResolveProxyHelper::OnProxyLookupComplete,
|
||||
base::Unretained(this), net::ERR_ABORTED, std::nullopt));
|
||||
browser_context_->GetDefaultStoragePartition()
|
||||
->GetNetworkContext()
|
||||
->LookUpProxyForURL(pending_requests_.front().url,
|
||||
net::NetworkAnonymizationKey(),
|
||||
std::move(proxy_lookup_client));
|
||||
network_context_->LookUpProxyForURL(pending_requests_.front().url,
|
||||
net::NetworkAnonymizationKey(),
|
||||
std::move(proxy_lookup_client));
|
||||
}
|
||||
|
||||
void ResolveProxyHelper::OnProxyLookupComplete(
|
||||
|
|
|
@ -12,20 +12,19 @@
|
|||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/proxy_lookup_client.mojom.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class ElectronBrowserContext;
|
||||
|
||||
class ResolveProxyHelper
|
||||
: public base::RefCountedThreadSafe<ResolveProxyHelper>,
|
||||
network::mojom::ProxyLookupClient {
|
||||
public:
|
||||
using ResolveProxyCallback = base::OnceCallback<void(std::string)>;
|
||||
|
||||
explicit ResolveProxyHelper(ElectronBrowserContext* browser_context);
|
||||
explicit ResolveProxyHelper(network::mojom::NetworkContext* network_context);
|
||||
|
||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||
|
||||
|
@ -71,7 +70,7 @@ class ResolveProxyHelper
|
|||
mojo::Receiver<network::mojom::ProxyLookupClient> receiver_{this};
|
||||
|
||||
// Weak Ref
|
||||
raw_ptr<ElectronBrowserContext> browser_context_;
|
||||
raw_ptr<network::mojom::NetworkContext> network_context_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue