Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* This test checks that a TRRServiceChannel can connect to the server with
a proxy.
Steps:
- Setup the proxy (PAC, proxy filter, and system proxy settings)
- Test when "network.trr.async_connInfo" is false. In this case, every
TRRServicChannel waits for the proxy info to be resolved.
- Test when "network.trr.async_connInfo" is true. In this case, every
TRRServicChannel uses an already created connection info to connect.
- The test test_trr_uri_change() is about checking if trr connection info
is updated correctly when trr uri changed.
*/
"use strict";
var { setTimeout } = ChromeUtils.importESModule(
);
/* import-globals-from trr_common.js */
let filter;
let systemProxySettings;
let trrProxy;
const pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService();
function setup() {
h2Port = trr_test_setup();
SetParentalControlEnabled(false);
}
setup();
registerCleanupFunction(async () => {
trr_clear_prefs();
Services.prefs.clearUserPref("network.proxy.type");
Services.prefs.clearUserPref("network.proxy.autoconfig_url");
Services.prefs.clearUserPref("network.trr.async_connInfo");
if (trrProxy) {
await trrProxy.stop();
}
});
class ProxyFilter {
constructor(type, host, port, flags) {
this._type = type;
this._host = host;
this._port = port;
this._flags = flags;
this.QueryInterface = ChromeUtils.generateQI(["nsIProtocolProxyFilter"]);
}
applyFilter(uri, pi, cb) {
cb.onProxyFilterResult(
pps.newProxyInfo(
this._type,
this._host,
this._port,
"",
"",
this._flags,
1000,
null
)
);
}
}
async function doTest(proxySetup, delay) {
info("Verifying a basic A record");
Services.dns.clearCache(true);
// Close all previous connections.
Services.obs.notifyObservers(null, "net:cancel-all-connections");
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 1000));
setModeAndURI(2, "doh?responseIP=2.2.2.2"); // TRR-first
trrProxy = new TRRProxy();
await trrProxy.start(h2Port);
info("port=" + trrProxy.port);
await proxySetup(trrProxy.port);
if (delay) {
await new Promise(resolve => do_timeout(delay, resolve));
}
await new TRRDNSListener("bar.example.com", "2.2.2.2");
// A non-zero request count indicates that TRR requests are being routed
// through the proxy.
Assert.ok(
(await trrProxy.request_count()) >= 1,
`Request count should be at least 1`
);
// clean up
Services.prefs.clearUserPref("network.proxy.type");
Services.prefs.clearUserPref("network.proxy.autoconfig_url");
if (filter) {
pps.unregisterFilter(filter);
filter = null;
}
if (systemProxySettings) {
MockRegistrar.unregister(systemProxySettings);
systemProxySettings = null;
}
await trrProxy.stop();
trrProxy = null;
}
add_task(async function test_trr_proxy() {
async function setupPACWithDataURL(proxyPort) {
var pac = `data:text/plain, function FindProxyForURL(url, host) { return "HTTPS foo.example.com:${proxyPort}";}`;
Services.prefs.setIntPref("network.proxy.type", 2);
Services.prefs.setCharPref("network.proxy.autoconfig_url", pac);
}
async function setupPACWithHttpURL(proxyPort) {
let httpserv = new HttpServer();
httpserv.registerPathHandler("/", function handler(metadata, response) {
response.setStatusLine(metadata.httpVersion, 200, "OK");
let content = `function FindProxyForURL(url, host) { return "HTTPS foo.example.com:${proxyPort}";}`;
response.setHeader("Content-Length", `${content.length}`);
response.bodyOutputStream.write(content, content.length);
});
httpserv.start(-1);
Services.prefs.setIntPref("network.proxy.type", 2);
let pacUri = `http://127.0.0.1:${httpserv.identity.primaryPort}/`;
Services.prefs.setCharPref("network.proxy.autoconfig_url", pacUri);
function consoleMessageObserved() {
return new Promise(resolve => {
let listener = {
QueryInterface: ChromeUtils.generateQI(["nsIConsoleListener"]),
observe(msg) {
if (msg == `PAC file installed from ${pacUri}`) {
Services.console.unregisterListener(listener);
resolve();
}
},
};
Services.console.registerListener(listener);
});
}
await consoleMessageObserved();
}
async function setupProxyFilter(proxyPort) {
filter = new ProxyFilter("https", "foo.example.com", proxyPort, 0);
pps.registerFilter(filter, 10);
}
async function setupSystemProxySettings(proxyPort) {
systemProxySettings = {
QueryInterface: ChromeUtils.generateQI(["nsISystemProxySettings"]),
mainThreadOnly: true,
PACURI: null,
getProxyForURI: () => {
return `HTTPS foo.example.com:${proxyPort}`;
},
};
MockRegistrar.register(
"@mozilla.org/system-proxy-settings;1",
systemProxySettings
);
Services.prefs.setIntPref(
"network.proxy.type",
Ci.nsIProtocolProxyService.PROXYCONFIG_SYSTEM
);
// simulate that system proxy setting is changed.
pps.notifyProxyConfigChangedInternal();
}
Services.prefs.setBoolPref("network.trr.async_connInfo", false);
await doTest(setupPACWithDataURL);
await doTest(setupPACWithDataURL, 1000);
await doTest(setupPACWithHttpURL);
await doTest(setupPACWithHttpURL, 1000);
await doTest(setupProxyFilter);
await doTest(setupProxyFilter, 1000);
await doTest(setupSystemProxySettings);
await doTest(setupSystemProxySettings, 1000);
Services.prefs.setBoolPref("network.trr.async_connInfo", true);
await doTest(setupPACWithDataURL);
await doTest(setupPACWithDataURL, 1000);
await doTest(setupPACWithHttpURL);
await doTest(setupPACWithHttpURL, 1000);
await doTest(setupProxyFilter);
await doTest(setupProxyFilter, 1000);
await doTest(setupSystemProxySettings);
await doTest(setupSystemProxySettings, 1000);
});
add_task(async function test_trr_uri_change() {
Services.prefs.setIntPref("network.proxy.type", 0);
Services.prefs.setBoolPref("network.trr.async_connInfo", true);
Services.dns.clearCache(true);
setModeAndURI(2, "doh?responseIP=2.2.2.2", "127.0.0.1");
await new TRRDNSListener("car.example.com", "127.0.0.1");
Services.dns.clearCache(true);
setModeAndURI(2, "doh?responseIP=2.2.2.2");
await new TRRDNSListener("car.example.net", "2.2.2.2");
});