test_fetch_integrity.html (6134B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title> Test fetch.integrity on console report for serviceWorker and sharedWorker </title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script src="error_reporting_helpers.js"></script> 7 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> 8 <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 9 </head> 10 <body> 11 <div id="content" style="display: none"></div> 12 <script src="utils.js"></script> 13 <script type="text/javascript"> 14 "use strict"; 15 16 let security_localizer = 17 stringBundleService.createBundle("chrome://global/locale/security/security.properties"); 18 19 let consoleScript; 20 let monitorCallbacks = []; 21 22 function registerConsoleMonitor() { 23 return new Promise(resolve => { 24 var url = SimpleTest.getTestFileURL("console_monitor.js"); 25 consoleScript = SpecialPowers.loadChromeScript(url); 26 27 consoleScript.addMessageListener("ready", resolve); 28 consoleScript.addMessageListener("monitor", function(msg) { 29 for (let i = 0; i < monitorCallbacks.length;) { 30 if (monitorCallbacks[i](msg)) { 31 ++i; 32 } else { 33 monitorCallbacks.splice(i, 1); 34 } 35 } 36 }); 37 consoleScript.sendAsyncMessage("load", {}); 38 }); 39 } 40 41 function unregisterConsoleMonitor() { 42 return new Promise(resolve => { 43 consoleScript.addMessageListener("unloaded", () => { 44 consoleScript.destroy(); 45 resolve(); 46 }); 47 consoleScript.sendAsyncMessage("unload", {}); 48 }); 49 } 50 51 function registerConsoleMonitorCallback(callback) { 52 monitorCallbacks.push(callback); 53 } 54 55 function waitForMessages() { 56 let messages = []; 57 58 // process repeated paired arguments of: msgId, args 59 for (let i = 0; i < arguments.length; i += 3) { 60 let msgId = arguments[i]; 61 let args = arguments[i + 1]; 62 messages.push(security_localizer.formatStringFromName(msgId, args)); 63 } 64 65 return new Promise(resolve => { 66 registerConsoleMonitorCallback(msg => { 67 for (let i = 0; i < messages.length; ++i) { 68 if (messages[i] == msg.errorMessage) { 69 messages.splice(i, 1); 70 break; 71 } 72 } 73 74 if (!messages.length) { 75 resolve(); 76 return false; 77 } 78 79 return true; 80 }); 81 }); 82 } 83 84 function expect_security_console_message(/* msgId, args, ... */) { 85 let expectations = []; 86 // process repeated paired arguments of: msgId, args 87 for (let i = 0; i < arguments.length; i += 3) { 88 let msgId = arguments[i]; 89 let args = arguments[i + 1]; 90 let filename = arguments[i + 2]; 91 expectations.push({ 92 errorMessage: security_localizer.formatStringFromName(msgId, args), 93 sourceName: filename, 94 }); 95 } 96 return new Promise(resolve => { 97 SimpleTest.monitorConsole(resolve, expectations); 98 }); 99 } 100 101 // (This doesn't really need to be its own task, but it allows the actual test 102 // case to be self-contained.) 103 add_task(function setupPrefs() { 104 return SpecialPowers.pushPrefEnv({"set": [ 105 ["dom.serviceWorkers.enabled", true], 106 ["dom.serviceWorkers.testing.enabled", true], 107 ["browser.newtab.preload", false], 108 ]}); 109 }); 110 111 add_task(async function test_integrity_serviceWorker() { 112 var filename = make_absolute_url("fetch.js"); 113 var filename2 = make_absolute_url("fake.html"); 114 115 let registration = await navigator.serviceWorker.register("fetch.js", 116 { scope: "./" }); 117 await waitForState(registration.installing, "activated"); 118 119 info("Test for mNavigationInterceptions.") 120 // The client_win will reload to another URL after opening filename2. 121 let client_win = window.open(filename2); 122 123 let expectedMessage = expect_security_console_message( 124 "MalformedIntegrityHash", 125 ["abc"], 126 filename, 127 "NoValidMetadata", 128 [""], 129 filename, 130 ); 131 let expectedMessage2 = expect_security_console_message( 132 "MalformedIntegrityHash", 133 ["abc"], 134 filename, 135 "NoValidMetadata", 136 [""], 137 filename, 138 ); 139 140 info("Test for mControlledDocuments and report error message to console."); 141 // The fetch will succeed because the integrity value is invalid and we are 142 // looking for the console message regarding the bad integrity value. 143 await fetch("fail.html"); 144 145 await wait_for_expected_message(expectedMessage); 146 147 await wait_for_expected_message(expectedMessage2); 148 149 await registration.unregister(); 150 client_win.close(); 151 }); 152 153 add_task(async function test_integrity_sharedWorker() { 154 var filename = make_absolute_url("sharedWorker_fetch.js"); 155 156 await registerConsoleMonitor(); 157 158 info("Attach main window to a SharedWorker."); 159 let sharedWorker = new SharedWorker(filename); 160 let waitForConnected = new Promise((resolve) => { 161 sharedWorker.port.onmessage = function (e) { 162 if (e.data == "Connected") { 163 resolve(); 164 } else { 165 reject(); 166 } 167 } 168 }); 169 await waitForConnected; 170 171 info("Attch another window to the same SharedWorker."); 172 // Open another window and its also managed by the shared worker. 173 let client_win = window.open("create_another_sharedWorker.html"); 174 let waitForBothConnected = new Promise((resolve) => { 175 sharedWorker.port.onmessage = function (e) { 176 if (e.data == "BothConnected") { 177 resolve(); 178 } else { 179 reject(); 180 } 181 } 182 }); 183 await waitForBothConnected; 184 185 let expectedMessage = waitForMessages( 186 "MalformedIntegrityHash", 187 ["abc"], 188 filename, 189 "NoValidMetadata", 190 [""], 191 filename, 192 ); 193 194 let expectedMessage2 = waitForMessages( 195 "MalformedIntegrityHash", 196 ["abc"], 197 filename, 198 "NoValidMetadata", 199 [""], 200 filename, 201 ); 202 203 info("Start to fetch a URL with wrong integrity.") 204 sharedWorker.port.start(); 205 sharedWorker.port.postMessage("StartFetchWithWrongIntegrity"); 206 207 let waitForSRIFailed = new Promise((resolve) => { 208 sharedWorker.port.onmessage = function (e) { 209 if (e.data == "SRI_failed") { 210 resolve(); 211 } else { 212 reject(); 213 } 214 } 215 }); 216 await waitForSRIFailed; 217 218 await expectedMessage; 219 await expectedMessage2; 220 221 client_win.close(); 222 223 await unregisterConsoleMonitor(); 224 }); 225 226 </script> 227 </body> 228 </html>