tor-browser

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

RTCIceCandidate-constructor.html (10840B)


      1 <!doctype html>
      2 <title>RTCIceCandidate constructor</title>
      3 <script src=/resources/testharness.js></script>
      4 <script src=/resources/testharnessreport.js></script>
      5 <script>
      6  'use strict';
      7 
      8  const candidateString = 'candidate:1905690388 1 udp 2113937151 192.168.0.1 58041 typ host generation 0 ufrag thC8 network-cost 50';
      9  const candidateString2 = 'candidate:435653019 2 tcp 1845501695 192.168.0.196 4444 typ srflx raddr www.example.com rport 22222 tcptype active';
     10  const arbitraryString = '<arbitrary string[0] content>;';
     11 
     12  test(t => {
     13    // The argument for RTCIceCandidateInit is optional (w3c/webrtc-pc #1153 #1166),
     14    // but the constructor throws because both sdpMid and sdpMLineIndex are null by default.
     15    // Note that current browsers pass this test but may throw TypeError for
     16    // different reason, i.e. they don't accept empty argument.
     17    // Further tests below are used to differentiate the errors.
     18    assert_throws_js(TypeError, () => new RTCIceCandidate());
     19  }, 'new RTCIceCandidate()');
     20 
     21  test(t => {
     22    // All fields in RTCIceCandidateInit are optional,
     23    // but the constructor throws because both sdpMid and sdpMLineIndex are null by default.
     24    // Note that current browsers pass this test but may throw TypeError for
     25    // different reason, i.e. they don't allow undefined candidate string.
     26    // Further tests below are used to differentiate the errors.
     27    assert_throws_js(TypeError, () => new RTCIceCandidate({}));
     28  }, 'new RTCIceCandidate({})');
     29 
     30  test(t => {
     31    // Checks that manually filling the default values for RTCIceCandidateInit
     32    // still throws because both sdpMid and sdpMLineIndex are null
     33    assert_throws_js(TypeError,
     34      () => new RTCIceCandidate({
     35        candidate: '',
     36        sdpMid: null,
     37        sdpMLineIndex: null,
     38        usernameFragment: undefined
     39      }));
     40  }, 'new RTCIceCandidate({ ... }) with manually filled default values');
     41 
     42  test(t => {
     43    // Checks that explicitly setting both sdpMid and sdpMLineIndex null should throw
     44    assert_throws_js(TypeError,
     45      () => new RTCIceCandidate({
     46        sdpMid: null,
     47        sdpMLineIndex: null
     48      }));
     49  }, 'new RTCIceCandidate({ sdpMid: null, sdpMLineIndex: null })');
     50 
     51  test(t => {
     52    // Throws because both sdpMid and sdpMLineIndex are null by default
     53    assert_throws_js(TypeError,
     54      () => new RTCIceCandidate({
     55        candidate: ''
     56      }));
     57  }, `new RTCIceCandidate({ candidate: '' })`);
     58 
     59  test(t => {
     60    // Throws because both sdpMid and sdpMLineIndex are null by default
     61    assert_throws_js(TypeError,
     62      () => new RTCIceCandidate({
     63        candidate: null
     64      }));
     65  }, `new RTCIceCandidate({ candidate: null })`);
     66 
     67  test(t => {
     68    // Throws because both sdpMid and sdpMLineIndex are null by default
     69    assert_throws_js(TypeError,
     70      () => new RTCIceCandidate({
     71        candidate: candidateString
     72      }));
     73  }, 'new RTCIceCandidate({ ... }) with valid candidate string only');
     74 
     75  test(t => {
     76    const candidate = new RTCIceCandidate({ sdpMid: 'audio' });
     77 
     78    assert_equals(candidate.candidate, '', 'candidate');
     79    assert_equals(candidate.sdpMid, 'audio', 'sdpMid');
     80    assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex');
     81    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
     82  }, `new RTCIceCandidate({ sdpMid: 'audio' })`);
     83 
     84  test(t => {
     85    const candidate = new RTCIceCandidate({ sdpMLineIndex: 0 });
     86 
     87    assert_equals(candidate.candidate, '', 'candidate');
     88    assert_equals(candidate.sdpMid, null, 'sdpMid');
     89    assert_equals(candidate.sdpMLineIndex, 0, 'sdpMLineIndex');
     90    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
     91  }, 'new RTCIceCandidate({ sdpMLineIndex: 0 })');
     92 
     93  test(t => {
     94    const candidate = new RTCIceCandidate({
     95      sdpMid: 'audio',
     96      sdpMLineIndex: 0
     97    });
     98 
     99    assert_equals(candidate.candidate, '', 'candidate');
    100    assert_equals(candidate.sdpMid, 'audio', 'sdpMid');
    101    assert_equals(candidate.sdpMLineIndex, 0, 'sdpMLineIndex');
    102    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
    103  }, `new RTCIceCandidate({ sdpMid: 'audio', sdpMLineIndex: 0 })`);
    104 
    105  test(t => {
    106    const candidate = new RTCIceCandidate({
    107      candidate: '',
    108      sdpMid: 'audio'
    109    });
    110 
    111    assert_equals(candidate.candidate, '', 'candidate');
    112    assert_equals(candidate.sdpMid, 'audio', 'sdpMid');
    113    assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex');
    114    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
    115  }, `new RTCIceCandidate({ candidate: '', sdpMid: 'audio' }`);
    116 
    117  test(t => {
    118    const candidate = new RTCIceCandidate({
    119      candidate: null,
    120      sdpMLineIndex: 0
    121    });
    122 
    123    assert_equals(candidate.candidate, 'null', 'candidate');
    124    assert_equals(candidate.sdpMid, null, 'sdpMid', 'sdpMid');
    125    assert_equals(candidate.sdpMLineIndex, 0, 'sdpMLineIndex');
    126    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
    127  }, `new RTCIceCandidate({ candidate: null, sdpMLineIndex: 0 }`);
    128 
    129  test(t => {
    130    const candidate = new RTCIceCandidate({
    131      candidate: candidateString,
    132      sdpMid: 'audio'
    133    });
    134 
    135    assert_equals(candidate.candidate, candidateString, 'candidate');
    136    assert_equals(candidate.sdpMid, 'audio', 'sdpMid');
    137    assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex');
    138    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
    139  }, 'new RTCIceCandidate({ ... }) with valid candidate string and sdpMid');
    140 
    141  test(t => {
    142    // candidate string is not validated in RTCIceCandidate
    143    const candidate = new RTCIceCandidate({
    144      candidate: arbitraryString,
    145      sdpMid: 'audio'
    146    });
    147 
    148    assert_equals(candidate.candidate, arbitraryString, 'candidate');
    149    assert_equals(candidate.sdpMid, 'audio', 'sdpMid');
    150    assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex');
    151    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
    152  }, 'new RTCIceCandidate({ ... }) with invalid candidate string and sdpMid');
    153 
    154 ["most", "all"].forEach(howMany => {
    155  test(t => {
    156    const candidate = new RTCIceCandidate({
    157      candidate: candidateString,
    158      sdpMid: 'video',
    159      sdpMLineIndex: 1,
    160      usernameFragment: 'test',
    161      relayProtocol: 'udp',
    162      url: 'stun:stun.example.org'
    163    });
    164 
    165    assert_equals(candidate.candidate, candidateString, 'candidate');
    166    assert_equals(candidate.sdpMid, 'video', 'sdpMid');
    167    assert_equals(candidate.sdpMLineIndex, 1, 'sdpMLineIndex');
    168    assert_equals(candidate.usernameFragment, 'test', 'usernameFragment');
    169 
    170    // The following fields should match those in the candidate field
    171    assert_equals(candidate.foundation, '1905690388', 'foundation');
    172    assert_equals(candidate.component, 'rtp', 'component');
    173    assert_equals(candidate.priority, 2113937151, 'priority');
    174    assert_equals(candidate.address, '192.168.0.1', 'address');
    175    assert_equals(candidate.protocol, 'udp', 'protocol');
    176    assert_equals(candidate.port, 58041, 'port');
    177    assert_equals(candidate.type, 'host', 'type');
    178    assert_equals(candidate.tcpType, null, 'tcpType');
    179    assert_equals(candidate.relatedAddress, null, 'relatedAddress');
    180    assert_equals(candidate.relatedPort, null, 'relatedPort');
    181    // The remaining fields are newer, so test them seperately
    182    if (howMany != "most") {
    183      assert_equals(candidate.relayProtocol, 'udp', 'relayProtocol');
    184      assert_equals(candidate.url, 'stun:stun.example.org', 'url');
    185    }
    186  }, `new RTCIceCandidate({ ... }) with nondefault values for ${howMany} fields`);
    187 
    188  test(t => {
    189    const candidate = new RTCIceCandidate({
    190      candidate: candidateString2,
    191      sdpMid: 'video',
    192      sdpMLineIndex: 1,
    193      usernameFragment: 'user1',
    194      relayProtocol: 'tcp',
    195      url: 'turn:turn.example.net'
    196    });
    197 
    198    assert_equals(candidate.candidate, candidateString2, 'candidate');
    199    assert_equals(candidate.sdpMid, 'video', 'sdpMid');
    200    assert_equals(candidate.sdpMLineIndex, 1, 'sdpMLineIndex');
    201    assert_equals(candidate.usernameFragment, 'user1', 'usernameFragment');
    202 
    203    // The following fields should match those in the candidate field
    204    assert_equals(candidate.foundation, '435653019', 'foundation');
    205    assert_equals(candidate.component, 'rtcp', 'component');
    206    assert_equals(candidate.priority, 1845501695, 'priority');
    207    assert_equals(candidate.address, '192.168.0.196', 'address');
    208    assert_equals(candidate.protocol, 'tcp', 'protocol');
    209    assert_equals(candidate.port, 4444, 'port');
    210    assert_equals(candidate.type, 'srflx', 'type');
    211    assert_equals(candidate.tcpType, 'active', 'tcpType');
    212    assert_equals(candidate.relatedAddress, 'www.example.com', 'relatedAddress');
    213    assert_equals(candidate.relatedPort, 22222, 'relatedPort');
    214    // The remaining fields are newer, so test them seperately
    215    if (howMany != "most") {
    216      assert_equals(candidate.url, 'turn:turn.example.net', 'url');
    217      assert_equals(candidate.relayProtocol, 'tcp', 'relayProtocol');
    218    }
    219  }, `new RTCIceCandidate({ ... }) with nondefault values for ${howMany} fields, tcp candidate`);
    220 });
    221 
    222  test(t => {
    223    let candidate = new RTCIceCandidate(new RTCIceCandidate({
    224      sdpMid: 'video',
    225      relayProtocol: 'tls',
    226      url: 'turn:turn.example.net'
    227    }));
    228 
    229    assert_equals(candidate.relayProtocol, 'tls', 'relayProtocol cloned');
    230    assert_equals(candidate.url, 'turn:turn.example.net', 'url cloned');
    231 
    232    candidate = new RTCIceCandidate(JSON.parse(JSON.stringify(candidate)));
    233    assert_equals(candidate.relayProtocol, null, 'relayProtocol not signaled');
    234    assert_equals(candidate.url, null, 'url not signaled');
    235  }, `new RTCIceCandidate({ relayProtocol, url }) cloned vs signaled`);
    236 
    237  test(t => {
    238    // sdpMid is not validated in RTCIceCandidate
    239    const candidate = new RTCIceCandidate({
    240      sdpMid: arbitraryString
    241    });
    242 
    243    assert_equals(candidate.candidate, '', 'candidate');
    244    assert_equals(candidate.sdpMid, arbitraryString, 'sdpMid');
    245    assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex');
    246    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
    247  }, 'new RTCIceCandidate({ ... }) with invalid sdpMid');
    248 
    249 
    250  test(t => {
    251    // Some arbitrary large out of bound line index that practically
    252    // do not reference any m= line in SDP.
    253    // However sdpMLineIndex is not validated in RTCIceCandidate
    254    // and it has no knowledge of the SDP it is associated with.
    255    const candidate = new RTCIceCandidate({
    256      sdpMLineIndex: 65535
    257    });
    258 
    259    assert_equals(candidate.candidate, '', 'candidate');
    260    assert_equals(candidate.sdpMid, null, 'sdpMid');
    261    assert_equals(candidate.sdpMLineIndex, 65535, 'sdpMLineIndex');
    262    assert_equals(candidate.usernameFragment, null, 'usernameFragment');
    263  }, 'new RTCIceCandidate({ ... }) with invalid sdpMLineIndex');
    264 
    265 </script>