This is all automated changes apart from ShellService.sys.mjs. Differential Revision: https://phabricator.services.mozilla.com/D268194
185 lines
4.9 KiB
JavaScript
185 lines
4.9 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
|
|
|
const lazy = {};
|
|
|
|
ChromeUtils.defineESModuleGetters(lazy, {
|
|
ProxyTypes: "chrome://remote/content/shared/webdriver/Capabilities.sys.mjs",
|
|
});
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(
|
|
lazy,
|
|
"protocolProxyService",
|
|
"@mozilla.org/network/protocol-proxy-service;1",
|
|
Ci.nsIProtocolProxyService
|
|
);
|
|
|
|
const nsIProtocolProxyChannelFilter = ChromeUtils.generateQI([
|
|
Ci.nsIProtocolProxyChannelFilter,
|
|
]);
|
|
|
|
// The maximum uint32 value.
|
|
const PR_UINT32_MAX = 4294967295;
|
|
|
|
/**
|
|
* A ProxyPerUserContextManager class keeps track of user contexts and their proxy configuration.
|
|
*/
|
|
export class ProxyPerUserContextManager {
|
|
#channelProxyFilter;
|
|
#proxyFilterRegistered;
|
|
#userContextToProxyConfiguration;
|
|
|
|
constructor() {
|
|
this.#proxyFilterRegistered = false;
|
|
|
|
// A map between internal user context ids and proxy configurations.
|
|
this.#userContextToProxyConfiguration = new Map();
|
|
}
|
|
|
|
destroy() {
|
|
this.#userContextToProxyConfiguration = new Map();
|
|
|
|
this.#unregisterProxyFilter();
|
|
}
|
|
|
|
/**
|
|
* Add proxy configuration for a provided user context id.
|
|
*
|
|
* @param {string} userContextId
|
|
* Internal user context id.
|
|
* @param {Proxy} proxy
|
|
* Proxy configuration.
|
|
*/
|
|
addConfiguration(userContextId, proxy) {
|
|
this.#userContextToProxyConfiguration.set(userContextId, proxy);
|
|
|
|
this.#registerProxyFilter();
|
|
}
|
|
|
|
/**
|
|
* Delete proxy configuration for a provided user context id.
|
|
*
|
|
* @param {string} userContextId
|
|
* Internal user context id.
|
|
*/
|
|
deleteConfiguration(userContextId) {
|
|
this.#userContextToProxyConfiguration.delete(userContextId);
|
|
|
|
this.#unregisterProxyFilter();
|
|
}
|
|
|
|
#addProxyFilter(proxyFilter, proxySettings) {
|
|
const { host, port, type } = proxySettings;
|
|
|
|
proxyFilter.onProxyFilterResult(
|
|
lazy.protocolProxyService.newProxyInfo(
|
|
type,
|
|
host,
|
|
port,
|
|
"" /* aProxyAuthorizationHeader */,
|
|
"" /* aConnectionIsolationKey */,
|
|
Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST /* aFlags */,
|
|
PR_UINT32_MAX /* aFailoverTimeout */,
|
|
null /* failover proxy */
|
|
)
|
|
);
|
|
}
|
|
|
|
#applyFilter = (channel, defaultProxyInfo, proxyFilter) => {
|
|
const originAttributes =
|
|
channel.loadInfo && channel.loadInfo.originAttributes;
|
|
|
|
if (
|
|
this.#userContextToProxyConfiguration.has(originAttributes.userContextId)
|
|
) {
|
|
const proxyInfo = this.#userContextToProxyConfiguration.get(
|
|
originAttributes.userContextId
|
|
);
|
|
|
|
if (proxyInfo.proxyType === lazy.ProxyTypes.Direct) {
|
|
proxyFilter.onProxyFilterResult(null);
|
|
|
|
return;
|
|
}
|
|
|
|
if (proxyInfo.proxyType === lazy.ProxyTypes.Manual) {
|
|
const channelURI = channel.originalURI;
|
|
for (const url of proxyInfo.noProxy ?? []) {
|
|
if (
|
|
(url.startsWith(".") && channelURI.host.endsWith(url)) ||
|
|
(!url.startsWith(".") && channelURI.host === url)
|
|
) {
|
|
proxyFilter.onProxyFilterResult(defaultProxyInfo);
|
|
|
|
// If at least one element from noProxy matches the channel URL no need to check further.
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (proxyInfo.httpProxy) {
|
|
this.#addProxyFilter(proxyFilter, {
|
|
host: proxyInfo.httpProxy,
|
|
port: proxyInfo.httpProxyPort,
|
|
type: "http",
|
|
});
|
|
}
|
|
|
|
if (proxyInfo.sslProxy) {
|
|
this.#addProxyFilter(proxyFilter, {
|
|
host: proxyInfo.sslProxy,
|
|
port: proxyInfo.sslProxyPort,
|
|
type: "https",
|
|
});
|
|
}
|
|
|
|
if (proxyInfo.socksProxy) {
|
|
this.#addProxyFilter(proxyFilter, {
|
|
host: proxyInfo.socksProxy,
|
|
port: proxyInfo.socksProxyPort,
|
|
type:
|
|
proxyInfo.socksVersion === 5
|
|
? "socks"
|
|
: `socks${proxyInfo.socksVersion}`,
|
|
});
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
proxyFilter.onProxyFilterResult(defaultProxyInfo);
|
|
};
|
|
|
|
#registerProxyFilter() {
|
|
if (!this.#proxyFilterRegistered) {
|
|
this.#proxyFilterRegistered = true;
|
|
|
|
this.#channelProxyFilter = {
|
|
QueryInterface: nsIProtocolProxyChannelFilter,
|
|
applyFilter: this.#applyFilter,
|
|
};
|
|
|
|
lazy.protocolProxyService.registerChannelFilter(
|
|
this.#channelProxyFilter,
|
|
0 /* set position `0` to override global filters */
|
|
);
|
|
}
|
|
}
|
|
|
|
#unregisterProxyFilter() {
|
|
if (
|
|
this.#proxyFilterRegistered &&
|
|
this.#userContextToProxyConfiguration.size === 0
|
|
) {
|
|
this.#proxyFilterRegistered = false;
|
|
lazy.protocolProxyService.unregisterChannelFilter(
|
|
this.#channelProxyFilter
|
|
);
|
|
this.#channelProxyFilter = null;
|
|
}
|
|
}
|
|
}
|