tor-browser

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

slow_doc.sjs (3557B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4  * License, v. 2.0. If a copy of the MPL was not distributed with this
      5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 "use strict";
      8 
      9 // stolen from file_blocked_script.sjs
     10 function setGlobalState(key, data) {
     11   const x = {
     12     data,
     13     QueryInterface: ChromeUtils.generateQI([]),
     14   };
     15   x.wrappedJSObject = x;
     16   setObjectState(key, x);
     17 }
     18 
     19 function getGlobalState(key) {
     20   let data;
     21   getObjectState(key, function (x) {
     22     data = x && x.wrappedJSObject.data;
     23   });
     24   return data;
     25 }
     26 
     27 function handleRequest(request, response) {
     28   const second = request.queryString == "second";
     29   const secondInContainer = request.queryString == "secondInContainer";
     30   if (second || secondInContainer) {
     31     // Initial request for document.
     32     response.setStatusLine(request.httpVersion, 200, "OK");
     33     response.setHeader("Cache-Control", "no-cache", false);
     34     response.setHeader("Content-Type", "text/html", false);
     35     response.write("<!doctype html>");
     36     response.write('<p id="first">first</p>');
     37     if (secondInContainer) {
     38       response.write("<section>");
     39     }
     40     // Reference a slow script which will block parsing the rest of this
     41     // document.
     42     response.write('<script src="?script"></script>');
     43     response.write('<p id="second">second</p>');
     44     if (secondInContainer) {
     45       response.write("</section>");
     46     }
     47     return;
     48   }
     49 
     50   if (request.queryString == "script") {
     51     // This is the request to load the slow, blocking script.
     52     response.processAsync();
     53     // Store the response in the global state.
     54     setGlobalState("a11y-script-response", response);
     55     const resolve = getGlobalState("a11y-script-resolve");
     56     if (resolve) {
     57       // Sometimes, the request to finish loading the script can arrive before
     58       // the initial request to load the script, since they are requested from
     59       // different processes. Notify the finish request that the initial request
     60       // has been handled.
     61       resolve();
     62     }
     63     return;
     64   }
     65 
     66   if (request.queryString == "scriptFinish") {
     67     // This is the request to finish (unblock) the slow script.
     68     response.processAsync();
     69     const finish = () => {
     70       response.setStatusLine(request.httpVersion, 200, "OK");
     71       response.setHeader("Cache-Control", "no-cache", false);
     72       response.setHeader("Content-Type", "application/json", false);
     73       response.write("true"); // the payload doesn't matter.
     74       response.finish();
     75       const blockedResponse = getGlobalState("a11y-script-response");
     76       blockedResponse.setStatusLine(request.httpVersion, 200, "OK");
     77       blockedResponse.setHeader("Cache-Control", "no-cache", false);
     78       blockedResponse.setHeader("Content-Type", "text/javascript", false);
     79       blockedResponse.write(";"); // the payload doesn't matter.
     80       blockedResponse.finish();
     81       setGlobalState("a11y-script-response", undefined);
     82       setGlobalState("a11y-script-resolve", undefined);
     83     };
     84     if (getGlobalState("a11y-script-response")) {
     85       // The initial script request has already been handled.
     86       finish();
     87     } else {
     88       // This finish request arrived before the initial request. Set up a
     89       // Promise so we know when the initial request has been handled.
     90       const promise = Promise.withResolvers();
     91       promise.promise.then(finish);
     92       setGlobalState("a11y-script-resolve", promise.resolve);
     93     }
     94   }
     95 }