Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* 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,
"use strict";
const { ContextualIdentityListener } = ChromeUtils.importESModule(
"chrome://remote/content/shared/listeners/ContextualIdentityListener.sys.mjs"
);
const { HttpServer } = ChromeUtils.importESModule(
);
// eslint-disable-next-line mozilla/no-redeclare-with-import-autofix
const { ProxyConfiguration } = ChromeUtils.importESModule(
"chrome://remote/content/shared/webdriver/Capabilities.sys.mjs"
);
const { ProxyPerUserContextManager } = ChromeUtils.importESModule(
"chrome://remote/content/webdriver-bidi/ProxyPerUserContextManager.sys.mjs"
);
const gOverride = Cc["@mozilla.org/network/native-dns-override;1"].getService(
Ci.nsINativeDNSResolverOverride
);
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["network.proxy.allow_hijacking_localhost", true]],
});
gOverride.addIPOverride("test1.example.com", "127.0.0.1");
registerCleanupFunction(async () => {
gOverride.clearOverrides();
});
});
add_task(async function test_manual_http_proxy_per_user_context() {
const [serverURL, proxyURL] = createHTTPProxy();
const proxyManager = new ProxyPerUserContextManager();
const userContext = ContextualIdentityService.create("test_name");
const { userContextId } = userContext;
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, serverURL, {
userContextId,
});
const browserInUserContext = tabInUserContext.linkedBrowser;
info("Set up a manual proxy for user context");
const proxyConfiguration = ProxyConfiguration.fromJSON({
proxyType: "manual",
httpProxy: proxyURL,
});
proxyManager.addConfiguration(userContextId, proxyConfiguration);
info("Verify that navigation request in user context is proxied");
await isPageProxied(browserInUserContext, serverURL);
const tabInDefaultUserContext = BrowserTestUtils.addTab(gBrowser, serverURL);
const browserInDefaultUserContext = tabInDefaultUserContext.linkedBrowser;
info("Verify that navigation request in default user context is not proxied");
await isPageNotProxied(browserInDefaultUserContext, serverURL);
info("Destroy proxy manager");
proxyManager.destroy();
info("Verify that navigation request in user context is not proxied");
await isPageNotProxied(browserInUserContext, serverURL);
BrowserTestUtils.removeTab(tabInUserContext);
ContextualIdentityService.remove(userContextId);
BrowserTestUtils.removeTab(tabInDefaultUserContext);
});
add_task(async function test_manual_http_proxy_per_user_context_with_noProxy() {
const [serverURL, proxyURL] = createHTTPProxy();
const proxyManager = new ProxyPerUserContextManager();
const userContext = ContextualIdentityService.create("test_name");
const { userContextId } = userContext;
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, serverURL, {
userContextId,
});
const browserInUserContext = tabInUserContext.linkedBrowser;
info("Set up a manual proxy for user context with `noProxy` field");
const proxyConfiguration = ProxyConfiguration.fromJSON({
proxyType: "manual",
httpProxy: proxyURL,
noProxy: ["test1.example.com"],
});
proxyManager.addConfiguration(userContextId, proxyConfiguration);
info("Verify that navigation request is not proxied");
await isPageNotProxied(browserInUserContext, serverURL);
proxyManager.destroy();
BrowserTestUtils.removeTab(tabInUserContext);
ContextualIdentityService.remove(userContextId);
});
add_task(
async function test_manual_http_proxy_per_user_context_with_noProxy_with_url_pattern() {
const [serverURL, proxyURL, secondServerURL] = createHTTPProxy();
const proxyManager = new ProxyPerUserContextManager();
const userContext = ContextualIdentityService.create("test_name");
const { userContextId } = userContext;
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, serverURL, {
userContextId,
});
const browserInUserContext = tabInUserContext.linkedBrowser;
info(
"Set up a manual proxy for user context with `noProxy` field for an URL pattern"
);
const proxyConfiguration = ProxyConfiguration.fromJSON({
proxyType: "manual",
httpProxy: proxyURL,
noProxy: [".example.com"],
});
proxyManager.addConfiguration(userContextId, proxyConfiguration);
info("Verify that navigation request is not proxied");
await isPageNotProxied(browserInUserContext, serverURL);
info("Verify that navigation to url not matching the pattern is proxied");
await isPageProxied(browserInUserContext, secondServerURL);
proxyManager.destroy();
BrowserTestUtils.removeTab(tabInUserContext);
ContextualIdentityService.remove(userContextId);
}
);
add_task(async function test_override_manual_http_proxy_per_user_context() {
const [serverURL, proxyURL] = createHTTPProxy();
const proxyManager = new ProxyPerUserContextManager();
const userContext = ContextualIdentityService.create("test_name");
const { userContextId } = userContext;
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, serverURL, {
userContextId,
});
const browserInUserContext = tabInUserContext.linkedBrowser;
info("Set up a manual proxy for user context");
const proxyConfiguration = ProxyConfiguration.fromJSON({
proxyType: "manual",
httpProxy: proxyURL,
});
proxyManager.addConfiguration(userContextId, proxyConfiguration);
info("Verify that navigation request is proxied");
await isPageProxied(browserInUserContext, serverURL);
info("Set a new proxy configuration for user context with direct proxy");
const newProxyConfiguration = ProxyConfiguration.fromJSON({
proxyType: "direct",
});
proxyManager.addConfiguration(userContextId, newProxyConfiguration);
info("Verify that navigation request is not proxied");
await isPageNotProxied(browserInUserContext, serverURL);
proxyManager.destroy();
BrowserTestUtils.removeTab(tabInUserContext);
ContextualIdentityService.remove(userContextId);
});
add_task(
async function test_override_global_manual_proxy_with_direct_proxy_per_user_context() {
const [serverURL, proxyURL] = createHTTPProxy();
info("Set up a global manual proxy");
const globalProxy = ProxyConfiguration.fromJSON({
proxyType: "manual",
httpProxy: proxyURL,
});
globalProxy.init();
const tabInDefaultUserContext = BrowserTestUtils.addTab(
gBrowser,
serverURL
);
const browserInDefaultUserContext = tabInDefaultUserContext.linkedBrowser;
info("Verify that navigation request is proxied");
await isPageProxied(browserInDefaultUserContext, serverURL);
const proxyManager = new ProxyPerUserContextManager();
const userContext = ContextualIdentityService.create("test_name");
const { userContextId } = userContext;
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, serverURL, {
userContextId,
});
const browserInUserContext = tabInUserContext.linkedBrowser;
info("Set up a direct proxy for user context");
const proxyConfiguration = ProxyConfiguration.fromJSON({
proxyType: "direct",
});
proxyManager.addConfiguration(userContextId, proxyConfiguration);
info("Verify that navigation request is not proxied");
await isPageNotProxied(browserInUserContext, serverURL);
proxyManager.destroy();
globalProxy.destroy();
BrowserTestUtils.removeTab(tabInUserContext);
ContextualIdentityService.remove(userContextId);
BrowserTestUtils.removeTab(tabInDefaultUserContext);
}
);
add_task(
async function test_override_global_system_proxy_with_direct_proxy_per_user_context() {
const [serverURL] = createHTTPProxy();
info("Set up a global system proxy");
const globalProxy = ProxyConfiguration.fromJSON({
proxyType: "system",
});
globalProxy.init();
const proxyManager = new ProxyPerUserContextManager();
const userContext = ContextualIdentityService.create("test_name");
const { userContextId } = userContext;
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, serverURL, {
userContextId,
});
const browserInUserContext = tabInUserContext.linkedBrowser;
info("Set up a direct proxy for user context");
const proxyConfiguration = ProxyConfiguration.fromJSON({
proxyType: "direct",
});
proxyManager.addConfiguration(userContextId, proxyConfiguration);
info("Verify that navigation request is not proxied");
await isPageNotProxied(browserInUserContext, serverURL);
proxyManager.destroy();
globalProxy.destroy();
BrowserTestUtils.removeTab(tabInUserContext);
ContextualIdentityService.remove(userContextId);
}
);
add_task(
async function test_delete_configuration_for_manual_http_proxy_per_user_context() {
const [serverURL, proxyURL] = createHTTPProxy();
const proxyManager = new ProxyPerUserContextManager();
const userContext = ContextualIdentityService.create("test_name");
const { userContextId } = userContext;
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, serverURL, {
userContextId,
});
const browserInUserContext = tabInUserContext.linkedBrowser;
info("Set up a manual proxy for user context");
const proxyConfiguration = ProxyConfiguration.fromJSON({
proxyType: "manual",
httpProxy: proxyURL,
});
proxyManager.addConfiguration(userContextId, proxyConfiguration);
info("Verify that navigation request is proxied");
await isPageProxied(browserInUserContext, serverURL);
info("Delete the proxy configuration");
proxyManager.deleteConfiguration(userContextId);
info("Verify that navigation request is not proxied");
await isPageNotProxied(browserInUserContext, serverURL);
info("Try to delete the configuration again");
proxyManager.deleteConfiguration(userContextId);
proxyManager.destroy();
BrowserTestUtils.removeTab(tabInUserContext);
ContextualIdentityService.remove(userContextId);
}
);
function createHTTPProxy() {
const server = new HttpServer();
server.start(-1);
server.identity.add("http", "test1.example.com", server.identity.primaryPort);
server.identity.add("http", "example.com", server.identity.primaryPort);
server.registerPathHandler("/", (request, response) => {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "text/plain", true);
response.write("Not proxied");
});
const proxyServer = new HttpServer();
proxyServer.start(-1);
proxyServer.identity.add(
"http",
"test1.example.com",
server.identity.primaryPort
);
proxyServer.identity.add("http", "example.com", server.identity.primaryPort);
proxyServer.registerPathHandler("/", (request, response) => {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "text/plain", true);
response.write("Proxied");
});
registerCleanupFunction(async () => {
await server.stop();
await proxyServer.stop();
});
return [
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
`localhost:${proxyServer.identity.primaryPort}`,
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
];
}
async function isPageProxied(browser, url) {
await loadPage(browser, url);
return SpecialPowers.spawn(browser, [], async () => {
Assert.strictEqual(
content.document.body.textContent,
"Proxied",
"The page was proxied"
);
});
}
async function isPageNotProxied(browser, url) {
await loadPage(browser, url);
return SpecialPowers.spawn(browser, [], async () => {
Assert.strictEqual(
content.document.body.textContent,
"Not proxied",
"The page was not proxied"
);
});
}
async function loadPage(browser, url) {
const loadedPromise = BrowserTestUtils.browserLoaded(browser);
BrowserTestUtils.startLoadingURIString(browser, url);
return loadedPromise;
}