Bug 1796551 [wpt PR 36570] - WebKit export of https://bugs.webkit.org/show_bug.cgi...
[gecko.git] / netwerk / test / unit / test_https_rr_ech_prefs.js
blob38b9a785e2c847cd2f76486d5f96e9ca9cdc56b8
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/. */
5 "use strict";
7 ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
9 let trrServer;
11 const dns = Cc["@mozilla.org/network/dns-service;1"].getService(
12   Ci.nsIDNSService
15 function setup() {
16   trr_test_setup();
18   Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
19   Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
20   Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
23 setup();
24 registerCleanupFunction(async () => {
25   trr_clear_prefs();
26   Services.prefs.clearUserPref("network.dns.upgrade_with_https_rr");
27   Services.prefs.clearUserPref("network.dns.use_https_rr_as_altsvc");
28   Services.prefs.clearUserPref("network.dns.echconfig.enabled");
29   Services.prefs.clearUserPref("network.dns.http3_echconfig.enabled");
30   Services.prefs.clearUserPref("network.http.http3.enable");
31   Services.prefs.clearUserPref("network.http.http2.enabled");
32   if (trrServer) {
33     await trrServer.stop();
34   }
35 });
37 function checkResult(inRecord, noHttp2, noHttp3, result) {
38   if (!result) {
39     Assert.throws(
40       () => {
41         inRecord
42           .QueryInterface(Ci.nsIDNSHTTPSSVCRecord)
43           .GetServiceModeRecord(noHttp2, noHttp3);
44       },
45       /NS_ERROR_NOT_AVAILABLE/,
46       "Should get an error"
47     );
48     return;
49   }
51   let record = inRecord
52     .QueryInterface(Ci.nsIDNSHTTPSSVCRecord)
53     .GetServiceModeRecord(noHttp2, noHttp3);
54   Assert.equal(record.priority, result.expectedPriority);
55   Assert.equal(record.name, result.expectedName);
56   Assert.equal(record.selectedAlpn, result.expectedAlpn);
59 // Test configuration:
60 //   There are two records: one has a echConfig and the other doesn't.
61 // We want to test if the record with echConfig is preferred.
62 add_task(async function testEchConfigEnabled() {
63   let trrServer = new TRRServer();
64   await trrServer.start();
66   Services.prefs.setIntPref("network.trr.mode", 3);
67   Services.prefs.setCharPref(
68     "network.trr.uri",
69     `https://foo.example.com:${trrServer.port}/dns-query`
70   );
71   Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
73   await trrServer.registerDoHAnswers("test.bar.com", "HTTPS", {
74     answers: [
75       {
76         name: "test.bar.com",
77         ttl: 55,
78         type: "HTTPS",
79         flush: false,
80         data: {
81           priority: 1,
82           name: "test.bar_1.com",
83           values: [{ key: "alpn", value: ["h3-29"] }],
84         },
85       },
86       {
87         name: "test.bar.com",
88         ttl: 55,
89         type: "HTTPS",
90         flush: false,
91         data: {
92           priority: 2,
93           name: "test.bar_2.com",
94           values: [
95             { key: "alpn", value: ["h2"] },
96             { key: "echconfig", value: "456..." },
97           ],
98         },
99       },
100     ],
101   });
103   let { inRecord } = await new TRRDNSListener("test.bar.com", {
104     type: dns.RESOLVE_TYPE_HTTPSSVC,
105   });
107   checkResult(inRecord, false, false, {
108     expectedPriority: 1,
109     expectedName: "test.bar_1.com",
110     expectedAlpn: "h3-29",
111   });
112   checkResult(inRecord, false, true, {
113     expectedPriority: 2,
114     expectedName: "test.bar_2.com",
115     expectedAlpn: "h2",
116   });
117   checkResult(inRecord, true, false, {
118     expectedPriority: 1,
119     expectedName: "test.bar_1.com",
120     expectedAlpn: "h3-29",
121   });
122   checkResult(inRecord, true, true);
124   Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
125   dns.clearCache(true);
127   ({ inRecord } = await new TRRDNSListener("test.bar.com", {
128     type: dns.RESOLVE_TYPE_HTTPSSVC,
129   }));
131   checkResult(inRecord, false, false, {
132     expectedPriority: 2,
133     expectedName: "test.bar_2.com",
134     expectedAlpn: "h2",
135   });
136   checkResult(inRecord, false, true, {
137     expectedPriority: 2,
138     expectedName: "test.bar_2.com",
139     expectedAlpn: "h2",
140   });
141   checkResult(inRecord, true, false, {
142     expectedPriority: 1,
143     expectedName: "test.bar_1.com",
144     expectedAlpn: "h3-29",
145   });
146   checkResult(inRecord, true, true);
148   await trrServer.stop();
149   trrServer = null;
152 // Test configuration:
153 //   There are two records: both have echConfigs, and only one supports h3.
154 // This test is about testing which record should we get when
155 // network.dns.http3_echconfig.enabled is true and false.
156 // When network.dns.http3_echconfig.enabled is false, we should try to
157 // connect with h2 and echConfig.
158 add_task(async function testTwoRecordsHaveEchConfig() {
159   dns.clearCache(true);
161   let trrServer = new TRRServer();
162   await trrServer.start();
164   Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
165   Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
166   Services.prefs.setIntPref("network.trr.mode", 3);
167   Services.prefs.setCharPref(
168     "network.trr.uri",
169     `https://foo.example.com:${trrServer.port}/dns-query`
170   );
172   await trrServer.registerDoHAnswers("test.foo.com", "HTTPS", {
173     answers: [
174       {
175         name: "test.foo.com",
176         ttl: 55,
177         type: "HTTPS",
178         flush: false,
179         data: {
180           priority: 1,
181           name: "test.foo_h3.com",
182           values: [
183             { key: "alpn", value: ["h3"] },
184             { key: "echconfig", value: "456..." },
185           ],
186         },
187       },
188       {
189         name: "test.foo.com",
190         ttl: 55,
191         type: "HTTPS",
192         flush: false,
193         data: {
194           priority: 2,
195           name: "test.foo_h2.com",
196           values: [
197             { key: "alpn", value: ["h2"] },
198             { key: "echconfig", value: "456..." },
199           ],
200         },
201       },
202     ],
203   });
205   let { inRecord } = await new TRRDNSListener("test.foo.com", {
206     type: dns.RESOLVE_TYPE_HTTPSSVC,
207   });
209   checkResult(inRecord, false, false, {
210     expectedPriority: 2,
211     expectedName: "test.foo_h2.com",
212     expectedAlpn: "h2",
213   });
214   checkResult(inRecord, false, true, {
215     expectedPriority: 2,
216     expectedName: "test.foo_h2.com",
217     expectedAlpn: "h2",
218   });
219   checkResult(inRecord, true, false, {
220     expectedPriority: 1,
221     expectedName: "test.foo_h3.com",
222     expectedAlpn: "h3",
223   });
224   checkResult(inRecord, true, true);
226   Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
227   dns.clearCache(true);
228   ({ inRecord } = await new TRRDNSListener("test.foo.com", {
229     type: dns.RESOLVE_TYPE_HTTPSSVC,
230   }));
232   checkResult(inRecord, false, false, {
233     expectedPriority: 1,
234     expectedName: "test.foo_h3.com",
235     expectedAlpn: "h3",
236   });
237   checkResult(inRecord, false, true, {
238     expectedPriority: 2,
239     expectedName: "test.foo_h2.com",
240     expectedAlpn: "h2",
241   });
242   checkResult(inRecord, true, false, {
243     expectedPriority: 1,
244     expectedName: "test.foo_h3.com",
245     expectedAlpn: "h3",
246   });
247   checkResult(inRecord, true, true);
249   await trrServer.stop();
250   trrServer = null;
253 // Test configuration:
254 //   There are two records: both have echConfigs, and one supports h3 and h2.
255 // When network.dns.http3_echconfig.enabled is false, we should use the record
256 // that supports h3 and h2 (the alpn is h2).
257 add_task(async function testTwoRecordsHaveEchConfig1() {
258   dns.clearCache(true);
260   let trrServer = new TRRServer();
261   await trrServer.start();
263   Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
264   Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
265   Services.prefs.setIntPref("network.trr.mode", 3);
266   Services.prefs.setCharPref(
267     "network.trr.uri",
268     `https://foo.example.com:${trrServer.port}/dns-query`
269   );
271   await trrServer.registerDoHAnswers("test.foo.com", "HTTPS", {
272     answers: [
273       {
274         name: "test.foo.com",
275         ttl: 55,
276         type: "HTTPS",
277         flush: false,
278         data: {
279           priority: 1,
280           name: "test.foo_h3.com",
281           values: [
282             { key: "alpn", value: ["h3", "h2"] },
283             { key: "echconfig", value: "456..." },
284           ],
285         },
286       },
287       {
288         name: "test.foo.com",
289         ttl: 55,
290         type: "HTTPS",
291         flush: false,
292         data: {
293           priority: 2,
294           name: "test.foo_h2.com",
295           values: [
296             { key: "alpn", value: ["h2", "http/1.1"] },
297             { key: "echconfig", value: "456..." },
298           ],
299         },
300       },
301     ],
302   });
304   let { inRecord } = await new TRRDNSListener("test.foo.com", {
305     type: dns.RESOLVE_TYPE_HTTPSSVC,
306   });
308   checkResult(inRecord, false, false, {
309     expectedPriority: 1,
310     expectedName: "test.foo_h3.com",
311     expectedAlpn: "h2",
312   });
313   checkResult(inRecord, false, true, {
314     expectedPriority: 1,
315     expectedName: "test.foo_h3.com",
316     expectedAlpn: "h2",
317   });
318   checkResult(inRecord, true, false, {
319     expectedPriority: 2,
320     expectedName: "test.foo_h2.com",
321     expectedAlpn: "http/1.1",
322   });
323   checkResult(inRecord, true, true, {
324     expectedPriority: 2,
325     expectedName: "test.foo_h2.com",
326     expectedAlpn: "http/1.1",
327   });
329   Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
330   dns.clearCache(true);
331   ({ inRecord } = await new TRRDNSListener("test.foo.com", {
332     type: dns.RESOLVE_TYPE_HTTPSSVC,
333   }));
335   checkResult(inRecord, false, false, {
336     expectedPriority: 1,
337     expectedName: "test.foo_h3.com",
338     expectedAlpn: "h3",
339   });
340   checkResult(inRecord, false, true, {
341     expectedPriority: 1,
342     expectedName: "test.foo_h3.com",
343     expectedAlpn: "h2",
344   });
345   checkResult(inRecord, true, false, {
346     expectedPriority: 1,
347     expectedName: "test.foo_h3.com",
348     expectedAlpn: "h3",
349   });
350   checkResult(inRecord, true, true, {
351     expectedPriority: 2,
352     expectedName: "test.foo_h2.com",
353     expectedAlpn: "http/1.1",
354   });
356   await trrServer.stop();
357   trrServer = null;
360 // Test configuration:
361 //   There are two records: only one support h3 and only one has echConfig.
362 // This test is about never usng the record without echConfig.
363 add_task(async function testOneRecordsHasEchConfig() {
364   dns.clearCache(true);
366   let trrServer = new TRRServer();
367   await trrServer.start();
369   Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
370   Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
371   Services.prefs.setIntPref("network.trr.mode", 3);
372   Services.prefs.setCharPref(
373     "network.trr.uri",
374     `https://foo.example.com:${trrServer.port}/dns-query`
375   );
377   await trrServer.registerDoHAnswers("test.foo.com", "HTTPS", {
378     answers: [
379       {
380         name: "test.foo.com",
381         ttl: 55,
382         type: "HTTPS",
383         flush: false,
384         data: {
385           priority: 1,
386           name: "test.foo_h3.com",
387           values: [
388             { key: "alpn", value: ["h3"] },
389             { key: "echconfig", value: "456..." },
390           ],
391         },
392       },
393       {
394         name: "test.foo.com",
395         ttl: 55,
396         type: "HTTPS",
397         flush: false,
398         data: {
399           priority: 2,
400           name: "test.foo_h2.com",
401           values: [{ key: "alpn", value: ["h2"] }],
402         },
403       },
404     ],
405   });
407   let { inRecord } = await new TRRDNSListener("test.foo.com", {
408     type: dns.RESOLVE_TYPE_HTTPSSVC,
409   });
411   checkResult(inRecord, false, false, {
412     expectedPriority: 1,
413     expectedName: "test.foo_h3.com",
414     expectedAlpn: "h3",
415   });
416   checkResult(inRecord, false, true, {
417     expectedPriority: 2,
418     expectedName: "test.foo_h2.com",
419     expectedAlpn: "h2",
420   });
421   checkResult(inRecord, true, false, {
422     expectedPriority: 1,
423     expectedName: "test.foo_h3.com",
424     expectedAlpn: "h3",
425   });
426   checkResult(inRecord, true, true);
428   Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
429   dns.clearCache(true);
430   ({ inRecord } = await new TRRDNSListener("test.foo.com", {
431     type: dns.RESOLVE_TYPE_HTTPSSVC,
432   }));
434   checkResult(inRecord, false, false, {
435     expectedPriority: 1,
436     expectedName: "test.foo_h3.com",
437     expectedAlpn: "h3",
438   });
439   checkResult(inRecord, false, true, {
440     expectedPriority: 2,
441     expectedName: "test.foo_h2.com",
442     expectedAlpn: "h2",
443   });
444   checkResult(inRecord, true, false, {
445     expectedPriority: 1,
446     expectedName: "test.foo_h3.com",
447     expectedAlpn: "h3",
448   });
449   checkResult(inRecord, true, true);
451   await trrServer.stop();
452   trrServer = null;
455 // Test the case that "network.http.http3.enable" and
456 // "network.http.http2.enabled" are true/false.
457 add_task(async function testHttp3AndHttp2Pref() {
458   dns.clearCache(true);
460   let trrServer = new TRRServer();
461   await trrServer.start();
463   Services.prefs.setBoolPref("network.http.http3.enable", false);
464   Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
465   Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
466   Services.prefs.setIntPref("network.trr.mode", 3);
467   Services.prefs.setCharPref(
468     "network.trr.uri",
469     `https://foo.example.com:${trrServer.port}/dns-query`
470   );
472   await trrServer.registerDoHAnswers("test.foo.com", "HTTPS", {
473     answers: [
474       {
475         name: "test.foo.com",
476         ttl: 55,
477         type: "HTTPS",
478         flush: false,
479         data: {
480           priority: 1,
481           name: "test.foo_h3.com",
482           values: [
483             { key: "alpn", value: ["h3", "h2"] },
484             { key: "echconfig", value: "456..." },
485           ],
486         },
487       },
488       {
489         name: "test.foo.com",
490         ttl: 55,
491         type: "HTTPS",
492         flush: false,
493         data: {
494           priority: 2,
495           name: "test.foo_h2.com",
496           values: [
497             { key: "alpn", value: ["h2"] },
498             { key: "echconfig", value: "456..." },
499           ],
500         },
501       },
502     ],
503   });
505   let { inRecord } = await new TRRDNSListener("test.foo.com", {
506     type: dns.RESOLVE_TYPE_HTTPSSVC,
507   });
509   checkResult(inRecord, false, false, {
510     expectedPriority: 1,
511     expectedName: "test.foo_h3.com",
512     expectedAlpn: "h2",
513   });
514   checkResult(inRecord, false, true, {
515     expectedPriority: 1,
516     expectedName: "test.foo_h3.com",
517     expectedAlpn: "h2",
518   });
519   checkResult(inRecord, true, false);
520   checkResult(inRecord, true, true);
522   Services.prefs.setBoolPref("network.http.http2.enabled", false);
523   checkResult(inRecord, false, false);
525   Services.prefs.setBoolPref("network.http.http3.enable", true);
526   checkResult(inRecord, false, false, {
527     expectedPriority: 1,
528     expectedName: "test.foo_h3.com",
529     expectedAlpn: "h3",
530   });
531   checkResult(inRecord, false, true);
532   checkResult(inRecord, true, false, {
533     expectedPriority: 1,
534     expectedName: "test.foo_h3.com",
535     expectedAlpn: "h3",
536   });
537   checkResult(inRecord, true, true);
539   await trrServer.stop();
540   trrServer = null;