tor-browser

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

dataChannel.js (9955B)


      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 /**
      6 * Returns the contents of a blob as text
      7 *
      8 * @param {Blob} blob
      9          The blob to retrieve the contents from
     10 */
     11 function getBlobContent(blob) {
     12  return new Promise(resolve => {
     13    var reader = new FileReader();
     14    // Listen for 'onloadend' which will always be called after a success or failure
     15    reader.onloadend = event => resolve(event.target.result);
     16    reader.readAsText(blob);
     17  });
     18 }
     19 
     20 /**
     21 * Returns the contents of a blob as text
     22 *
     23 * @param {ArrayBuffer} arraybuffer
     24          The ArrayBuffer to retrieve the contents from
     25 */
     26 function getArrayBufferContent(arraybuffer) {
     27  const decoder = new TextDecoder("utf-8");
     28  return decoder.decode(arraybuffer);
     29 }
     30 
     31 var commandsCreateDataChannel = [
     32  function PC_REMOTE_EXPECT_DATA_CHANNEL(test) {
     33    test.pcRemote.expectDataChannel();
     34  },
     35 
     36  function PC_LOCAL_CREATE_DATA_CHANNEL(test) {
     37    var channel = test.pcLocal.createDataChannel({});
     38    is(
     39      channel.binaryType,
     40      "arraybuffer",
     41      channel + " is of binary type 'arraybuffer'"
     42    );
     43 
     44    is(
     45      test.pcLocal.signalingState,
     46      STABLE,
     47      "Create datachannel does not change signaling state"
     48    );
     49    return test.pcLocal.observedNegotiationNeeded;
     50  },
     51 ];
     52 
     53 var commandsWaitForDataChannel = [
     54  function PC_LOCAL_VERIFY_DATA_CHANNEL_STATE(test) {
     55    return test.pcLocal.dataChannels[0].opened;
     56  },
     57 
     58  function PC_REMOTE_VERIFY_DATA_CHANNEL_STATE(test) {
     59    return test.pcRemote.nextDataChannel.then(channel => channel.opened);
     60  },
     61 ];
     62 
     63 var commandsCheckDataChannel = [
     64  function SEND_MESSAGE(test) {
     65    var message = "Lorem ipsum dolor sit amet";
     66 
     67    info("Sending message:" + message);
     68    return test.send(message).then(result => {
     69      is(
     70        result.data,
     71        message,
     72        "Message correctly transmitted from pcLocal to pcRemote."
     73      );
     74    });
     75  },
     76 
     77  function SEND_BLOB(test) {
     78    var contents = "At vero eos et accusam et justo duo dolores et ea rebum.";
     79    var blob = new Blob([contents], { type: "text/plain" });
     80 
     81    info("Sending blob");
     82    return test.send(blob).then(result => {
     83      ok(
     84        result.data instanceof ArrayBuffer,
     85        "Received data is of instance ArrayBuffer"
     86      );
     87      is(
     88        result.data.byteLength,
     89        blob.size,
     90        "Received data has the correct size."
     91      );
     92 
     93      const recv_contents = getArrayBufferContent(result.data);
     94      is(recv_contents, contents, "Received data has the correct content.");
     95    });
     96  },
     97 
     98  function CREATE_SECOND_DATA_CHANNEL(test) {
     99    return test.createDataChannel({}).then(result => {
    100      is(
    101        result.remote.binaryType,
    102        "arraybuffer",
    103        "remote data channel is of binary type 'arraybuffer'"
    104      );
    105    });
    106  },
    107 
    108  function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL(test) {
    109    var channels = test.pcRemote.dataChannels;
    110    var message = "I am the Omega";
    111 
    112    info("Sending message:" + message);
    113    return test.send(message).then(result => {
    114      is(
    115        channels.indexOf(result.channel),
    116        channels.length - 1,
    117        "Last channel used"
    118      );
    119      is(result.data, message, "Received message has the correct content.");
    120    });
    121  },
    122 
    123  function SEND_MESSAGE_THROUGH_FIRST_CHANNEL(test) {
    124    var message = "Message through 1st channel";
    125    var options = {
    126      sourceChannel: test.pcLocal.dataChannels[0],
    127      targetChannel: test.pcRemote.dataChannels[0],
    128    };
    129 
    130    info("Sending message:" + message);
    131    return test.send(message, options).then(result => {
    132      is(
    133        test.pcRemote.dataChannels.indexOf(result.channel),
    134        0,
    135        "1st channel used"
    136      );
    137      is(result.data, message, "Received message has the correct content.");
    138    });
    139  },
    140 
    141  function SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL(test) {
    142    var message = "Return a message also through 1st channel";
    143    var options = {
    144      sourceChannel: test.pcRemote.dataChannels[0],
    145      targetChannel: test.pcLocal.dataChannels[0],
    146    };
    147 
    148    info("Sending message:" + message);
    149    return test.send(message, options).then(result => {
    150      is(
    151        test.pcLocal.dataChannels.indexOf(result.channel),
    152        0,
    153        "1st channel used"
    154      );
    155      is(result.data, message, "Return message has the correct content.");
    156    });
    157  },
    158 
    159  function CREATE_NEGOTIATED_DATA_CHANNEL_MAX_RETRANSMITS(test) {
    160    var options = {
    161      negotiated: true,
    162      id: 5,
    163      protocol: "foo/bar",
    164      ordered: false,
    165      maxRetransmits: 500,
    166    };
    167    return test.createDataChannel(options).then(result => {
    168      is(
    169        result.local.binaryType,
    170        "arraybuffer",
    171        result.remote + " is of binary type 'arraybuffer'"
    172      );
    173      is(
    174        result.local.id,
    175        options.id,
    176        result.local + " id is:" + result.local.id
    177      );
    178      is(
    179        result.local.protocol,
    180        options.protocol,
    181        result.local + " protocol is:" + result.local.protocol
    182      );
    183      is(
    184        result.local.ordered,
    185        options.ordered,
    186        result.local + " ordered is:" + result.local.ordered
    187      );
    188      is(
    189        result.local.maxRetransmits,
    190        options.maxRetransmits,
    191        result.local + " maxRetransmits is:" + result.local.maxRetransmits
    192      );
    193      is(
    194        result.local.maxPacketLifeTime,
    195        null,
    196        result.local + " maxPacketLifeTime is:" + result.local.maxPacketLifeTime
    197      );
    198 
    199      is(
    200        result.remote.binaryType,
    201        "arraybuffer",
    202        result.remote + " is of binary type 'arraybuffer'"
    203      );
    204      is(
    205        result.remote.id,
    206        options.id,
    207        result.remote + " id is:" + result.remote.id
    208      );
    209      is(
    210        result.remote.protocol,
    211        options.protocol,
    212        result.remote + " protocol is:" + result.remote.protocol
    213      );
    214      is(
    215        result.remote.ordered,
    216        options.ordered,
    217        result.remote + " ordered is:" + result.remote.ordered
    218      );
    219      is(
    220        result.remote.maxRetransmits,
    221        options.maxRetransmits,
    222        result.remote + " maxRetransmits is:" + result.remote.maxRetransmits
    223      );
    224      is(
    225        result.remote.maxPacketLifeTime,
    226        null,
    227        result.remote +
    228          " maxPacketLifeTime is:" +
    229          result.remote.maxPacketLifeTime
    230      );
    231    });
    232  },
    233 
    234  function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL2(test) {
    235    var channels = test.pcRemote.dataChannels;
    236    var message = "I am the walrus; Goo goo g'joob";
    237 
    238    info("Sending message:" + message);
    239    return test.send(message).then(result => {
    240      is(
    241        channels.indexOf(result.channel),
    242        channels.length - 1,
    243        "Last channel used"
    244      );
    245      is(result.data, message, "Received message has the correct content.");
    246    });
    247  },
    248 
    249  function CREATE_NEGOTIATED_DATA_CHANNEL_MAX_PACKET_LIFE_TIME(test) {
    250    var options = {
    251      ordered: false,
    252      maxPacketLifeTime: 10,
    253    };
    254    return test.createDataChannel(options).then(result => {
    255      is(
    256        result.local.binaryType,
    257        "arraybuffer",
    258        result.local + " is of binary type 'arraybuffer'"
    259      );
    260      is(
    261        result.local.protocol,
    262        "",
    263        result.local + " protocol is:" + result.local.protocol
    264      );
    265      is(
    266        result.local.ordered,
    267        options.ordered,
    268        result.local + " ordered is:" + result.local.ordered
    269      );
    270      is(
    271        result.local.maxRetransmits,
    272        null,
    273        result.local + " maxRetransmits is:" + result.local.maxRetransmits
    274      );
    275      is(
    276        result.local.maxPacketLifeTime,
    277        options.maxPacketLifeTime,
    278        result.local + " maxPacketLifeTime is:" + result.local.maxPacketLifeTime
    279      );
    280 
    281      is(
    282        result.remote.binaryType,
    283        "arraybuffer",
    284        result.remote + " is of binary type 'arraybuffer'"
    285      );
    286      is(
    287        result.remote.protocol,
    288        "",
    289        result.remote + " protocol is:" + result.remote.protocol
    290      );
    291      is(
    292        result.remote.ordered,
    293        options.ordered,
    294        result.remote + " ordered is:" + result.remote.ordered
    295      );
    296      is(
    297        result.remote.maxRetransmits,
    298        null,
    299        result.remote + " maxRetransmits is:" + result.remote.maxRetransmits
    300      );
    301      is(
    302        result.remote.maxPacketLifeTime,
    303        options.maxPacketLifeTime,
    304        result.remote +
    305          " maxPacketLifeTime is:" +
    306          result.remote.maxPacketLifeTime
    307      );
    308    });
    309  },
    310 
    311  function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL3(test) {
    312    var channels = test.pcRemote.dataChannels;
    313    var message = "Nice to see you working maxPacketLifeTime";
    314 
    315    info("Sending message:" + message);
    316    return test.send(message).then(result => {
    317      is(
    318        channels.indexOf(result.channel),
    319        channels.length - 1,
    320        "Last channel used"
    321      );
    322      is(result.data, message, "Received message has the correct content.");
    323    });
    324  },
    325 ];
    326 
    327 var commandsCheckLargeXfer = [
    328  function SEND_BIG_BUFFER(test) {
    329    var size = 2 * 1024 * 1024; // SCTP internal buffer is now 1MB, so use 2MB to ensure the buffer gets full
    330    var buffer = new ArrayBuffer(size);
    331    var options = {};
    332    options.bufferedAmountLowThreshold = 64 * 1024;
    333    info("Sending arraybuffer");
    334    return test.send(buffer, options).then(result => {
    335      ok(
    336        result.data instanceof ArrayBuffer,
    337        "Received data is of instance ArrayBuffer"
    338      );
    339      is(result.data.byteLength, size, "Received data has the correct size.");
    340    });
    341  },
    342 ];
    343 
    344 function addInitialDataChannel(chain) {
    345  chain.insertBefore("PC_LOCAL_CREATE_OFFER", commandsCreateDataChannel);
    346  chain.insertBefore(
    347    "PC_LOCAL_WAIT_FOR_MEDIA_FLOW",
    348    commandsWaitForDataChannel
    349  );
    350  chain.removeAfter("PC_REMOTE_CHECK_ICE_CONNECTIONS");
    351  chain.append(commandsCheckDataChannel);
    352 }