tor-browser

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

browser_dns_prefetch_link_header.js (9062B)


      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 // Test steps:
      6 // 1. Load file_link_dns_prefetch.sjs
      7 // 2.`<link rel="dns-prefetch" href="https://example.org">` is in
      8 //    the server-side sjs, so we will make the dns-request.
      9 // 3. We verify that the dns request was made
     10 
     11 const gDashboard = Cc["@mozilla.org/network/dashboard;1"].getService(
     12  Ci.nsIDashboard
     13 );
     14 
     15 /////////////////////////////////////////////////////////////////////////////
     16 // To observe DNS requests when running via the mochitest proxy we must first take a few steps:
     17 //
     18 // 1. Update the mochitest proxy pac file to include dns resolution.
     19 //  We do this by injecting "dnsResolve(host);" into the `FindProxyForURL()` pac function.
     20 let existingPACScript = Services.prefs.getCharPref(
     21  "network.proxy.autoconfig_url"
     22 );
     23 
     24 let findProxyForURLFunction = "function FindProxyForURL(url, host){";
     25 let directDnsPacScript = existingPACScript.replace(
     26  findProxyForURLFunction,
     27  `${findProxyForURLFunction}
     28    dnsResolve(host);
     29    `
     30 );
     31 Services.prefs.setStringPref(
     32  "network.proxy.autoconfig_url",
     33  directDnsPacScript
     34 );
     35 
     36 // 2. Ensure we don't disable dns prefetch despite using a proxy (this would otherwise happen after every request that the proxy completed)
     37 Services.prefs.setBoolPref("network.dns.prefetch_via_proxy", true);
     38 
     39 // 3. Make sure that HTTPS-First does not interfere with us loading HTTP tests
     40 let initialHttpsFirst = Services.prefs.getBoolPref("dom.security.https_first");
     41 Services.prefs.setBoolPref("dom.security.https_first", false);
     42 
     43 // 4. And finally enable dns prefetching via the private dns service api (generally disabled in mochitest proxy)
     44 
     45 Services.dns.QueryInterface(Ci.nsPIDNSService).prefetchEnabled = true;
     46 /////////////////////////////////////////////////////////////////////////////
     47 
     48 registerCleanupFunction(function () {
     49  // Restore proxy pac and dns prefetch behaviour via proxy
     50  Services.prefs.setCharPref("network.proxy.autoconfig_url", existingPACScript);
     51  Services.prefs.clearUserPref("network.dns.prefetch_via_proxy");
     52  Services.prefs.setBoolPref("dom.security.https_first", initialHttpsFirst);
     53  Services.dns.QueryInterface(Ci.nsPIDNSService).prefetchEnabled = false;
     54 });
     55 
     56 async function isRecordFound(hostname) {
     57  return new Promise(resolve => {
     58    gDashboard.requestDNSInfo(function (data) {
     59      let found = false;
     60      for (let i = 0; i < data.entries.length; i++) {
     61        if (data.entries[i].hostname == hostname) {
     62          found = true;
     63          break;
     64        }
     65      }
     66      resolve(found);
     67    });
     68  });
     69 }
     70 
     71 let https_requestUrl = `https://example.com/browser/netwerk/test/browser/file_link_dns_prefetch.sjs`;
     72 let http_requestUrl = `http://example.com/browser/netwerk/test/browser/file_link_dns_prefetch.sjs`; // eslint-disable-line @microsoft/sdl/no-insecure-url
     73 
     74 add_setup(async function () {
     75  await SpecialPowers.pushPrefEnv({
     76    set: [["test.wait300msAfterTabSwitch", true]],
     77  });
     78 });
     79 
     80 // Test dns-prefetch on https
     81 add_task(async function test_https_dns_prefetch() {
     82  Services.dns.clearCache(true);
     83 
     84  await BrowserTestUtils.withNewTab(
     85    {
     86      gBrowser,
     87      url: https_requestUrl,
     88      waitForLoad: true,
     89    },
     90    async function () {}
     91  );
     92 
     93  Assert.ok(
     94    await TestUtils.waitForCondition(() => {
     95      return isRecordFound("example.org");
     96    }),
     97    "Record from link rel=dns-prefetch element should be found"
     98  );
     99  Assert.ok(await isRecordFound("example.com"), "Host record should be found");
    100 });
    101 
    102 // Test dns-prefetch on http
    103 add_task(async function test_http_dns_prefetch() {
    104  Services.dns.clearCache(true);
    105 
    106  await BrowserTestUtils.withNewTab(
    107    {
    108      gBrowser,
    109      url: http_requestUrl,
    110      waitForLoad: true,
    111    },
    112    async function () {}
    113  );
    114 
    115  Assert.ok(
    116    await TestUtils.waitForCondition(() => {
    117      return isRecordFound("example.org");
    118    }),
    119    "Record from link rel=dns-prefetch element should be found"
    120  );
    121  Assert.ok(await isRecordFound("example.com"), "Host record should be found");
    122 });
    123 
    124 // Test dns-prefetch on https with the feature disabled
    125 add_task(async function test_https_dns_prefetch_disabled() {
    126  Services.dns.clearCache(true);
    127 
    128  // Disable the feature to verify that it will not prefetch
    129  Services.prefs.setBoolPref("network.dns.disablePrefetchFromHTTPS", true);
    130 
    131  await BrowserTestUtils.withNewTab(
    132    {
    133      gBrowser,
    134      url: https_requestUrl,
    135      waitForLoad: true,
    136    },
    137    async function () {}
    138  );
    139 
    140  Assert.ok(await isRecordFound("example.com"), "Host record should be found");
    141  Assert.ok(
    142    !(await isRecordFound("example.org")),
    143    "Record from link rel=dns-prefetch element should not be found with disablePrefetchFromHTTPS set"
    144  );
    145 
    146  Services.prefs.clearUserPref("network.dns.disablePrefetchFromHTTPS");
    147 });
    148 
    149 // Test dns-prefetch on http with the feature disabled
    150 add_task(async function test_http_dns_prefetch_disabled() {
    151  Services.dns.clearCache(true);
    152 
    153  // Disable the feature to verify, but this test is http, and so prefetch will execute
    154  Services.prefs.setBoolPref("network.dns.disablePrefetchFromHTTPS", true);
    155 
    156  await BrowserTestUtils.withNewTab(
    157    {
    158      gBrowser,
    159      url: http_requestUrl,
    160      waitForLoad: true,
    161    },
    162    async function () {}
    163  );
    164 
    165  Assert.ok(
    166    await TestUtils.waitForCondition(() => {
    167      return isRecordFound("example.org");
    168    }),
    169    "Record from link rel=dns-prefetch element should be found on http page with disablePrefetchFromHTTPS set"
    170  );
    171  Assert.ok(await isRecordFound("example.com"), "Host record should be found");
    172 
    173  Services.prefs.clearUserPref("network.dns.disablePrefetchFromHTTPS");
    174 });
    175 
    176 // Test if we speculatively prefetch dns for anchor elements on https documents
    177 add_task(async function test_https_anchor_speculative_dns_prefetch() {
    178  Services.dns.clearCache(true);
    179 
    180  await BrowserTestUtils.withNewTab(
    181    {
    182      gBrowser,
    183      url: https_requestUrl,
    184      waitForLoad: true,
    185    },
    186    async function () {
    187      Assert.ok(
    188        await isRecordFound("example.com"),
    189        "Host record should be found"
    190      );
    191      Assert.ok(
    192        !(await isRecordFound("www.mozilla.org")),
    193        "By default we do not speculatively prefetch dns for anchor elements on https documents"
    194      );
    195    }
    196  );
    197 
    198  // And enable the pref to verify that it works
    199  Services.prefs.setBoolPref(
    200    "dom.prefetch_dns_for_anchor_https_document",
    201    true
    202  );
    203  Services.dns.clearCache(true);
    204 
    205  await BrowserTestUtils.withNewTab(
    206    {
    207      gBrowser,
    208      url: https_requestUrl,
    209      waitForLoad: true,
    210    },
    211    async function () {
    212      // The anchor element prefetchs are sent after pageload event; wait for them
    213      Assert.ok(
    214        await TestUtils.waitForCondition(() => {
    215          return isRecordFound("www.mozilla.org");
    216        }),
    217        "Speculatively prefetch dns for anchor elements on https documents"
    218      );
    219      Assert.ok(
    220        await isRecordFound("example.com"),
    221        "Host record should be found"
    222      );
    223    }
    224  );
    225 
    226  Services.prefs.clearUserPref("dom.prefetch_dns_for_anchor_https_document");
    227 });
    228 
    229 // Test that we speculatively prefetch dns for anchor elements on http documents
    230 add_task(async function test_http_anchor_speculative_dns_prefetch() {
    231  Services.dns.clearCache(true);
    232 
    233  await BrowserTestUtils.withNewTab(
    234    {
    235      gBrowser,
    236      url: http_requestUrl,
    237      waitForLoad: true,
    238    },
    239    async function () {
    240      Assert.ok(
    241        await TestUtils.waitForCondition(() => {
    242          return isRecordFound("example.org");
    243        }),
    244        "Record from link rel=dns-prefetch element should be found"
    245      );
    246 
    247      // The anchor element prefetchs are sent after pageload event; wait for them
    248      Assert.ok(
    249        await TestUtils.waitForCondition(() => {
    250          return isRecordFound("www.mozilla.org");
    251        }),
    252        "By default we speculatively prefetch dns for anchor elements on http documents"
    253      );
    254 
    255      Assert.ok(
    256        await isRecordFound("example.com"),
    257        "Host record should be found"
    258      );
    259    }
    260  );
    261 
    262  // And disable the pref to verify that we no longer make the requests
    263  Services.prefs.setBoolPref(
    264    "dom.prefetch_dns_for_anchor_http_document",
    265    false
    266  );
    267  Services.dns.clearCache(true);
    268 
    269  await BrowserTestUtils.withNewTab(
    270    {
    271      gBrowser,
    272      url: http_requestUrl,
    273      waitForLoad: true,
    274    },
    275    async function () {
    276      Assert.ok(
    277        await TestUtils.waitForCondition(() => {
    278          return isRecordFound("example.org");
    279        }),
    280        "Record from link rel=dns-prefetch element should be found"
    281      );
    282      Assert.ok(
    283        !(await isRecordFound("www.mozilla.org")),
    284        "We disabled speculative prefetch dns for anchor elements on http documents"
    285      );
    286      Assert.ok(
    287        await isRecordFound("example.com"),
    288        "Host record should be found"
    289      );
    290    }
    291  );
    292 
    293  Services.prefs.clearUserPref("dom.prefetch_dns_for_anchor_http_document");
    294 });