tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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")