tor-browser

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

server_multie10s_update.sjs (3130B)


      1 // stolen from file_blocked_script.sjs
      2 function setGlobalState(data, key) {
      3   x = {
      4     data,
      5     QueryInterface(iid) {
      6       return this;
      7     },
      8   };
      9   x.wrappedJSObject = x;
     10   setObjectState(key, x);
     11 }
     12 
     13 function getGlobalState(key) {
     14   var data;
     15   getObjectState(key, function (x) {
     16     data = x && x.wrappedJSObject.data;
     17   });
     18   return data;
     19 }
     20 
     21 function completeBlockingRequest(response) {
     22   response.write("42");
     23   response.finish();
     24 }
     25 
     26 // This stores the response that's currently blocking, or true if the release
     27 // got here before the blocking request.
     28 const BLOCKING_KEY = "multie10s-update-release";
     29 // This tracks the number of blocking requests we received up to this point in
     30 // time.  This value will be cleared when fetched.  It's on the caller to make
     31 // sure that all the blocking requests that might occurr have already occurred.
     32 const COUNT_KEY = "multie10s-update-count";
     33 
     34 /**
     35  * Serve a request that will only be completed when the ?release variant of this
     36  * .sjs is fetched.  This allows us to avoid using a timer, which slows down the
     37  * tests and is brittle under slow hardware.
     38  */
     39 function handleBlockingRequest(request, response) {
     40   response.processAsync();
     41   response.setHeader("Content-Type", "application/javascript", false);
     42 
     43   const existingCount = getGlobalState(COUNT_KEY) || 0;
     44   setGlobalState(existingCount + 1, COUNT_KEY);
     45 
     46   const alreadyReleased = getGlobalState(BLOCKING_KEY);
     47   if (alreadyReleased === true) {
     48     completeBlockingRequest(response);
     49     setGlobalState(null, BLOCKING_KEY);
     50   } else if (alreadyReleased) {
     51     // If we've got another response stacked up, this means something is wrong
     52     // with the test.  The count mechanism will detect this, so just let this
     53     // one through so we fail fast rather than hanging.
     54     dump("we got multiple blocking requests stacked up!!\n");
     55     completeBlockingRequest(response);
     56   } else {
     57     setGlobalState(response, BLOCKING_KEY);
     58   }
     59 }
     60 
     61 function handleReleaseRequest(request, response) {
     62   const blockingResponse = getGlobalState(BLOCKING_KEY);
     63   if (blockingResponse) {
     64     completeBlockingRequest(blockingResponse);
     65     setGlobalState(null, BLOCKING_KEY);
     66   } else {
     67     setGlobalState(true, BLOCKING_KEY);
     68   }
     69 
     70   response.setHeader("Content-Type", "application/json", false);
     71   response.write(JSON.stringify({ released: true }));
     72 }
     73 
     74 function handleCountRequest(request, response) {
     75   const count = getGlobalState(COUNT_KEY) || 0;
     76   // --verify requires that we clear this so the test can be re-run.
     77   setGlobalState(0, COUNT_KEY);
     78 
     79   response.setHeader("Content-Type", "application/json", false);
     80   response.write(JSON.stringify({ count }));
     81 }
     82 
     83 function handleRequest(request, response) {
     84   dump(
     85     "server_multie10s_update.sjs: processing request for " +
     86       request.path +
     87       "?" +
     88       request.queryString +
     89       "\n"
     90   );
     91   const query = new URLSearchParams(request.queryString);
     92   if (query.has("release")) {
     93     handleReleaseRequest(request, response);
     94   } else if (query.has("get-and-clear-count")) {
     95     handleCountRequest(request, response);
     96   } else {
     97     handleBlockingRequest(request, response);
     98   }
     99 }