tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_bug_1918928.js (4426B)


      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 const { TestUtils } = ChromeUtils.importESModule(
      8  "resource://testing-common/TestUtils.sys.mjs"
      9 );
     10 
     11 const CONFIRM_OK = 2;
     12 const CONFIRM_DISABLED = 5;
     13 
     14 function WaitHTTPSRR(input) {
     15  const NS_HTTP_FORCE_WAIT_HTTP_RR = 1 << 22;
     16  return (input & NS_HTTP_FORCE_WAIT_HTTP_RR) !== 0;
     17 }
     18 
     19 async function waitForConfirmationState(state, msToWait = 0) {
     20  await TestUtils.waitForCondition(
     21    () => Services.dns.currentTrrConfirmationState == state,
     22    `Timed out waiting for ${state}. Currently ${Services.dns.currentTrrConfirmationState}`,
     23    1,
     24    msToWait
     25  );
     26  equal(
     27    Services.dns.currentTrrConfirmationState,
     28    state,
     29    "expected confirmation state"
     30  );
     31 }
     32 
     33 let h2Port;
     34 let trrServer;
     35 
     36 function makeChan(url) {
     37  let chan = NetUtil.newChannel({
     38    uri: url,
     39    loadUsingSystemPrincipal: true,
     40    contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
     41  }).QueryInterface(Ci.nsIHttpChannel);
     42  return chan;
     43 }
     44 
     45 function channelOpenPromise(chan, flags) {
     46  return new Promise(resolve => {
     47    function finish(req, buffer) {
     48      resolve([req, buffer]);
     49    }
     50    chan.asyncOpen(new ChannelListener(finish, null, flags));
     51  });
     52 }
     53 
     54 add_setup(async function setup() {
     55  trrServer = new TRRServer();
     56  await trrServer.start();
     57  h2Port = trrServer.port();
     58 
     59  trr_test_setup();
     60  registerCleanupFunction(async () => {
     61    trr_clear_prefs();
     62    if (trrServer) {
     63      await trrServer.stop();
     64    }
     65  });
     66 });
     67 
     68 function ActivityObserver() {}
     69 
     70 ActivityObserver.prototype = {
     71  caps: 0,
     72  observeActivity(aChannel, aType, aSubtype) {
     73    try {
     74      aChannel.QueryInterface(Ci.nsIChannel);
     75      if (
     76        aChannel.URI.spec ===
     77          `https://foo.example.com:${h2Port}/server-timing` &&
     78        aType === Ci.nsIHttpActivityObserver.ACTIVITY_TYPE_HTTP_TRANSACTION &&
     79        aSubtype === Ci.nsIHttpActivityObserver.ACTIVITY_SUBTYPE_REQUEST_HEADER
     80      ) {
     81        this.caps = aChannel.QueryInterface(Ci.nsIHttpChannelInternal).caps;
     82      }
     83    } catch (_) {}
     84  },
     85 };
     86 
     87 // Test in TRRFIRST mode, channel only wait for HTTPS RR when TRR is confirmed.
     88 add_task(async function test_caps_in_trr_first() {
     89  Services.prefs.setCharPref("network.trr.confirmationNS", "skip");
     90  Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
     91  equal(Services.dns.currentTrrConfirmationState, CONFIRM_DISABLED);
     92 
     93  let observerService = Cc[
     94    "@mozilla.org/network/http-activity-distributor;1"
     95  ].getService(Ci.nsIHttpActivityDistributor);
     96  let observer = new ActivityObserver();
     97  observerService.addObserver(observer);
     98 
     99  let chan = makeChan(`https://foo.example.com:${h2Port}/server-timing`);
    100  await channelOpenPromise(chan);
    101 
    102  Assert.ok(!WaitHTTPSRR(observer.caps));
    103 
    104  await trrServer.registerDoHAnswers("confirm.example.com", "NS", {
    105    answers: [
    106      {
    107        name: "confirm.example.com",
    108        ttl: 55,
    109        type: "NS",
    110        flush: false,
    111        data: "test.com",
    112      },
    113    ],
    114  });
    115 
    116  Services.dns.clearCache(true);
    117  Services.prefs.setCharPref(
    118    "network.trr.confirmationNS",
    119    "confirm.example.com"
    120  );
    121 
    122  Services.prefs.setCharPref(
    123    "network.trr.uri",
    124    `https://foo.example.com:${trrServer.port()}/dns-query`
    125  );
    126  Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
    127  await waitForConfirmationState(CONFIRM_OK, 1000);
    128 
    129  observer.caps = 0;
    130  chan = makeChan(`https://foo.example.com:${h2Port}/server-timing`);
    131  await channelOpenPromise(chan);
    132 
    133  Assert.ok(WaitHTTPSRR(observer.caps));
    134 });
    135 
    136 // Test in TRRONLY mode, channel always wait for HTTPS RR.
    137 add_task(async function test_caps_in_trr_only() {
    138  Services.prefs.setCharPref(
    139    "network.trr.confirmationNS",
    140    "confirm.example.com"
    141  );
    142  Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRONLY);
    143  equal(Services.dns.currentTrrConfirmationState, CONFIRM_DISABLED);
    144 
    145  let observerService = Cc[
    146    "@mozilla.org/network/http-activity-distributor;1"
    147  ].getService(Ci.nsIHttpActivityDistributor);
    148  let observer = new ActivityObserver();
    149  observerService.addObserver(observer);
    150 
    151  let chan = makeChan(`https://foo.example.com:${h2Port}/server-timing`);
    152  await channelOpenPromise(chan);
    153 
    154  Assert.ok(WaitHTTPSRR(observer.caps));
    155 });