tor-browser

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

streams-close.https.any.js (8719B)


      1 // META: global=window,worker
      2 // META: script=/common/get-host-info.sub.js
      3 // META: script=/common/utils.js
      4 // META: script=resources/webtransport-test-helpers.sub.js
      5 
      6 // Note: There is no aioquic event for STOP_SENDING yet, so the server does
      7 // not support checking this yet. Hence, tests checking from the STOP_SENDING
      8 // signal cannot be tested yet.
      9 
     10 promise_test(async t => {
     11  const id = token();
     12  const wt = new WebTransport(webtransport_url(`client-close.py?token=${id}`));
     13  add_completion_callback(() => wt.close());
     14  await wt.ready;
     15 
     16  const bidi_stream = await wt.createBidirectionalStream();
     17 
     18  const writable = bidi_stream.writable;
     19  writable.close();
     20 
     21  await wait(10);
     22  const data = await query(id);
     23 
     24  assert_own_property(data, 'stream-close-info');
     25  const info = data['stream-close-info'];
     26 
     27  assert_equals(info.source, 'FIN', 'source');
     28 }, 'Close outgoing stream / bidi-1');
     29 
     30 promise_test(async t => {
     31  const id = token();
     32  const wt = new WebTransport(webtransport_url(`client-close.py?token=${id}`));
     33  add_completion_callback(() => wt.close());
     34  await wt.ready;
     35 
     36  const streams_reader = wt.incomingBidirectionalStreams.getReader();
     37  const {value: bidi} = await streams_reader.read();
     38 
     39  const writable = bidi.writable;
     40  writable.close();
     41 
     42  await wait(10);
     43  const data = await query(id);
     44 
     45  assert_own_property(data, 'stream-close-info');
     46  const info = data['stream-close-info'];
     47 
     48  assert_equals(info.source, 'FIN', 'source');
     49 }, 'Close outgoing stream / bidi-2');
     50 
     51 promise_test(async t => {
     52  const id = token();
     53  const wt = new WebTransport(webtransport_url(`client-close.py?token=${id}`));
     54  add_completion_callback(() => wt.close());
     55  await wt.ready;
     56 
     57  const writable = await wt.createUnidirectionalStream();
     58  writable.close();
     59 
     60  await wait(10);
     61  const data = await query(id);
     62 
     63  assert_own_property(data, 'stream-close-info');
     64  const info = data['stream-close-info'];
     65 
     66  assert_equals(info.source, 'FIN', 'source');
     67 }, 'Close outgoing stream / uni');
     68 
     69 promise_test(async t => {
     70  const id = token();
     71  const wt = new WebTransport(webtransport_url(`client-close.py?token=${id}`));
     72  add_completion_callback(() => wt.close());
     73  await wt.ready;
     74 
     75  const bidi_stream = await wt.createBidirectionalStream();
     76 
     77  const writable = bidi_stream.writable;
     78 
     79  const WT_CODE = 139;
     80  const HTTP_CODE = webtransport_code_to_http_code(WT_CODE);
     81  await writable.abort(
     82      new WebTransportError({streamErrorCode: WT_CODE}));
     83 
     84  await wait(10);
     85  const data = await query(id);
     86 
     87  // Check that stream is aborted with RESET_STREAM with the code and reason
     88  assert_own_property(data, 'stream-close-info');
     89  const info = data['stream-close-info'];
     90 
     91  assert_equals(info.source, 'reset', 'reset stream');
     92  assert_equals(info.code, HTTP_CODE, 'code');
     93 }, 'Abort client-created bidirectional stream');
     94 
     95 promise_test(async t => {
     96  const id = token();
     97  const wt = new WebTransport(webtransport_url(`client-close.py?token=${id}`));
     98  add_completion_callback(() => wt.close());
     99  await wt.ready;
    100 
    101  const stream_reader = wt.incomingBidirectionalStreams.getReader();
    102  const { value: bidi_stream } = await stream_reader.read();
    103  stream_reader.releaseLock();
    104 
    105  const writer = bidi_stream.writable.getWriter();
    106 
    107  const WT_CODE = 52;
    108  const HTTP_CODE = webtransport_code_to_http_code(WT_CODE);
    109  await writer.abort(
    110      new WebTransportError({streamErrorCode: WT_CODE}));
    111 
    112  await wait(10);
    113  const data = await query(id);
    114 
    115  // Check that stream is aborted with RESET_STREAM with the code and reason
    116  assert_own_property(data, 'stream-close-info');
    117  const info = data['stream-close-info'];
    118 
    119  assert_equals(info.source, 'reset', 'reset_stream');
    120  assert_equals(info.code, HTTP_CODE, 'code');
    121 }, 'Abort server-initiated bidirectional stream');
    122 
    123 promise_test(async t => {
    124  const id = token();
    125  const wt = new WebTransport(webtransport_url(`client-close.py?token=${id}`));
    126  add_completion_callback(() => wt.close());
    127  await wt.ready;
    128 
    129  const writable = await wt.createUnidirectionalStream();
    130 
    131  const WT_CODE = 95;
    132  const HTTP_CODE = webtransport_code_to_http_code(WT_CODE);
    133  await writable.abort(
    134      new WebTransportError({streamErrorCode: WT_CODE}));
    135 
    136  await wait(10);
    137  const data = await query(id);
    138 
    139  // Check that stream is aborted with RESET_STREAM with the code and reason
    140  assert_own_property(data, 'stream-close-info');
    141  const info = data['stream-close-info'];
    142 
    143  assert_equals(info.source, 'reset', 'reset_stream');
    144  assert_equals(info.code, HTTP_CODE, 'code');
    145 }, 'Abort unidirectional stream with WebTransportError');
    146 
    147 promise_test(async t => {
    148  const id = token();
    149  const wt = new WebTransport(webtransport_url(`client-close.py?token=${id}`));
    150  add_completion_callback(() => wt.close());
    151  await wt.ready;
    152 
    153  const writable = await wt.createUnidirectionalStream();
    154  const writer = writable.getWriter();
    155 
    156  const WT_CODE = 134;
    157  const HTTP_CODE = webtransport_code_to_http_code(WT_CODE);
    158 
    159  // We use a large chunk so that sending the FIN signal takes time.
    160  const chunk = new Uint8Array(64 * 1024);
    161  const e = new WebTransportError({streamErrorCode: WT_CODE});
    162  // Write a chunk, close the stream, and then abort the stream immediately to
    163  // abort the closing operation.
    164  // TODO: Check that the abort promise is correctly rejected/resolved based on
    165  // the spec discussion at https://github.com/whatwg/streams/issues/1203.
    166  await writer.write(chunk);
    167  const close_promise = writer.close();
    168  const abort_promise = writer.abort(e);
    169 
    170  await promise_rejects_exactly(t, e, close_promise, 'close_promise');
    171  await promise_rejects_exactly(t, e, writer.closed, '.closed');
    172  await promise_rejects_exactly(t, e, abort_promise, 'abort_promise');
    173  writer.releaseLock();
    174 
    175  await wait(10);
    176  const data = await query(id);
    177 
    178  // Check that stream is aborted with RESET_STREAM with the code and reason
    179  assert_own_property(data, 'stream-close-info');
    180  const info = data['stream-close-info'];
    181 
    182  assert_equals(info.source, 'reset', 'reset_stream');
    183  assert_equals(info.code, HTTP_CODE, 'code');
    184 }, 'Close and abort unidirectional stream');
    185 
    186 promise_test(async t => {
    187  const id = token();
    188  const wt = new WebTransport(webtransport_url(`client-close.py?token=${id}`));
    189  add_completion_callback(() => wt.close());
    190  await wt.ready;
    191 
    192  const writable = await wt.createUnidirectionalStream();
    193  await writable.abort();
    194 
    195  await wait(10);
    196  const data = await query(id);
    197 
    198  // Check that stream is aborted with RESET_STREAM with the code and reason
    199  assert_own_property(data, 'stream-close-info');
    200  const info = data['stream-close-info'];
    201 
    202  assert_equals(info.source, 'reset', 'reset_stream');
    203  assert_equals(info.code, webtransport_code_to_http_code(0), 'code');
    204 }, 'Abort unidirectional stream with default error code');
    205 
    206 promise_test(async t => {
    207  const WT_CODE = 0;
    208  const HTTP_CODE = webtransport_code_to_http_code(WT_CODE);
    209  const wt = new WebTransport(
    210    webtransport_url(`abort-stream-from-server.py?code=${HTTP_CODE}`));
    211  add_completion_callback(() => wt.close());
    212  await wt.ready;
    213 
    214  const writable = await wt.createUnidirectionalStream();
    215  const writer = writable.getWriter();
    216 
    217  // Write something, to make the stream visible to the server side.
    218  await writer.write(new Uint8Array([64]));
    219 
    220  // Sadly we cannot use promise_rejects_dom as the error constructor is
    221  // WebTransportError rather than DOMException. Ditto below.
    222  // We get a possible error, and then make sure wt.closed is rejected with it.
    223  const e = await writer.closed.catch(e => e);
    224  await promise_rejects_exactly(
    225      t, e, writer.closed, 'closed promise should be rejected');
    226  assert_true(e instanceof WebTransportError);
    227  assert_equals(e.source, 'stream', 'source');
    228  assert_equals(e.streamErrorCode, WT_CODE, 'streamErrorCode');
    229 }, 'STOP_SENDING coming from server');
    230 
    231 promise_test(async t => {
    232  const WT_CODE = 0xffffffff;
    233  const HTTP_CODE = webtransport_code_to_http_code(WT_CODE);
    234  const wt = new WebTransport(
    235    webtransport_url(`abort-stream-from-server.py?code=${HTTP_CODE}`));
    236  add_completion_callback(() => wt.close());
    237  await wt.ready;
    238 
    239  const bidi = await wt.createBidirectionalStream();
    240  const writer = bidi.writable.getWriter();
    241 
    242  // Write something, to make the stream visible to the server side.
    243  await writer.write(new Uint8Array([64]));
    244 
    245  const reader = bidi.readable.getReader();
    246  const e = await reader.closed.catch(e => e);
    247  await promise_rejects_exactly(
    248      t, e, reader.closed, 'closed promise should be rejected');
    249  assert_true(e instanceof WebTransportError);
    250  assert_equals(e.source, 'stream', 'source');
    251  assert_equals(e.streamErrorCode, WT_CODE, 'streamErrorCode');
    252 }, 'RESET_STREAM coming from server');