browser_download_attribute.js (3924B)
1 "use strict"; 2 3 function promisePanelOpened() { 4 if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") { 5 return Promise.resolve(); 6 } 7 return BrowserTestUtils.waitForEvent(DownloadsPanel.panel, "popupshown"); 8 } 9 10 const CONSOLE_UPGRADE_TRY_MESSAGE = "Upgrading insecure request"; 11 const CONSOLE_ERROR_MESSAGE = "Downgrading to “http” again"; 12 const DOWNLOAD_PAGE_URL = 13 "nocert.example.com/browser/dom/security/test/https-first/file_download_attribute.html"; 14 const DOWNLOAD_LINK_URL = 15 "nocert.example.org/browser/dom/security/test/https-first/file_download_attribute.sjs"; 16 17 // Verifys that https-first tried to upgrade the download 18 // - and that the upgrade attempt failed. 19 // We will receive 4 messages. Two for upgrading and downgrading 20 // the download page and another two for upgrading and downgrading 21 // the download. 22 let msgCounter = 0; 23 function shouldConsoleTryUpgradeAndError() { 24 // Waits until CONSOLE_ERROR_MESSAGE was logged. 25 // Checks if download was tried via http:// 26 return new Promise(resolve => { 27 function listener(msgObj) { 28 let text = msgObj.message; 29 // Verify upgrade messages 30 if ( 31 text.includes(CONSOLE_UPGRADE_TRY_MESSAGE) && 32 text.includes("http://") 33 ) { 34 if (msgCounter == 0) { 35 ok( 36 text.includes(DOWNLOAD_PAGE_URL), 37 "Tries to upgrade nocert example to https" 38 ); 39 } else { 40 ok( 41 text.includes(DOWNLOAD_LINK_URL), 42 "Tries to upgrade download to https" 43 ); 44 } 45 msgCounter++; 46 } 47 // Verify downgrade messages 48 if (text.includes(CONSOLE_ERROR_MESSAGE) && msgCounter > 0) { 49 if (msgCounter == 1) { 50 ok( 51 text.includes("https://" + DOWNLOAD_PAGE_URL), 52 "Downgrades nocert example to http" 53 ); 54 msgCounter++; 55 } else { 56 ok( 57 text.includes("https://" + DOWNLOAD_LINK_URL), 58 "Downgrades download to http" 59 ); 60 Services.console.unregisterListener(listener); 61 resolve(); 62 } 63 } 64 } 65 Services.console.registerListener(listener); 66 }); 67 } 68 69 // Test https-first download of an html file from an http site. 70 // Test description: 71 // 1. https-first tries to upgrade site to https 72 // 2. upgrade fails because site has no certificate 73 // 3. https-first downgrades to http and starts download via http 74 // 4. Successfully completes download 75 add_task(async function test_with_downloads_pref_enabled() { 76 await SpecialPowers.pushPrefEnv({ 77 set: [["dom.security.https_first", true]], 78 }); 79 let checkPromise = shouldConsoleTryUpgradeAndError(); 80 let downloadsPanelPromise = promisePanelOpened(); 81 let downloadsPromise = Downloads.getList(Downloads.PUBLIC); 82 83 BrowserTestUtils.startLoadingURIString(gBrowser, DOWNLOAD_PAGE_URL); 84 // wait for downloadsPanel to open before continuing with test 85 await downloadsPanelPromise; 86 let downloadList = await downloadsPromise; 87 await checkPromise; 88 is(DownloadsPanel.isPanelShowing, true, "DownloadsPanel should be open."); 89 is( 90 downloadList._downloads.length, 91 1, 92 "File should be successfully downloaded." 93 ); 94 95 let [download] = downloadList._downloads; 96 is(download.contentType, "text/html", "File contentType should be correct."); 97 // ensure https-first didn't upgrade the scheme. 98 is( 99 download.source.url, 100 "http://" + DOWNLOAD_LINK_URL, 101 "Scheme should be http." 102 ); 103 104 info("cleaning up downloads"); 105 try { 106 if (Services.appinfo.OS === "WINNT") { 107 // We need to make the file writable to delete it on Windows. 108 await IOUtils.setPermissions(download.target.path, 0o600); 109 } 110 await IOUtils.remove(download.target.path); 111 } catch (error) { 112 info("The file " + download.target.path + " is not removed, " + error); 113 } 114 115 await downloadList.remove(download); 116 await download.finalize(); 117 });