tor-browser

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

test_simple_stream.js (5882B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // keep eslint happy until it knows about WebTransport
      6 /* global WebTransport:false */
      7 /* global TextDecoderStream:false */
      8 
      9 // Using multiple files to reduce racing
     10 // This file tests reading/writing to incoming/outgoing streams (uni & bidi)
     11 //
     12 "use strict";
     13 
     14 var h3Port;
     15 var host;
     16 
     17 registerCleanupFunction(async () => {
     18  Services.prefs.clearUserPref("network.dns.localDomains");
     19  Services.prefs.clearUserPref("network.webtransport.enabled");
     20  Services.prefs.clearUserPref("network.webtransport.redirect.enabled");
     21 });
     22 
     23 var { NetUtil } = ChromeUtils.importESModule(
     24  "resource://gre/modules/NetUtil.sys.mjs"
     25 );
     26 
     27 function readFile(file) {
     28  let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
     29    Ci.nsIFileInputStream
     30  );
     31  fstream.init(file, -1, 0, 0);
     32  let data = NetUtil.readInputStreamToString(fstream, fstream.available());
     33  fstream.close();
     34  return data;
     35 }
     36 
     37 function addCertFromFile(certdb, filename, trustString) {
     38  let certFile = do_get_file(filename, false);
     39  let pem = readFile(certFile)
     40    .replace(/-----BEGIN CERTIFICATE-----/, "")
     41    .replace(/-----END CERTIFICATE-----/, "")
     42    .replace(/[\r\n]/g, "");
     43  certdb.addCertFromBase64(pem, trustString);
     44 }
     45 
     46 add_setup(async function setup() {
     47  Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com");
     48  Services.prefs.setBoolPref("network.webtransport.enabled", true);
     49  Services.prefs.setBoolPref("network.webtransport.redirect.enabled", true);
     50 
     51  h3Port = Services.env.get("MOZHTTP3_PORT");
     52  Assert.notEqual(h3Port, null);
     53  Assert.notEqual(h3Port, "");
     54  host = "foo.example.com:" + h3Port;
     55  do_get_profile();
     56 
     57  let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
     58    Ci.nsIX509CertDB
     59  );
     60  // `../unit/` so that unit_ipc tests can use as well
     61  addCertFromFile(
     62    certdb,
     63    "../../../../netwerk/test/unit/http2-ca.pem",
     64    "CTu,u,u"
     65  );
     66 });
     67 
     68 // Read all chunks from |readable_stream|, decode chunks to a utf-8 string, then
     69 // return the string. (borrowed from wpt tests)
     70 async function read_stream_as_string(readable_stream) {
     71  const decoder = new TextDecoderStream();
     72  const decode_stream = readable_stream.pipeThrough(decoder);
     73  const reader = decode_stream.getReader();
     74 
     75  let chunks = "";
     76  while (true) {
     77    const { value: chunk, done } = await reader.read();
     78    if (done) {
     79      break;
     80    }
     81    chunks += chunk;
     82  }
     83  reader.releaseLock();
     84  return chunks;
     85 }
     86 
     87 add_task(async function test_wt_incoming_unidi_stream() {
     88  // trigger stream creation server side and default echo
     89  let wt = new WebTransport(
     90    "https://" + host + "/create_unidi_stream_and_hello"
     91  );
     92  await wt.ready;
     93 
     94  const streams = await wt.incomingUnidirectionalStreams;
     95  const stream_reader = streams.getReader();
     96  const { value: recv_stream } = await stream_reader.read();
     97  let str = await read_stream_as_string(recv_stream);
     98  stream_reader.releaseLock();
     99  Assert.equal(str, "qwerty");
    100 
    101  wt.close();
    102 });
    103 
    104 add_task(async function test_wt_incoming_and_outgoing_unidi_stream() {
    105  // create the client's incoming stream from the server side
    106  // we need it to listen to the echo back
    107  let wt = new WebTransport("https://" + host + "/create_unidi_stream");
    108  await wt.ready;
    109 
    110  // send hello to server
    111  let expected = "uni_hello";
    112  let writableStream = await wt.createUnidirectionalStream(); // only triggers NewStream OnWrite
    113  let wsDefaultWriter = writableStream.getWriter();
    114  await wsDefaultWriter.ready;
    115  let data = new TextEncoder().encode(expected);
    116  await wsDefaultWriter.write(data); // triggers Http3ServerEvent::Data
    117  await wsDefaultWriter.close();
    118  wsDefaultWriter.releaseLock();
    119 
    120  // read the echo
    121  const streams = await wt.incomingUnidirectionalStreams;
    122  const stream_reader = streams.getReader();
    123  const { value: recv_stream } = await stream_reader.read();
    124  let str = await read_stream_as_string(recv_stream);
    125  Assert.equal(str, expected);
    126  stream_reader.releaseLock();
    127  await recv_stream.closed;
    128 
    129  wt.close();
    130 });
    131 
    132 add_task(async function test_wt_outgoing_bidi_stream() {
    133  let wt = new WebTransport("https://" + host + "/success");
    134  await wt.ready;
    135 
    136  // write to server
    137  let wtbds = await wt.createBidirectionalStream();
    138  let writableStream = wtbds.writable;
    139  let wsDefaultWriter = writableStream.getWriter();
    140  await wsDefaultWriter.ready;
    141  let expected = "xyzhello";
    142  let data = new TextEncoder().encode(expected);
    143  await wsDefaultWriter.write(data);
    144  await wsDefaultWriter.close();
    145  wsDefaultWriter.releaseLock();
    146 
    147  // string goes through server and is echoed back here
    148  const str = await read_stream_as_string(wtbds.readable);
    149  Assert.equal(str, expected);
    150 
    151  wt.close();
    152 });
    153 
    154 add_task(async function test_wt_incoming_bidi_stream() {
    155  let wt = new WebTransport(
    156    "https://" + host + "/create_bidi_stream_and_hello"
    157  );
    158  // await wt.ready; // causes occasional hang on release --verify
    159 
    160  const stream_reader = wt.incomingBidirectionalStreams.getReader();
    161  const { value: bidi_stream } = await stream_reader.read();
    162  stream_reader.releaseLock();
    163 
    164  const str = await read_stream_as_string(bidi_stream.readable);
    165  Assert.equal(str, "asdfg");
    166 
    167  wt.close();
    168 });
    169 
    170 add_task(async function test_wt_incoming_bidi_stream_huge_data() {
    171  let wt = new WebTransport(
    172    "https://" + host + "/create_bidi_stream_and_large_data"
    173  );
    174  // await wt.ready; // causes occasional hang on release --verify
    175 
    176  const stream_reader = wt.incomingBidirectionalStreams.getReader();
    177  const { value: bidi_stream } = await stream_reader.read();
    178  stream_reader.releaseLock();
    179 
    180  const str = await read_stream_as_string(bidi_stream.readable);
    181  Assert.equal(str.length, 32 * 1024 * 1024);
    182  wt.close();
    183 });