diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/test/unit/test_http3_server.js | 168 |
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..5c1b081c52 --- /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(); +}); |