Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* 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/. */
"use strict";
var { setTimeout } = ChromeUtils.importESModule(
"resource://gre/modules/Timer.sys.mjs"
);
const { NodeHTTP2Server, HTTP3Server } = ChromeUtils.importESModule(
);
const override = Cc["@mozilla.org/network/native-dns-override;1"].getService(
Ci.nsINativeDNSResolverOverride
);
const mockController = Cc[
"@mozilla.org/network/mock-network-controller;1"
].getService(Ci.nsIMockNetworkLayerController);
let h3Port;
let h3Server;
let h2Server;
let h3ServerPath;
let h3DBPath;
async function startH3Server() {
h3Server = new HTTP3Server();
await h3Server.start(h3ServerPath, h3DBPath);
h3Port = h3Server.port();
}
async function stopH3Server() {
if (h3Server) {
await h3Server.stop();
h3Server = null;
}
}
add_setup(async function () {
h3ServerPath = Services.env.get("MOZ_HTTP3_SERVER_PATH");
h3DBPath = Services.env.get("MOZ_HTTP3_CERT_DB_PATH");
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
Services.prefs.setBoolPref("network.http.happy_eyeballs_enabled", true);
Services.prefs.setBoolPref("network.http.http3.enable", true);
Services.prefs.setBoolPref("network.socket.attach_mock_network_layer", true);
Services.prefs.setBoolPref("network.socket.ip_addr_any.disabled", true);
// Required for H3 UDP to function on macOS in xpcshell tests.
Services.prefs.setBoolPref("network.http.http3.use_nspr_for_io", true);
h2Server = new NodeHTTP2Server();
await h2Server.start();
await h2Server.registerPathHandler("/", (_req, resp) => {
resp.writeHead(200, { "Content-Type": "text/plain" });
resp.end("ok");
});
registerCleanupFunction(async () => {
Services.prefs.clearUserPref("network.http.happy_eyeballs_enabled");
Services.prefs.clearUserPref("network.http.http3.enable");
Services.prefs.clearUserPref("network.socket.attach_mock_network_layer");
Services.prefs.clearUserPref("network.socket.ip_addr_any.disabled");
Services.prefs.clearUserPref("network.http.http3.use_nspr_for_io");
Services.prefs.clearUserPref(
"network.http.http3.alt-svc-mapping-for-testing"
);
Services.prefs.clearUserPref("network.http.speculative-parallel-limit");
override.clearOverrides();
mockController.clearPausedTCPConnect();
mockController.clearBlockedUDPAddr();
if (h2Server) {
await h2Server.stop();
}
await stopH3Server();
});
});
async function resetConnections() {
Services.obs.notifyObservers(null, "net:cancel-all-connections");
Services.obs.notifyObservers(null, "browser:purge-session-history");
let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent);
await nssComponent.asyncClearSSLExternalAndInternalSessionCache();
Services.dns.clearCache(true);
override.clearOverrides();
mockController.clearPausedTCPConnect();
mockController.clearBlockedUDPAddr();
Services.prefs.clearUserPref(
"network.http.http3.alt-svc-mapping-for-testing"
);
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 1000));
}
async function do_test_any_addr_refused(host, anyAddr) {
await startH3Server();
await resetConnections();
override.addIPOverride(host, anyAddr);
Services.prefs.setCharPref(
"network.http.http3.alt-svc-mapping-for-testing",
`${host};h3=:${h3Port}`
);
let h2Port = h2Server.port();
let chan = NetUtil.newChannel({
uri: `https://${host}:${h2Port}/`,
loadUsingSystemPrincipal: true,
}).QueryInterface(Ci.nsIHttpChannel);
chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
await new Promise(resolve => {
chan.asyncOpen(
new ChannelListener(() => resolve(), null, CL_EXPECT_FAILURE)
);
});
Assert.equal(
chan.status,
Cr.NS_ERROR_CONNECTION_REFUSED,
`Connection to ${anyAddr} must fail with NS_ERROR_CONNECTION_REFUSED`
);
await stopH3Server();
}
add_task(async function test_h3_ipv4_any_addr_refused() {
await do_test_any_addr_refused("zeroip4.example.com", "0.0.0.0");
});
add_task(async function test_h3_ipv6_any_addr_refused() {
await do_test_any_addr_refused("zeroip6.example.com", "::");
});