tor-browser

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

fetch-event-respond-with-readable-stream-worker.js (1939B)


      1 'use strict';
      2 importScripts("/resources/testharness.js");
      3 
      4 const map = new Map();
      5 
      6 self.addEventListener('fetch', event => {
      7  const url = new URL(event.request.url);
      8  if (!url.searchParams.has('stream')) return;
      9 
     10  if (url.searchParams.has('observe-cancel')) {
     11    const id = url.searchParams.get('id');
     12    if (id === undefined) {
     13      event.respondWith(new Error('error'));
     14      return;
     15    }
     16    event.waitUntil(new Promise(resolve => {
     17      map.set(id, {label: 'pending', resolve});
     18    }));
     19 
     20    const stream = new ReadableStream({
     21      pull(c) {
     22        if (url.searchParams.get('enqueue') === 'true') {
     23          url.searchParams.delete('enqueue');
     24          c.enqueue(new Uint8Array([65]));
     25        }
     26      },
     27      cancel() {
     28        map.get(id).label = 'cancelled';
     29      }
     30    });
     31    event.respondWith(new Response(stream));
     32    return;
     33  }
     34 
     35  if (url.searchParams.has('query-cancel')) {
     36    const id = url.searchParams.get('id');
     37    if (id === undefined) {
     38      event.respondWith(new Error('error'));
     39      return;
     40    }
     41    const entry = map.get(id);
     42    if (entry === undefined) {
     43      event.respondWith(new Error('not found'));
     44      return;
     45    }
     46    map.delete(id);
     47    entry.resolve();
     48    event.respondWith(new Response(entry.label));
     49    return;
     50  }
     51 
     52  if (url.searchParams.has('use-fetch-stream')) {
     53    event.respondWith(async function() {
     54      const response = await fetch('pass.txt');
     55      return new Response(response.body);
     56    }());
     57    return;
     58  }
     59 
     60  const delayEnqueue = url.searchParams.has('delay');
     61 
     62  const stream = new ReadableStream({
     63    start(controller) {
     64      const encoder = new TextEncoder();
     65 
     66      const populate = () => {
     67        controller.enqueue(encoder.encode('PASS'));
     68        controller.close();
     69      }
     70 
     71      if (delayEnqueue) {
     72        step_timeout(populate, 16);
     73      }
     74      else {
     75        populate();
     76      }
     77    }
     78  });
     79 
     80  event.respondWith(new Response(stream));
     81 });