opaque-origin.html (7138B)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset=utf-8> 5 <meta name="timeout" content="long"> 6 <title></title> 7 <script src=/resources/testharness.js></script> 8 <script src=/resources/testharnessreport.js></script> 9 </head> 10 <body> 11 <script> 12 <!-- 13 promise_test(t => { 14 return new Promise((resolve) => { 15 let ifr = document.createElement("iframe"); 16 ifr.src = 17 "data:text/html,<script> let bc = new BroadcastChannel(\"test\");" + 18 "bc.onmessage = (e) => {" + 19 " if (e.data == \"ping\") bc.postMessage('pong');"+ 20 " else parent.postMessage({workerMessageOrigin: e.data, messageOrigin: e.origin}, \"*\"); };" + 21 "new Worker(URL.createObjectURL(new Blob([\"" + 22 "let bc2 = new BroadcastChannel('test'); bc2.postMessage('ping'); " + 23 "bc2.onmessage = e => bc2.postMessage(e.origin);" + 24 "\"], {type: 'text/javascript'}))); </script>"; 25 window.addEventListener("message", t.step_func(e => { 26 assert_equals(e.data.workerMessageOrigin, "null"); 27 assert_equals(e.data.messageOrigin, "null"); 28 resolve(); 29 }), {once: true}); 30 t.add_cleanup(() => { document.body.removeChild(ifr) }); 31 document.body.appendChild(ifr); 32 }); 33 }, "Opaque origin should be serialized to \"null\""); 34 35 36 const iframe_src = (channel_name, iframe_name) => `data:text/html,<script> 37 let bc2 = new BroadcastChannel("${channel_name}"); 38 bc2.onmessage = (e) => { 39 if (e.data == "from-${iframe_name}") { 40 parent.postMessage("${iframe_name}-done", "*"); 41 } else { 42 parent.postMessage("fail", "*"); 43 } 44 }; 45 let bc3 = new BroadcastChannel("${channel_name}"); 46 bc3.postMessage("from-${iframe_name}"); 47 </script>`; 48 49 promise_test(t => { 50 return new Promise((resolve, reject) => { 51 const channel_name = "opaque-origin-test-2"; 52 const bc1 = new BroadcastChannel(channel_name); 53 bc1.onmessage = t.unreached_func("Received message from an opaque origin"); 54 55 // We'll create an iframe and have it send a BroadcastChannel message 56 // between two instances. Once the message is received, it will postMessage 57 // back and we'll repeat this with another iframe. If the first 58 // BroadcastChannel message is received by `bc1`, or if the second 59 // BroadcastChannel message is received by `bc1` or `bc2` in the first 60 // iframe, then the test should fail. 61 62 window.addEventListener("message", e => { 63 if(e.data == "iframe1-done") { 64 let iframe2 = document.createElement("iframe"); 65 iframe2.src = iframe_src(channel_name, "iframe2"); 66 t.add_cleanup(() => { document.body.removeChild(iframe2) }); 67 document.body.appendChild(iframe2); 68 } else if(e.data == "iframe2-done") { 69 resolve(); 70 } else if(e.data == "fail") { 71 reject("One opaque origin received a message from the other"); 72 } else { 73 reject("An unexpected error occurred"); 74 } 75 }); 76 77 let iframe1 = document.createElement("iframe"); 78 iframe1.src = iframe_src(channel_name, "iframe1"); 79 t.add_cleanup(() => { document.body.removeChild(iframe1) }); 80 document.body.appendChild(iframe1); 81 }); 82 }, "BroadcastChannel messages from opaque origins should be self-contained"); 83 84 const data_url_worker_src = (channel_name, worker_name) => { 85 const source = ` 86 const handler = (reply) => { 87 let bc2 = new BroadcastChannel("${channel_name}"); 88 bc2.onmessage = (e) => { 89 if (e.data == "from-${worker_name}") { 90 reply("${worker_name}-done"); 91 } else { 92 reply("fail"); 93 } 94 }; 95 let bc3 = new BroadcastChannel("${channel_name}"); 96 bc3.postMessage("from-${worker_name}"); 97 }; 98 // For dedicated workers: 99 self.addEventListener("message", () => handler(self.postMessage)); 100 // For shared workers: 101 self.addEventListener("connect", (e) => { 102 var port = e.ports[0]; 103 port.onmessage = () => handler(msg => port.postMessage(msg)); 104 port.start(); 105 106 }); 107 `; 108 return "data:,".concat(encodeURIComponent(source)); 109 } 110 111 promise_test(t => { 112 return new Promise((resolve, reject) => { 113 const channel_name = "opaque-origin-test-3"; 114 const bc1 = new BroadcastChannel(channel_name); 115 bc1.onmessage = e => { reject("Received message from an opaque origin"); }; 116 117 // Same as the previous test but with data URL dedicated workers (which 118 // should have opaque origins per the HTML spec). 119 const worker_name_prefix = "data-url-dedicated-worker"; 120 const worker_1_name = `${worker_name_prefix}-1`; 121 const worker_2_name = `${worker_name_prefix}-2`; 122 123 const handler = e => { 124 if(e.data == `${worker_1_name}-done`) { 125 const worker2 = new Worker(data_url_worker_src(channel_name, worker_2_name)); 126 t.add_cleanup(() => worker2.terminate()); 127 worker2.addEventListener("message", handler); 128 worker2.postMessage("go!"); 129 } else if(e.data == `${worker_2_name}-done`) { 130 resolve(); 131 } else if(e.data == "fail") { 132 reject("One opaque origin received a message from the other"); 133 } else { 134 reject("An unexpected error occurred"); 135 } 136 }; 137 138 let worker1 = new Worker(data_url_worker_src(channel_name, worker_1_name)); 139 t.add_cleanup(() => worker1.terminate()); 140 worker1.addEventListener("message", handler); 141 worker1.postMessage("go!"); 142 }); 143 }, "BroadcastChannel messages from data URL dedicated workers should be self-contained"); 144 145 promise_test(() => { 146 return new Promise((resolve, reject) => { 147 const channel_name = "opaque-origin-test-4"; 148 const bc1 = new BroadcastChannel(channel_name); 149 150 // Same as the previous test but with data URL shared workers (which 151 // should have opaque origins per the HTML spec). 152 const worker_name_prefix = "data-url-shared-worker"; 153 const worker_1_name = `${worker_name_prefix}-1`; 154 const worker_2_name = `${worker_name_prefix}-2`; 155 156 const handler = e => { 157 if (e.data == `${worker_1_name}-done`) { 158 const worker_script = data_url_worker_src(channel_name, worker_2_name); 159 const worker2 = new SharedWorker(worker_script, worker_2_name); 160 worker2.port.addEventListener("message", handler); 161 worker2.port.start(); 162 worker2.port.postMessage("go!"); 163 } else if(e.data == `${worker_2_name}-done`) { 164 resolve(); 165 } else if(e.data == "fail") { 166 reject("One opaque origin received a message from the other"); 167 } else { 168 reject("An unexpected error occurred"); 169 } 170 }; 171 172 bc1.onmessage = e => { 173 if (e.data == "go!") { 174 const worker_script = data_url_worker_src(channel_name, worker_1_name); 175 const worker1 = new SharedWorker(worker_script, worker_1_name); 176 worker1.port.addEventListener("message", handler); 177 worker1.port.start(); 178 worker1.port.postMessage("go!"); 179 } else { 180 reject("Received message from an opaque origin"); 181 } 182 }; 183 184 // Ensure that the BroadcastChannel instance above can receive messages 185 // before we create the first shared worker. 186 const bc2 = new BroadcastChannel(channel_name); 187 bc2.postMessage("go!"); 188 }); 189 }, "BroadcastChannel messages from data URL shared workers should be self-contained"); 190 //--> 191 </script> 192 </body> 193 </html>