From a2254476532bab6552c8b23db7f1c09cb85876c3 Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Fri, 7 Aug 2020 15:38:06 -0700 Subject: [PATCH] browser(firefox): introduce global proxy (#3335) This will be used instead of messing up user preferences for proxy setup. --- browser_patches/firefox/BUILD_NUMBER | 4 ++-- .../firefox/juggler/NetworkObserver.js | 16 +++++++------- .../firefox/juggler/TargetRegistry.js | 22 ++++++++++++++++++- .../juggler/protocol/BrowserHandler.js | 9 ++++++-- .../firefox/juggler/protocol/Protocol.js | 14 +++++++++++- 5 files changed, 51 insertions(+), 14 deletions(-) diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index 432da8e167..a644ec8dc2 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -1,2 +1,2 @@ -1154 -Changed: lushnikov@chromium.org Thu Aug 6 10:22:22 PDT 2020 +1155 +Changed: lushnikov@chromium.org Fri Aug 7 15:25:51 PDT 2020 diff --git a/browser_patches/firefox/juggler/NetworkObserver.js b/browser_patches/firefox/juggler/NetworkObserver.js index f1126bdfe5..8a7088a9bb 100644 --- a/browser_patches/firefox/juggler/NetworkObserver.js +++ b/browser_patches/firefox/juggler/NetworkObserver.js @@ -297,7 +297,13 @@ class NetworkRequest { if (!pageNetwork) return false; const browserContext = pageNetwork._target.browserContext(); - const credentials = browserContext ? browserContext.httpCredentials : undefined; + let credentials = null; + if (authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) { + const proxy = this._networkObserver._targetRegistry.getProxyInfo(aChannel); + credentials = proxy ? {username: proxy.username, password: proxy.password} : null; + } else { + credentials = browserContext ? browserContext.httpCredentials : undefined; + } if (!credentials) return false; authInfo.username = credentials.username; @@ -569,17 +575,11 @@ class NetworkObserver { this._channelProxyFilter = { QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolProxyChannelFilter]), applyFilter: (channel, defaultProxyInfo, proxyFilter) => { - const originAttributes = channel.loadInfo && channel.loadInfo.originAttributes; - const browserContext = originAttributes ? this._targetRegistry.browserContextForUserContextId(originAttributes.userContextId) : null; - const proxy = browserContext ? browserContext.proxy : null; + const proxy = this._targetRegistry.getProxyInfo(channel); if (!proxy) { proxyFilter.onProxyFilterResult(defaultProxyInfo); return; } - if (proxy.bypass.some(domain => channel.URI.host.endsWith(domain))) { - proxyFilter.onProxyFilterResult(defaultProxyInfo); - return; - } proxyFilter.onProxyFilterResult(protocolProxyService.newProxyInfo( proxy.type, proxy.host, diff --git a/browser_patches/firefox/juggler/TargetRegistry.js b/browser_patches/firefox/juggler/TargetRegistry.js index 49cfdeb7b0..105ec0702f 100644 --- a/browser_patches/firefox/juggler/TargetRegistry.js +++ b/browser_patches/firefox/juggler/TargetRegistry.js @@ -113,6 +113,8 @@ class TargetRegistry { this._browserToTarget = new Map(); this._browserBrowsingContextToTarget = new Map(); + this._browserProxy = null; + // Cleanup containers from previous runs (if any) for (const identity of ContextualIdentityService.getPublicIdentities()) { if (identity.name && identity.name.startsWith(IDENTITY_NAME)) { @@ -241,6 +243,20 @@ class TargetRegistry { extHelperAppSvc.setDownloadInterceptor(new DownloadInterceptor(this)); } + setBrowserProxy(proxy) { + this._browserProxy = proxy; + } + + getProxyInfo(channel) { + const originAttributes = channel.loadInfo && channel.loadInfo.originAttributes; + const browserContext = originAttributes ? this.browserContextForUserContextId(originAttributes.userContextId) : null; + // Prefer context proxy and fallback to browser-level proxy. + const proxyInfo = (browserContext && browserContext._proxy) || this._browserProxy; + if (!proxyInfo || proxyInfo.bypass.some(domainSuffix => channel.URI.host.endsWith(domainSuffix))) + return null; + return proxyInfo; + } + defaultContext() { return this._defaultContext; } @@ -473,8 +489,8 @@ class BrowserContext { this._permissions = new Map(); this._registry._browserContextIdToBrowserContext.set(this.browserContextId, this); this._registry._userContextIdToBrowserContext.set(this.userContextId, this); + this._proxy = null; this.removeOnDetach = removeOnDetach; - this.proxy = undefined; this.extraHTTPHeaders = undefined; this.httpCredentials = undefined; this.requestInterceptionEnabled = undefined; @@ -507,6 +523,10 @@ class BrowserContext { this._registry._userContextIdToBrowserContext.delete(this.userContextId); } + setProxy(proxy) { + this._proxy = proxy; + } + setIgnoreHTTPSErrors(ignoreHTTPSErrors) { if (this.ignoreHTTPSErrors === ignoreHTTPSErrors) return; diff --git a/browser_patches/firefox/juggler/protocol/BrowserHandler.js b/browser_patches/firefox/juggler/protocol/BrowserHandler.js index a9a06f2a41..50e7a9ba38 100644 --- a/browser_patches/firefox/juggler/protocol/BrowserHandler.js +++ b/browser_patches/firefox/juggler/protocol/BrowserHandler.js @@ -151,8 +151,13 @@ class BrowserHandler { this._targetRegistry.browserContextForId(browserContextId).httpCredentials = nullToUndefined(credentials); } - async setProxy({browserContextId, type, host, port, bypass}) { - this._targetRegistry.browserContextForId(browserContextId).proxy = { type, host, port, bypass }; + async setBrowserProxy({type, host, port, bypass, username, password}) { + this._targetRegistry.setBrowserProxy({ type, host, port, bypass, username, password}); + } + + async setContextProxy({browserContextId, type, host, port, bypass, username, password}) { + const browserContext = this._targetRegistry.browserContextForId(browserContextId); + browserContext.setProxy({ type, host, port, bypass, username, password }); } setRequestInterception({browserContextId, enabled}) { diff --git a/browser_patches/firefox/juggler/protocol/Protocol.js b/browser_patches/firefox/juggler/protocol/Protocol.js index 23e47e7340..5a6822694e 100644 --- a/browser_patches/firefox/juggler/protocol/Protocol.js +++ b/browser_patches/firefox/juggler/protocol/Protocol.js @@ -258,13 +258,25 @@ const Browser = { headers: t.Array(networkTypes.HTTPHeader), }, }, - 'setProxy': { + 'setBrowserProxy': { + params: { + type: t.Enum(['http', 'https', 'socks', 'socks4']), + bypass: t.Array(t.String), + host: t.String, + port: t.Number, + username: t.Optional(t.String), + password: t.Optional(t.String), + }, + }, + 'setContextProxy': { params: { browserContextId: t.Optional(t.String), type: t.Enum(['http', 'https', 'socks', 'socks4']), bypass: t.Array(t.String), host: t.String, port: t.Number, + username: t.Optional(t.String), + password: t.Optional(t.String), }, }, 'setHTTPCredentials': {