coop-coep.py (3093B)
1 import json 2 3 def main(request, response): 4 requestData = request.GET 5 if request.method == u"POST": 6 requestData = request.POST 7 8 coop = requestData.first(b"coop") 9 coopReportOnly = requestData.first(b"coop-report-only", None) 10 coep = requestData.first(b"coep") 11 coepReportOnly = requestData.first(b"coep-report-only", None) 12 redirect = requestData.first(b"redirect", None) 13 if coop != b"": 14 response.headers.set(b"Cross-Origin-Opener-Policy", coop) 15 if coopReportOnly is not None: 16 response.headers.set(b"Cross-Origin-Opener-Policy-Report-Only", coopReportOnly) 17 if coep != b"": 18 response.headers.set(b"Cross-Origin-Embedder-Policy", coep) 19 if coepReportOnly is not None: 20 response.headers.set(b"Cross-Origin-Embedder-Policy-Report-Only", coepReportOnly) 21 if b'cache' in requestData: 22 response.headers.set(b'Cache-Control', b'max-age=3600') 23 host = request.url_parts[1] 24 25 if redirect != None: 26 response.status = 302 27 response.headers.set(b"Location", redirect) 28 return 29 30 # Collect relevant params to be visible to response JS 31 params = {} 32 for key in (b"navHistory", b"avoidBackAndForth", b"navigate", b"channel", b"responseToken", b"iframeToken"): 33 value = requestData.first(key, None) 34 params[key.decode()] = value and value.decode() 35 36 response.content = b""" 37 <!doctype html> 38 <meta charset=utf-8> 39 <script src="/common/get-host-info.sub.js"></script> 40 <script src="/html/cross-origin-opener-policy/resources/fully-loaded.js"></script> 41 <body> 42 <script> 43 const params = %s; 44 const navHistory = params.navHistory; 45 const avoidBackAndForth = params.avoidBackAndForth; 46 const navigate = params.navigate; 47 if (navHistory !== null) { 48 fullyLoaded().then(() => { 49 history.go(Number(navHistory)); 50 }); 51 } else if (navigate !== null && (history.length === 1 || !avoidBackAndForth)) { 52 fullyLoaded().then(() => { 53 self.location = navigate; 54 }); 55 } else { 56 let openerDOMAccessAllowed = false; 57 try { 58 openerDOMAccessAllowed = !!self.opener.document.URL; 59 } catch(ex) { 60 } 61 // Handle the response from the frame, closing the popup once the 62 // test completes. 63 addEventListener("message", event => { 64 if (event.data == "close") { 65 close(); 66 } 67 }); 68 iframe = document.createElement("iframe"); 69 iframe.onload = () => { 70 const payload = { name: self.name, opener: !!self.opener, openerDOMAccess: openerDOMAccessAllowed }; 71 iframe.contentWindow.postMessage(payload, "*"); 72 }; 73 const channelName = params.channel; 74 const responseToken = params.responseToken; 75 const iframeToken = params.iframeToken; 76 iframe.src = `${get_host_info().HTTPS_ORIGIN}/html/cross-origin-opener-policy/resources/postback.html` + 77 `?channel=${encodeURIComponent(channelName)}` + 78 `&responseToken=${responseToken}` + 79 `&iframeToken=${iframeToken}`; 80 document.body.appendChild(iframe); 81 } 82 </script> 83 </body> 84 """ % json.dumps(params).encode("utf-8")