summaryrefslogtreecommitdiffstats
path: root/dom/security/test/https-first/browser_mixed_content_download.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/security/test/https-first/browser_mixed_content_download.js')
-rw-r--r--dom/security/test/https-first/browser_mixed_content_download.js156
1 files changed, 156 insertions, 0 deletions
diff --git a/dom/security/test/https-first/browser_mixed_content_download.js b/dom/security/test/https-first/browser_mixed_content_download.js
new file mode 100644
index 0000000000..09ea64cea8
--- /dev/null
+++ b/dom/security/test/https-first/browser_mixed_content_download.js
@@ -0,0 +1,156 @@
+ChromeUtils.defineESModuleGetters(this, {
+ Downloads: "resource://gre/modules/Downloads.sys.mjs",
+ DownloadsCommon: "resource:///modules/DownloadsCommon.sys.mjs",
+});
+
+const HandlerService = Cc[
+ "@mozilla.org/uriloader/handler-service;1"
+].getService(Ci.nsIHandlerService);
+
+const MIMEService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+
+let SECURE_BASE_URL =
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content/",
+ "https://example.com/"
+ ) + "download_page.html";
+
+/**
+ * Waits until a download is triggered.
+ * It waits until a prompt is shown,
+ * saves and then accepts the dialog.
+ * @returns {Promise} Resolved once done.
+ */
+
+function shouldTriggerDownload() {
+ return new Promise((resolve, reject) => {
+ Services.wm.addListener({
+ onOpenWindow(xulWin) {
+ Services.wm.removeListener(this);
+ let win = xulWin.docShell.domWindow;
+ waitForFocus(() => {
+ if (
+ win.location ==
+ "chrome://mozapps/content/downloads/unknownContentType.xhtml"
+ ) {
+ let dialog = win.document.getElementById("unknownContentType");
+ let button = dialog.getButton("accept");
+ let actionRadio = win.document.getElementById("save");
+ actionRadio.click();
+ button.disabled = false;
+ dialog.acceptDialog();
+ resolve();
+ } else {
+ reject();
+ }
+ }, win);
+ },
+ });
+ });
+}
+
+const CONSOLE_UPGRADE_MESSAGE = "Upgrading insecure request";
+const CONSOLE_DOWNGRADE_MESSAGE = "Downgrading to “http” again.";
+const DOWNLOAD_URL =
+ "example.com/browser/dom/security/test/https-first/download_server.sjs";
+// Verifies that https-first tries to upgrade download,
+// falls back since download is not available via https
+let msgCounter = 0;
+function shouldConsoleError() {
+ return new Promise((resolve, reject) => {
+ function listener(msgObj) {
+ let text = msgObj.message;
+ if (text.includes(CONSOLE_UPGRADE_MESSAGE) && msgCounter == 0) {
+ ok(
+ text.includes("http://" + DOWNLOAD_URL),
+ "Https-first tries to upgrade download to https"
+ );
+ msgCounter++;
+ }
+ if (text.includes(CONSOLE_DOWNGRADE_MESSAGE) && msgCounter == 1) {
+ ok(
+ text.includes("https://" + DOWNLOAD_URL),
+ "Https-first downgrades download to http."
+ );
+ resolve();
+ Services.console.unregisterListener(listener);
+ }
+ }
+ Services.console.registerListener(listener);
+ });
+}
+
+async function resetDownloads() {
+ // Removes all downloads from the download List
+ const types = new Set();
+ let publicList = await Downloads.getList(Downloads.PUBLIC);
+ let downloads = await publicList.getAll();
+ for (let download of downloads) {
+ if (download.contentType) {
+ types.add(download.contentType);
+ }
+ publicList.remove(download);
+ await download.finalize(true);
+ }
+
+ if (types.size) {
+ // reset handlers for the contentTypes of any files previously downloaded
+ for (let type of types) {
+ const mimeInfo = MIMEService.getFromTypeAndExtension(type, "");
+ info("resetting handler for type: " + type);
+ HandlerService.remove(mimeInfo);
+ }
+ }
+}
+
+async function runTest(url, link, checkFunction, description) {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["dom.security.https_first", true],
+ ["browser.download.always_ask_before_handling_new_types", true],
+ ],
+ });
+ requestLongerTimeout(2);
+ await resetDownloads();
+
+ let tab = BrowserTestUtils.addTab(gBrowser, url);
+ gBrowser.selectedTab = tab;
+
+ let browser = gBrowser.getBrowserForTab(tab);
+ await BrowserTestUtils.browserLoaded(browser);
+ is(
+ gBrowser.currentURI.schemeIs("https"),
+ true,
+ "Scheme of opened tab should be https"
+ );
+ info("Checking: " + description);
+
+ let checkPromise = checkFunction();
+ // Click the Link to trigger the download
+ SpecialPowers.spawn(gBrowser.selectedBrowser, [link], contentLink => {
+ content.document.getElementById(contentLink).click();
+ });
+ await checkPromise;
+ ok(true, description);
+ BrowserTestUtils.removeTab(tab);
+}
+
+//Test description:
+// 1. Open "https://example.com"
+// 2. From "https://example.com" download something, but that download is only available via http.
+// 3. Https-first tries to upgrade the download.
+// 4. Upgrading fails - so http-first downgrade download to http.
+
+add_task(async function test_mixed_download() {
+ await runTest(
+ SECURE_BASE_URL,
+ "insecure",
+ () => Promise.all([shouldTriggerDownload(), shouldConsoleError()]),
+ "Secure -> Insecure should Error"
+ );
+ // remove downloaded file
+ let downloadsPromise = Downloads.getList(Downloads.PUBLIC);
+ let downloadList = await downloadsPromise;
+ let [download] = downloadList._downloads;
+ await downloadList.remove(download);
+});