summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/test_http3_server.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/unit/test_http3_server.js')
-rw-r--r--netwerk/test/unit/test_http3_server.js168
1 files changed, 168 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_http3_server.js b/netwerk/test/unit/test_http3_server.js
new file mode 100644
index 0000000000..3daf9cfa3c
--- /dev/null
+++ b/netwerk/test/unit/test_http3_server.js
@@ -0,0 +1,168 @@
+/* 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";
+
+let h2Port;
+let h3Port;
+let trrServer;
+
+const certOverrideService = Cc[
+ "@mozilla.org/security/certoverride;1"
+].getService(Ci.nsICertOverrideService);
+const { TestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/TestUtils.sys.mjs"
+);
+
+add_setup(async function setup() {
+ h2Port = Services.env.get("MOZHTTP2_PORT");
+ Assert.notEqual(h2Port, null);
+ Assert.notEqual(h2Port, "");
+
+ h3Port = Services.env.get("MOZHTTP3_PORT_PROXY");
+ Assert.notEqual(h3Port, null);
+ Assert.notEqual(h3Port, "");
+
+ trr_test_setup();
+
+ Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
+ Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
+
+ registerCleanupFunction(async () => {
+ trr_clear_prefs();
+ Services.prefs.clearUserPref("network.dns.upgrade_with_https_rr");
+ Services.prefs.clearUserPref("network.dns.use_https_rr_as_altsvc");
+ Services.prefs.clearUserPref("network.dns.disablePrefetch");
+ await trrServer.stop();
+ });
+
+ if (mozinfo.socketprocess_networking) {
+ Services.dns;
+ await TestUtils.waitForCondition(() => Services.io.socketProcessLaunched);
+ }
+});
+
+function makeChan(url) {
+ let chan = NetUtil.newChannel({
+ uri: url,
+ loadUsingSystemPrincipal: true,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
+ }).QueryInterface(Ci.nsIHttpChannel);
+ return chan;
+}
+
+function channelOpenPromise(chan, flags) {
+ return new Promise(resolve => {
+ function finish(req, buffer) {
+ certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
+ false
+ );
+ resolve([req, buffer]);
+ }
+ let internal = chan.QueryInterface(Ci.nsIHttpChannelInternal);
+ internal.setWaitForHTTPSSVCRecord();
+ certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
+ true
+ );
+ chan.asyncOpen(new ChannelListener(finish, null, flags));
+ });
+}
+
+// Use NodeHTTPServer to create an HTTP server and test if the Http/3 server
+// can act as a reverse proxy.
+add_task(async function testHttp3ServerAsReverseProxy() {
+ trrServer = new TRRServer();
+ await trrServer.start();
+ Services.dns.clearCache(true);
+ Services.prefs.setIntPref("network.trr.mode", 3);
+ Services.prefs.setCharPref(
+ "network.trr.uri",
+ `https://foo.example.com:${trrServer.port()}/dns-query`
+ );
+
+ await trrServer.registerDoHAnswers("test.h3_example.com", "HTTPS", {
+ answers: [
+ {
+ name: "test.h3_example.com",
+ ttl: 55,
+ type: "HTTPS",
+ flush: false,
+ data: {
+ priority: 1,
+ name: "test.h3_example.com",
+ values: [
+ { key: "alpn", value: "h3-29" },
+ { key: "port", value: h3Port },
+ ],
+ },
+ },
+ ],
+ });
+
+ await trrServer.registerDoHAnswers("test.h3_example.com", "A", {
+ answers: [
+ {
+ name: "test.h3_example.com",
+ ttl: 55,
+ type: "A",
+ flush: false,
+ data: "127.0.0.1",
+ },
+ ],
+ });
+
+ await new TRRDNSListener("test.h3_example.com", {
+ type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
+ });
+
+ let server = new NodeHTTPServer();
+ await server.start();
+ registerCleanupFunction(async () => {
+ await server.stop();
+ });
+
+ await server.registerPathHandler("/test", (req, resp) => {
+ if (req.method === "GET") {
+ resp.writeHead(200);
+ resp.end("got GET request");
+ } else if (req.method === "POST") {
+ let received = "";
+ req.on("data", function receivePostData(chunk) {
+ received += chunk.toString();
+ });
+ req.on("end", function finishPost() {
+ resp.writeHead(200);
+ resp.end(received);
+ });
+ }
+ });
+
+ // Tell the Http/3 server which port to forward requests.
+ let chan = makeChan(`https://test.h3_example.com/port?${server.port()}`);
+ await channelOpenPromise(chan, CL_ALLOW_UNKNOWN_CL);
+
+ // Test GET method.
+ chan = makeChan(`https://test.h3_example.com/test`);
+ let [req, buf] = await channelOpenPromise(chan, CL_ALLOW_UNKNOWN_CL);
+ Assert.equal(req.protocolVersion, "h3-29");
+ Assert.equal(buf, "got GET request");
+
+ var stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
+ Ci.nsIStringInputStream
+ );
+ stream.data = "b".repeat(500);
+
+ // Test POST method.
+ chan = makeChan(`https://test.h3_example.com/test`);
+ chan
+ .QueryInterface(Ci.nsIUploadChannel)
+ .setUploadStream(stream, "text/plain", stream.available());
+ chan.requestMethod = "POST";
+
+ [req, buf] = await channelOpenPromise(chan, CL_ALLOW_UNKNOWN_CL);
+ Assert.equal(req.protocolVersion, "h3-29");
+ Assert.equal(buf, stream.data);
+
+ await trrServer.stop();
+});