summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_proxy_listener.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /toolkit/components/extensions/test/xpcshell/test_proxy_listener.js
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_proxy_listener.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/test_proxy_listener.js298
1 files changed, 298 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_proxy_listener.js b/toolkit/components/extensions/test/xpcshell/test_proxy_listener.js
new file mode 100644
index 0000000000..8cc46d45e7
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_proxy_listener.js
@@ -0,0 +1,298 @@
+"use strict";
+
+XPCOMUtils.defineLazyServiceGetter(
+ this,
+ "gProxyService",
+ "@mozilla.org/network/protocol-proxy-service;1",
+ "nsIProtocolProxyService"
+);
+
+const TRANSPARENT_PROXY_RESOLVES_HOST =
+ Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST;
+
+function getProxyInfo(url = "http://www.mozilla.org/") {
+ return new Promise((resolve, reject) => {
+ let channel = NetUtil.newChannel({
+ uri: url,
+ loadUsingSystemPrincipal: true,
+ });
+
+ gProxyService.asyncResolve(channel, 0, {
+ onProxyAvailable(req, uri, pi, status) {
+ resolve(pi);
+ },
+ });
+ });
+}
+
+const testData = [
+ {
+ // An ExtensionError is thrown for this, but we are unable to catch it as we
+ // do with the PAC script api. In this case, we expect null for proxyInfo.
+ proxyInfo: "not_defined",
+ expected: {
+ proxyInfo: null,
+ },
+ },
+ {
+ proxyInfo: 1,
+ expected: {
+ error: {
+ message:
+ "ProxyInfoData: proxyData must be an object or array of objects",
+ },
+ },
+ },
+ {
+ proxyInfo: [
+ {
+ type: "socks",
+ host: "foo.bar",
+ port: 1080,
+ username: "johnsmith",
+ password: "pass123",
+ proxyDNS: true,
+ failoverTimeout: 3,
+ },
+ { type: "http", host: "192.168.1.1", port: 3128 },
+ { type: "https", host: "192.168.1.2", port: 1121, failoverTimeout: 1 },
+ {
+ type: "socks",
+ host: "192.168.1.3",
+ port: 1999,
+ proxyDNS: true,
+ username: "mungosantamaria",
+ password: "foobar",
+ },
+ { type: "direct" },
+ ],
+ expected: {
+ proxyInfo: {
+ type: "socks",
+ host: "foo.bar",
+ port: 1080,
+ proxyDNS: true,
+ username: "johnsmith",
+ password: "pass123",
+ failoverTimeout: 3,
+ failoverProxy: {
+ host: "192.168.1.1",
+ port: 3128,
+ type: "http",
+ failoverProxy: {
+ host: "192.168.1.2",
+ port: 1121,
+ type: "https",
+ failoverTimeout: 1,
+ failoverProxy: {
+ host: "192.168.1.3",
+ port: 1999,
+ type: "socks",
+ proxyDNS: TRANSPARENT_PROXY_RESOLVES_HOST,
+ username: "mungosantamaria",
+ password: "foobar",
+ failoverProxy: {
+ type: "direct",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+];
+
+add_task(async function test_proxy_listener() {
+ let extensionData = {
+ manifest: {
+ permissions: ["proxy", "<all_urls>"],
+ },
+ background() {
+ // Some tests generate multiple errors, we'll just rely on the first.
+ let seenError = false;
+ let proxyInfo;
+ browser.proxy.onError.addListener(error => {
+ if (!seenError) {
+ browser.test.sendMessage("proxy-error-received", error);
+ seenError = true;
+ }
+ });
+
+ browser.proxy.onRequest.addListener(
+ details => {
+ browser.test.log(`onRequest ${JSON.stringify(details)}`);
+ if (proxyInfo == "not_defined") {
+ return not_defined; // eslint-disable-line no-undef
+ }
+ return proxyInfo;
+ },
+ { urls: ["<all_urls>"] }
+ );
+
+ browser.test.onMessage.addListener((message, data) => {
+ if (message === "set-proxy") {
+ seenError = false;
+ proxyInfo = data.proxyInfo;
+ }
+ });
+
+ browser.test.sendMessage("ready");
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+ await extension.awaitMessage("ready");
+
+ for (let test of testData) {
+ extension.sendMessage("set-proxy", test);
+ let testError = test.expected.error;
+ let errorWait = testError && extension.awaitMessage("proxy-error-received");
+
+ let proxyInfo = await getProxyInfo();
+ let expectedProxyInfo = test.expected.proxyInfo;
+
+ if (testError) {
+ info("waiting for error data");
+ let error = await errorWait;
+ equal(error.message, testError.message, "Correct error message received");
+ equal(proxyInfo, null, "no proxyInfo received");
+ } else if (expectedProxyInfo === null) {
+ equal(proxyInfo, null, "no proxyInfo received");
+ } else {
+ for (
+ let proxyUsed = proxyInfo;
+ proxyUsed;
+ proxyUsed = proxyUsed.failoverProxy
+ ) {
+ let {
+ type,
+ host,
+ port,
+ username,
+ password,
+ proxyDNS,
+ failoverTimeout,
+ } = expectedProxyInfo;
+ equal(proxyUsed.host, host, `Expected proxy host to be ${host}`);
+ equal(proxyUsed.port, port || -1, `Expected proxy port to be ${port}`);
+ equal(proxyUsed.type, type, `Expected proxy type to be ${type}`);
+ // May be null or undefined depending on use of newProxyInfoWithAuth or newProxyInfo
+ equal(
+ proxyUsed.username || "",
+ username || "",
+ `Expected proxy username to be ${username}`
+ );
+ equal(
+ proxyUsed.password || "",
+ password || "",
+ `Expected proxy password to be ${password}`
+ );
+ equal(
+ proxyUsed.flags,
+ proxyDNS == undefined ? 0 : proxyDNS,
+ `Expected proxyDNS to be ${proxyDNS}`
+ );
+ // Default timeout is 10
+ equal(
+ proxyUsed.failoverTimeout,
+ failoverTimeout || 10,
+ `Expected failoverTimeout to be ${failoverTimeout}`
+ );
+ expectedProxyInfo = expectedProxyInfo.failoverProxy;
+ }
+ ok(!expectedProxyInfo, "no left over failoverProxy");
+ }
+ }
+
+ await extension.unload();
+});
+
+async function getExtension(expectedProxyInfo) {
+ function background(proxyInfo) {
+ browser.test.log(
+ `testing proxy.onRequest with proxyInfo = ${JSON.stringify(proxyInfo)}`
+ );
+ browser.proxy.onRequest.addListener(
+ details => {
+ return proxyInfo;
+ },
+ { urls: ["<all_urls>"] }
+ );
+ }
+ let extensionData = {
+ manifest: {
+ permissions: ["proxy", "<all_urls>"],
+ },
+ background: `(${background})(${JSON.stringify(expectedProxyInfo)})`,
+ };
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+ return extension;
+}
+
+add_task(async function test_passthrough() {
+ let ext1 = await getExtension(null);
+ let ext2 = await getExtension({ host: "1.2.3.4", port: 8888, type: "https" });
+
+ // Also use a restricted url to test the ability to proxy those.
+ let proxyInfo = await getProxyInfo("https://addons.mozilla.org/");
+
+ equal(proxyInfo.host, "1.2.3.4", `second extension won`);
+ equal(proxyInfo.port, "8888", `second extension won`);
+ equal(proxyInfo.type, "https", `second extension won`);
+
+ await ext2.unload();
+
+ proxyInfo = await getProxyInfo();
+ equal(proxyInfo, null, `expected no proxy`);
+ await ext1.unload();
+});
+
+add_task(async function test_ftp_disabled() {
+ let extension = await getExtension({
+ host: "1.2.3.4",
+ port: 8888,
+ type: "http",
+ });
+
+ let proxyInfo = await getProxyInfo("ftp://somewhere.mozilla.org/");
+
+ equal(
+ proxyInfo,
+ null,
+ `proxy of ftp request is not available when ftp is disabled`
+ );
+
+ await extension.unload();
+});
+
+add_task(async function test_ws() {
+ let proxyRequestCount = 0;
+ let proxy = createHttpServer();
+ proxy.registerPathHandler("CONNECT", (request, response) => {
+ response.setStatusLine(request.httpVersion, 404, "Proxy not found");
+ ++proxyRequestCount;
+ });
+
+ let extension = await getExtension({
+ host: proxy.identity.primaryHost,
+ port: proxy.identity.primaryPort,
+ type: "http",
+ });
+
+ // We need a page to use the WebSocket constructor, so let's use an extension.
+ let dummy = ExtensionTestUtils.loadExtension({
+ background() {
+ // The connection will not be upgraded to WebSocket, so it will close.
+ let ws = new WebSocket("wss://example.net/");
+ ws.onclose = () => browser.test.sendMessage("websocket_closed");
+ },
+ });
+ await dummy.startup();
+ await dummy.awaitMessage("websocket_closed");
+ await dummy.unload();
+
+ equal(proxyRequestCount, 1, "Expected one proxy request");
+ await extension.unload();
+});