fune/toolkit/components/extensions/test/xpcshell/test_proxy_scripts_results.js
Kris Maglione e930b89c34 Bug 1514594: Part 3 - Change ChromeUtils.import API.
***
Bug 1514594: Part 3a - Change ChromeUtils.import to return an exports object; not pollute global. r=mccr8

This changes the behavior of ChromeUtils.import() to return an exports object,
rather than a module global, in all cases except when `null` is passed as a
second argument, and changes the default behavior not to pollute the global
scope with the module's exports. Thus, the following code written for the old
model:

  ChromeUtils.import("resource://gre/modules/Services.jsm");

is approximately the same as the following, in the new model:

  var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");

Since the two behaviors are mutually incompatible, this patch will land with a
scripted rewrite to update all existing callers to use the new model rather
than the old.
***
Bug 1514594: Part 3b - Mass rewrite all JS code to use the new ChromeUtils.import API. rs=Gijs

This was done using the followng script:

https://bitbucket.org/kmaglione/m-c-rewrites/src/tip/processors/cu-import-exports.jsm
***
Bug 1514594: Part 3c - Update ESLint plugin for ChromeUtils.import API changes. r=Standard8

Differential Revision: https://phabricator.services.mozilla.com/D16747
***
Bug 1514594: Part 3d - Remove/fix hundreds of duplicate imports from sync tests. r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D16748
***
Bug 1514594: Part 3e - Remove no-op ChromeUtils.import() calls. r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D16749
***
Bug 1514594: Part 3f.1 - Cleanup various test corner cases after mass rewrite. r=Gijs
***
Bug 1514594: Part 3f.2 - Cleanup various non-test corner cases after mass rewrite. r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D16750

--HG--
extra : rebase_source : 359574ee3064c90f33bf36c2ebe3159a24cc8895
extra : histedit_source : b93c8f42808b1599f9122d7842d2c0b3e656a594%2C64a3a4e3359dc889e2ab2b49461bab9e27fc10a7
2019-01-17 10:18:31 -08:00

341 lines
10 KiB
JavaScript

"use strict";
/* eslint no-unused-vars: ["error", {"args": "none", "varsIgnorePattern": "^(FindProxyForURL)$"}] */
XPCOMUtils.defineLazyServiceGetter(this, "gProxyService",
"@mozilla.org/network/protocol-proxy-service;1",
"nsIProtocolProxyService");
const TRANSPARENT_PROXY_RESOLVES_HOST = Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST;
let extension;
add_task(async function setup() {
let extensionData = {
manifest: {
"permissions": ["proxy"],
},
background() {
browser.proxy.onProxyError.addListener(error => {
browser.test.sendMessage("proxy-error-received", error);
});
browser.test.onMessage.addListener((message, data) => {
if (message === "set-proxy") {
browser.runtime.sendMessage(data, {toProxyScript: true}).then(response => {
browser.test.sendMessage("proxy-set", response);
});
}
});
browser.proxy.register("proxy.js").then(() => {
browser.test.sendMessage("ready");
});
},
files: {
"proxy.js": `"use strict";
let settings = {proxy: null};
function FindProxyForURL(url, host) {
return settings.proxy;
}
browser.runtime.onMessage.addListener((msg, sender, respond) => {
if (msg.proxy) {
settings.proxy = msg.proxy;
return Promise.resolve(settings.proxy);
}
});
`,
},
};
extension = ExtensionTestUtils.loadExtension(extensionData);
await extension.startup();
await extension.awaitMessage("ready");
});
async function setupProxyScript(proxy) {
extension.sendMessage("set-proxy", {proxy});
let proxyInfoSent = await extension.awaitMessage("proxy-set");
deepEqual(proxyInfoSent, proxy, "got back proxy data from proxy script");
}
async function testProxyResolution(test) {
let {proxy, expected} = test;
let errorMsg;
if (expected.error) {
errorMsg = extension.awaitMessage("proxy-error-received");
}
let proxyInfo = await new Promise((resolve, reject) => {
let channel = NetUtil.newChannel({
uri: "http://www.mozilla.org/",
loadUsingSystemPrincipal: true,
});
gProxyService.asyncResolve(channel, 0, {
onProxyAvailable(req, uri, pi, status) {
resolve(pi && pi.QueryInterface(Ci.nsIProxyInfo));
},
});
});
let expectedProxyInfo = expected.proxyInfo;
if (expected.error) {
equal(proxyInfo, null, "Expected proxyInfo to be null");
equal((await errorMsg).message, expected.error, "error received");
} else if (proxy == null) {
equal(proxyInfo, expectedProxyInfo, "proxy is direct");
} 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, `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;
}
}
}
add_task(async function test_pac_results() {
let tests = [
{
proxy: undefined,
expected: {
error: "ProxyInfoData: proxyData must be a string or array of objects",
},
},
{
proxy: 5,
expected: {
error: "ProxyInfoData: proxyData must be a string or array of objects",
},
},
{
proxy: "INVALID",
expected: {
error: "ProxyInfoData: Unrecognized proxy type: \"invalid\"",
},
},
{
proxy: "SOCKS",
expected: {
error: "ProxyInfoData: Invalid host or port from proxy rule: \"SOCKS\"",
},
},
{
proxy: "PROXY 1.2.3.4:8080 EXTRA",
expected: {
error: "ProxyInfoData: Invalid arguments passed for proxy rule: \"PROXY 1.2.3.4:8080 EXTRA\"",
},
},
{
proxy: "PROXY :",
expected: {
error: "ProxyInfoData: Invalid host or port from proxy rule: \"PROXY :\"",
},
},
{
proxy: "PROXY :8080",
expected: {
error: "ProxyInfoData: Invalid host or port from proxy rule: \"PROXY :8080\"",
},
},
{
proxy: "PROXY ::",
expected: {
error: "ProxyInfoData: Invalid host or port from proxy rule: \"PROXY ::\"",
},
},
{
proxy: "PROXY 1.2.3.4:",
expected: {
error: "ProxyInfoData: Invalid host or port from proxy rule: \"PROXY 1.2.3.4:\"",
},
},
{
proxy: "DIRECT 1.2.3.4:8080",
expected: {
error: "ProxyInfoData: Invalid argument for proxy type: \"direct\"",
},
},
{
proxy: ["SOCKS foo.bar:1080", {type: "http", host: "foo.bar", port: 3128}],
expected: {
error: "ProxyInfoData: Invalid proxy server type: \"undefined\"",
},
},
{
proxy: {type: "socks", host: "foo.bar", port: 1080, username: "mungosantamaria", password: "pass123"},
expected: {
error: "ProxyInfoData: proxyData must be a string or array of objects",
},
},
{
proxy: [{type: "pptp", host: "foo.bar", port: 1080, username: "mungosantamaria", password: "pass123", proxyDNS: true, failoverTimeout: 3},
{type: "http", host: "192.168.1.1", port: 1128, username: "mungosantamaria", password: "word321"}],
expected: {
error: "ProxyInfoData: Invalid proxy server type: \"pptp\"",
},
},
{
proxy: [{type: "http", host: "foo.bar", port: 65536, username: "mungosantamaria", password: "pass123", proxyDNS: true, failoverTimeout: 3},
{type: "http", host: "192.168.1.1", port: 3128, username: "mungosantamaria", password: "word321"}],
expected: {
error: "ProxyInfoData: Proxy server port 65536 outside range 1 to 65535",
},
},
{
proxy: [{type: "direct"}],
expected: {
proxyInfo: null,
},
},
{
proxy: "PROXY 1.2.3.4:8080",
expected: {
proxyInfo: {
host: "1.2.3.4",
port: "8080",
type: "http",
failoverProxy: null,
},
},
},
{
proxy: " PROXY 2.3.4.5:8080 ",
expected: {
proxyInfo: {
host: "2.3.4.5",
port: "8080",
type: "http",
failoverProxy: null,
},
},
},
{
proxy: "PROXY 1.2.3.4:8080; SOCKS 4.4.4.4:9000; DIRECT",
expected: {
proxyInfo: {
host: "1.2.3.4",
port: "8080",
type: "http",
failoverProxy: {
host: "4.4.4.4",
port: "9000",
type: "socks",
failoverProxy: {
type: "direct",
host: null,
port: -1,
},
},
},
},
},
{
proxy: [{type: "http", host: "foo.bar", port: 3128}],
expected: {
proxyInfo: {
host: "foo.bar",
port: "3128",
type: "http",
},
},
},
{
proxy: "SOCKS foo.bar:1080",
expected: {
proxyInfo: {
host: "foo.bar",
port: "1080",
type: "socks",
},
},
},
{
proxy: "SOCKS4 foo.bar:1080",
expected: {
proxyInfo: {
host: "foo.bar",
port: "1080",
type: "socks4",
},
},
},
{
proxy: [{type: "https", host: "foo.bar", port: 3128}],
expected: {
proxyInfo: {
host: "foo.bar",
port: "3128",
type: "https",
},
},
},
{
proxy: [{type: "socks", host: "foo.bar", port: 1080, username: "mungo", password: "santamaria123", proxyDNS: true, failoverTimeout: 5}],
expected: {
proxyInfo: {
type: "socks",
host: "foo.bar",
port: 1080,
username: "mungo",
password: "santamaria123",
failoverTimeout: 5,
failoverProxy: null,
proxyDNS: TRANSPARENT_PROXY_RESOLVES_HOST,
},
},
},
{
proxy: [{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"}],
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",
},
},
},
},
},
},
},
];
for (let test of tests) {
await setupProxyScript(test.proxy);
await testProxyResolution(test);
// Our proxy script for testing is stateless, so repeating the test should
// yield exactly the same results.
await testProxyResolution(test);
}
});
add_task(async function shutdown() {
await extension.unload();
});