test_http3_server.js (4877B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 let h2Port; 8 let h3Port; 9 let trrServer; 10 11 const certOverrideService = Cc[ 12 "@mozilla.org/security/certoverride;1" 13 ].getService(Ci.nsICertOverrideService); 14 const { TestUtils } = ChromeUtils.importESModule( 15 "resource://testing-common/TestUtils.sys.mjs" 16 ); 17 18 const { NodeHTTPServer } = ChromeUtils.importESModule( 19 "resource://testing-common/NodeServer.sys.mjs" 20 ); 21 22 add_setup(async function setup() { 23 h2Port = Services.env.get("MOZHTTP2_PORT"); 24 Assert.notEqual(h2Port, null); 25 Assert.notEqual(h2Port, ""); 26 27 h3Port = Services.env.get("MOZHTTP3_PORT_PROXY"); 28 Assert.notEqual(h3Port, null); 29 Assert.notEqual(h3Port, ""); 30 31 trr_test_setup(); 32 33 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true); 34 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true); 35 36 registerCleanupFunction(async () => { 37 trr_clear_prefs(); 38 Services.prefs.clearUserPref("network.dns.upgrade_with_https_rr"); 39 Services.prefs.clearUserPref("network.dns.use_https_rr_as_altsvc"); 40 Services.prefs.clearUserPref("network.dns.disablePrefetch"); 41 await trrServer.stop(); 42 }); 43 44 if (mozinfo.socketprocess_networking) { 45 Services.dns; 46 await TestUtils.waitForCondition(() => Services.io.socketProcessLaunched); 47 } 48 }); 49 50 function makeChan(url) { 51 let chan = NetUtil.newChannel({ 52 uri: url, 53 loadUsingSystemPrincipal: true, 54 contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT, 55 }).QueryInterface(Ci.nsIHttpChannel); 56 return chan; 57 } 58 59 function channelOpenPromise(chan, flags) { 60 return new Promise(resolve => { 61 function finish(req, buffer) { 62 certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData( 63 false 64 ); 65 resolve([req, buffer]); 66 } 67 certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData( 68 true 69 ); 70 chan.asyncOpen(new ChannelListener(finish, null, flags)); 71 }); 72 } 73 74 // Use NodeHTTPServer to create an HTTP server and test if the Http/3 server 75 // can act as a reverse proxy. 76 add_task(async function testHttp3ServerAsReverseProxy() { 77 trrServer = new TRRServer(); 78 await trrServer.start(); 79 Services.dns.clearCache(true); 80 Services.prefs.setIntPref("network.trr.mode", 3); 81 Services.prefs.setCharPref( 82 "network.trr.uri", 83 `https://foo.example.com:${trrServer.port()}/dns-query` 84 ); 85 86 await trrServer.registerDoHAnswers("test.h3_example.com", "HTTPS", { 87 answers: [ 88 { 89 name: "test.h3_example.com", 90 ttl: 55, 91 type: "HTTPS", 92 flush: false, 93 data: { 94 priority: 1, 95 name: "test.h3_example.com", 96 values: [ 97 { key: "alpn", value: "h3" }, 98 { key: "port", value: h3Port }, 99 ], 100 }, 101 }, 102 ], 103 }); 104 105 await trrServer.registerDoHAnswers("test.h3_example.com", "A", { 106 answers: [ 107 { 108 name: "test.h3_example.com", 109 ttl: 55, 110 type: "A", 111 flush: false, 112 data: "127.0.0.1", 113 }, 114 ], 115 }); 116 117 await new TRRDNSListener("test.h3_example.com", { 118 type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC, 119 }); 120 121 let server = new NodeHTTPServer(); 122 await server.start(); 123 registerCleanupFunction(async () => { 124 await server.stop(); 125 }); 126 127 await server.registerPathHandler("/test", (req, resp) => { 128 if (req.method === "GET") { 129 resp.writeHead(200); 130 resp.end("got GET request"); 131 } else if (req.method === "POST") { 132 let received = ""; 133 req.on("data", function receivePostData(chunk) { 134 received += chunk.toString(); 135 }); 136 req.on("end", function finishPost() { 137 resp.writeHead(200); 138 resp.end(received); 139 }); 140 } 141 }); 142 143 // Tell the Http/3 server which port to forward requests. 144 let chan = makeChan(`https://test.h3_example.com/port?${server.port()}`); 145 await channelOpenPromise(chan, CL_ALLOW_UNKNOWN_CL); 146 147 // Test GET method. 148 chan = makeChan(`https://test.h3_example.com/test`); 149 let [req, buf] = await channelOpenPromise(chan, CL_ALLOW_UNKNOWN_CL); 150 Assert.equal(req.protocolVersion, "h3"); 151 Assert.equal(buf, "got GET request"); 152 153 var stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( 154 Ci.nsIStringInputStream 155 ); 156 stream.setByteStringData("b".repeat(500)); 157 158 // Test POST method. 159 chan = makeChan(`https://test.h3_example.com/test`); 160 chan 161 .QueryInterface(Ci.nsIUploadChannel) 162 .setUploadStream(stream, "text/plain", stream.available()); 163 chan.requestMethod = "POST"; 164 165 [req, buf] = await channelOpenPromise(chan, CL_ALLOW_UNKNOWN_CL); 166 Assert.equal(req.protocolVersion, "h3"); 167 Assert.equal(buf, stream.data); 168 169 await trrServer.stop(); 170 });