tor-browser

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

browser_slow_download.js (4953B)


      1 "use strict";
      2 
      3 // Create a uri for an https site
      4 const testPath = getRootDirectory(gTestPath).replace(
      5  "chrome://mochitests/content",
      6  "https://example.com"
      7 );
      8 const TEST_URI = testPath + "file_slow_download.html";
      9 const EXPECTED_DOWNLOAD_URL =
     10  "example.com/browser/dom/security/test/https-first/file_slow_download.sjs";
     11 
     12 // Since the server send the complete download file after 3 seconds we need an longer timeout
     13 requestLongerTimeout(4);
     14 
     15 function promisePanelOpened() {
     16  if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
     17    return Promise.resolve();
     18  }
     19  return BrowserTestUtils.waitForEvent(DownloadsPanel.panel, "popupshown");
     20 }
     21 
     22 /**
     23 * Waits for a download to finish, in case it has not finished already.
     24 *
     25 * @param aDownload
     26 *        The Download object to wait upon.
     27 *
     28 * @returns {Promise<void>}
     29 *   Resolves when the download has finished successfully.
     30 * @rejects JavaScript exception if the download failed.
     31 */
     32 function promiseDownloadStopped(aDownload) {
     33  if (!aDownload.stopped) {
     34    // The download is in progress, wait for the current attempt to finish and
     35    // report any errors that may occur.
     36    return aDownload.start();
     37  }
     38 
     39  if (aDownload.succeeded) {
     40    return Promise.resolve();
     41  }
     42 
     43  // The download failed or was canceled.
     44  return Promise.reject(aDownload.error || new Error("Download canceled."));
     45 }
     46 
     47 // Verifys that no background request was send
     48 let requestCounter = 0;
     49 function examiner() {
     50  SpecialPowers.addObserver(this, "specialpowers-http-notify-request");
     51 }
     52 
     53 examiner.prototype = {
     54  observe(subject, topic, data) {
     55    if (topic !== "specialpowers-http-notify-request") {
     56      return;
     57    }
     58    // On Android we have other requests appear here as well. Let's make
     59    // sure we only evaluate requests triggered by the test.
     60    if (
     61      !data.startsWith("http://example.com") &&
     62      !data.startsWith("https://example.com")
     63    ) {
     64      return;
     65    }
     66    ++requestCounter;
     67    if (requestCounter == 1) {
     68      is(data, TEST_URI, "Download start page is https");
     69      return;
     70    }
     71    if (requestCounter == 2) {
     72      // The specialpowers-http-notify-request fires before the internal redirect( /upgrade) to
     73      // https happens.
     74      is(
     75        data,
     76        "http://" + EXPECTED_DOWNLOAD_URL,
     77        "First download request is http (internal)"
     78      );
     79      return;
     80    }
     81    if (requestCounter == 3) {
     82      is(
     83        data,
     84        "https://" + EXPECTED_DOWNLOAD_URL,
     85        "Download got upgraded to https"
     86      );
     87      return;
     88    }
     89    ok(false, "we should never get here, but just in case");
     90  },
     91  remove() {
     92    SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
     93  },
     94 };
     95 
     96 // Test description:
     97 // 1. Open https://example.com
     98 // 2. Start download - location of download is http
     99 // 3. https-first upgrades to https
    100 // 4. Server send first part of download and after 3 seconds the rest
    101 // 5. Complete download of text file
    102 add_task(async function test_slow_download() {
    103  await SpecialPowers.pushPrefEnv({
    104    set: [["dom.security.https_first", true]],
    105  });
    106 
    107  // remove all previous downloads
    108  let downloadsList = await Downloads.getList(Downloads.PUBLIC);
    109  await downloadsList.removeFinished();
    110 
    111  // add observer to ensure that the background request gets canceled for the upgraded Download
    112  this.examiner = new examiner();
    113 
    114  let downloadsPanelPromise = promisePanelOpened();
    115  let downloadsPromise = Downloads.getList(Downloads.PUBLIC);
    116  BrowserTestUtils.startLoadingURIString(gBrowser, TEST_URI);
    117  // wait for downloadsPanel to open before continuing with test
    118  await downloadsPanelPromise;
    119  let downloadList = await downloadsPromise;
    120  is(DownloadsPanel.isPanelShowing, true, "DownloadsPanel should be open.");
    121  is(downloadList._downloads.length, 1, "File should be downloaded.");
    122  let [download] = downloadList._downloads;
    123  // wait for download to finish (with success or error)
    124  await promiseDownloadStopped(download);
    125  is(download.contentType, "text/plain", "File contentType should be correct.");
    126  // ensure https-first did upgrade the scheme.
    127  is(
    128    download.source.url,
    129    "https://" + EXPECTED_DOWNLOAD_URL,
    130    "Scheme should be https."
    131  );
    132  // ensure that no background request was send
    133  is(
    134    requestCounter,
    135    3,
    136    "three requests total (download page, download http, download https/ upgraded)"
    137  );
    138  // ensure that downloaded is complete
    139  is(download.target.size, 25, "Download size is correct");
    140  //clean up
    141  this.examiner.remove();
    142  info("cleaning up downloads");
    143  try {
    144    if (Services.appinfo.OS === "WINNT") {
    145      // We need to make the file writable to delete it on Windows.
    146      await IOUtils.setPermissions(download.target.path, 0o600);
    147    }
    148    await IOUtils.remove(download.target.path);
    149  } catch (error) {
    150    info("The file " + download.target.path + " is not removed, " + error);
    151  }
    152 
    153  await downloadList.remove(download);
    154  await download.finalize();
    155 });