tor-browser

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

receiver.test.js (29836B)


      1 'use strict';
      2 
      3 const assert = require('assert');
      4 const crypto = require('crypto');
      5 
      6 const PerMessageDeflate = require('../lib/permessage-deflate');
      7 const Receiver = require('../lib/receiver');
      8 const Sender = require('../lib/sender');
      9 const { EMPTY_BUFFER, kStatusCode } = require('../lib/constants');
     10 
     11 describe('Receiver', () => {
     12  it('parses an unmasked text message', (done) => {
     13    const receiver = new Receiver();
     14 
     15    receiver.on('message', (data, isBinary) => {
     16      assert.deepStrictEqual(data, Buffer.from('Hello'));
     17      assert.ok(!isBinary);
     18      done();
     19    });
     20 
     21    receiver.write(Buffer.from('810548656c6c6f', 'hex'));
     22  });
     23 
     24  it('parses a close message', (done) => {
     25    const receiver = new Receiver();
     26 
     27    receiver.on('conclude', (code, data) => {
     28      assert.strictEqual(code, 1005);
     29      assert.strictEqual(data, EMPTY_BUFFER);
     30      done();
     31    });
     32 
     33    receiver.write(Buffer.from('8800', 'hex'));
     34  });
     35 
     36  it('parses a close message spanning multiple writes', (done) => {
     37    const receiver = new Receiver();
     38 
     39    receiver.on('conclude', (code, data) => {
     40      assert.strictEqual(code, 1000);
     41      assert.deepStrictEqual(data, Buffer.from('DONE'));
     42      done();
     43    });
     44 
     45    receiver.write(Buffer.from('8806', 'hex'));
     46    receiver.write(Buffer.from('03e8444F4E45', 'hex'));
     47  });
     48 
     49  it('parses a masked text message', (done) => {
     50    const receiver = new Receiver({ isServer: true });
     51 
     52    receiver.on('message', (data, isBinary) => {
     53      assert.deepStrictEqual(data, Buffer.from('5:::{"name":"echo"}'));
     54      assert.ok(!isBinary);
     55      done();
     56    });
     57 
     58    receiver.write(
     59      Buffer.from('81933483a86801b992524fa1c60959e68a5216e6cb005ba1d5', 'hex')
     60    );
     61  });
     62 
     63  it('parses a masked text message longer than 125 B', (done) => {
     64    const receiver = new Receiver({ isServer: true });
     65    const msg = Buffer.from('A'.repeat(200));
     66 
     67    const list = Sender.frame(msg, {
     68      fin: true,
     69      rsv1: false,
     70      opcode: 0x01,
     71      mask: true,
     72      readOnly: true
     73    });
     74 
     75    const frame = Buffer.concat(list);
     76 
     77    receiver.on('message', (data, isBinary) => {
     78      assert.deepStrictEqual(data, msg);
     79      assert.ok(!isBinary);
     80      done();
     81    });
     82 
     83    receiver.write(frame.slice(0, 2));
     84    setImmediate(() => receiver.write(frame.slice(2)));
     85  });
     86 
     87  it('parses a really long masked text message', (done) => {
     88    const receiver = new Receiver({ isServer: true });
     89    const msg = Buffer.from('A'.repeat(64 * 1024));
     90 
     91    const list = Sender.frame(msg, {
     92      fin: true,
     93      rsv1: false,
     94      opcode: 0x01,
     95      mask: true,
     96      readOnly: true
     97    });
     98 
     99    const frame = Buffer.concat(list);
    100 
    101    receiver.on('message', (data, isBinary) => {
    102      assert.deepStrictEqual(data, msg);
    103      assert.ok(!isBinary);
    104      done();
    105    });
    106 
    107    receiver.write(frame);
    108  });
    109 
    110  it('parses a 300 B fragmented masked text message', (done) => {
    111    const receiver = new Receiver({ isServer: true });
    112    const msg = Buffer.from('A'.repeat(300));
    113 
    114    const fragment1 = msg.slice(0, 150);
    115    const fragment2 = msg.slice(150);
    116 
    117    const options = { rsv1: false, mask: true, readOnly: true };
    118 
    119    const frame1 = Buffer.concat(
    120      Sender.frame(fragment1, {
    121        fin: false,
    122        opcode: 0x01,
    123        ...options
    124      })
    125    );
    126    const frame2 = Buffer.concat(
    127      Sender.frame(fragment2, {
    128        fin: true,
    129        opcode: 0x00,
    130        ...options
    131      })
    132    );
    133 
    134    receiver.on('message', (data, isBinary) => {
    135      assert.deepStrictEqual(data, msg);
    136      assert.ok(!isBinary);
    137      done();
    138    });
    139 
    140    receiver.write(frame1);
    141    receiver.write(frame2);
    142  });
    143 
    144  it('parses a ping message', (done) => {
    145    const receiver = new Receiver({ isServer: true });
    146    const msg = Buffer.from('Hello');
    147 
    148    const list = Sender.frame(msg, {
    149      fin: true,
    150      rsv1: false,
    151      opcode: 0x09,
    152      mask: true,
    153      readOnly: true
    154    });
    155 
    156    const frame = Buffer.concat(list);
    157 
    158    receiver.on('ping', (data) => {
    159      assert.deepStrictEqual(data, msg);
    160      done();
    161    });
    162 
    163    receiver.write(frame);
    164  });
    165 
    166  it('parses a ping message with no data', (done) => {
    167    const receiver = new Receiver();
    168 
    169    receiver.on('ping', (data) => {
    170      assert.strictEqual(data, EMPTY_BUFFER);
    171      done();
    172    });
    173 
    174    receiver.write(Buffer.from('8900', 'hex'));
    175  });
    176 
    177  it('parses a 300 B fragmented masked text message with a ping in the middle (1/2)', (done) => {
    178    const receiver = new Receiver({ isServer: true });
    179    const msg = Buffer.from('A'.repeat(300));
    180    const pingMessage = Buffer.from('Hello');
    181 
    182    const fragment1 = msg.slice(0, 150);
    183    const fragment2 = msg.slice(150);
    184 
    185    const options = { rsv1: false, mask: true, readOnly: true };
    186 
    187    const frame1 = Buffer.concat(
    188      Sender.frame(fragment1, {
    189        fin: false,
    190        opcode: 0x01,
    191        ...options
    192      })
    193    );
    194    const frame2 = Buffer.concat(
    195      Sender.frame(pingMessage, {
    196        fin: true,
    197        opcode: 0x09,
    198        ...options
    199      })
    200    );
    201    const frame3 = Buffer.concat(
    202      Sender.frame(fragment2, {
    203        fin: true,
    204        opcode: 0x00,
    205        ...options
    206      })
    207    );
    208 
    209    let gotPing = false;
    210 
    211    receiver.on('message', (data, isBinary) => {
    212      assert.deepStrictEqual(data, msg);
    213      assert.ok(!isBinary);
    214      assert.ok(gotPing);
    215      done();
    216    });
    217    receiver.on('ping', (data) => {
    218      gotPing = true;
    219      assert.ok(data.equals(pingMessage));
    220    });
    221 
    222    receiver.write(frame1);
    223    receiver.write(frame2);
    224    receiver.write(frame3);
    225  });
    226 
    227  it('parses a 300 B fragmented masked text message with a ping in the middle (2/2)', (done) => {
    228    const receiver = new Receiver({ isServer: true });
    229    const msg = Buffer.from('A'.repeat(300));
    230    const pingMessage = Buffer.from('Hello');
    231 
    232    const fragment1 = msg.slice(0, 150);
    233    const fragment2 = msg.slice(150);
    234 
    235    const options = { rsv1: false, mask: true, readOnly: false };
    236 
    237    const frame1 = Buffer.concat(
    238      Sender.frame(Buffer.from(fragment1), {
    239        fin: false,
    240        opcode: 0x01,
    241        ...options
    242      })
    243    );
    244    const frame2 = Buffer.concat(
    245      Sender.frame(Buffer.from(pingMessage), {
    246        fin: true,
    247        opcode: 0x09,
    248        ...options
    249      })
    250    );
    251    const frame3 = Buffer.concat(
    252      Sender.frame(Buffer.from(fragment2), {
    253        fin: true,
    254        opcode: 0x00,
    255        ...options
    256      })
    257    );
    258 
    259    let chunks = [];
    260    const splitBuffer = (buf) => {
    261      const i = Math.floor(buf.length / 2);
    262      return [buf.slice(0, i), buf.slice(i)];
    263    };
    264 
    265    chunks = chunks.concat(splitBuffer(frame1));
    266    chunks = chunks.concat(splitBuffer(frame2));
    267    chunks = chunks.concat(splitBuffer(frame3));
    268 
    269    let gotPing = false;
    270 
    271    receiver.on('message', (data, isBinary) => {
    272      assert.deepStrictEqual(data, msg);
    273      assert.ok(!isBinary);
    274      assert.ok(gotPing);
    275      done();
    276    });
    277    receiver.on('ping', (data) => {
    278      gotPing = true;
    279      assert.ok(data.equals(pingMessage));
    280    });
    281 
    282    for (let i = 0; i < chunks.length; ++i) {
    283      receiver.write(chunks[i]);
    284    }
    285  });
    286 
    287  it('parses a 100 B masked binary message', (done) => {
    288    const receiver = new Receiver({ isServer: true });
    289    const msg = crypto.randomBytes(100);
    290 
    291    const list = Sender.frame(msg, {
    292      fin: true,
    293      rsv1: false,
    294      opcode: 0x02,
    295      mask: true,
    296      readOnly: true
    297    });
    298 
    299    const frame = Buffer.concat(list);
    300 
    301    receiver.on('message', (data, isBinary) => {
    302      assert.deepStrictEqual(data, msg);
    303      assert.ok(isBinary);
    304      done();
    305    });
    306 
    307    receiver.write(frame);
    308  });
    309 
    310  it('parses a 256 B masked binary message', (done) => {
    311    const receiver = new Receiver({ isServer: true });
    312    const msg = crypto.randomBytes(256);
    313 
    314    const list = Sender.frame(msg, {
    315      fin: true,
    316      rsv1: false,
    317      opcode: 0x02,
    318      mask: true,
    319      readOnly: true
    320    });
    321 
    322    const frame = Buffer.concat(list);
    323 
    324    receiver.on('message', (data, isBinary) => {
    325      assert.deepStrictEqual(data, msg);
    326      assert.ok(isBinary);
    327      done();
    328    });
    329 
    330    receiver.write(frame);
    331  });
    332 
    333  it('parses a 200 KiB masked binary message', (done) => {
    334    const receiver = new Receiver({ isServer: true });
    335    const msg = crypto.randomBytes(200 * 1024);
    336 
    337    const list = Sender.frame(msg, {
    338      fin: true,
    339      rsv1: false,
    340      opcode: 0x02,
    341      mask: true,
    342      readOnly: true
    343    });
    344 
    345    const frame = Buffer.concat(list);
    346 
    347    receiver.on('message', (data, isBinary) => {
    348      assert.deepStrictEqual(data, msg);
    349      assert.ok(isBinary);
    350      done();
    351    });
    352 
    353    receiver.write(frame);
    354  });
    355 
    356  it('parses a 200 KiB unmasked binary message', (done) => {
    357    const receiver = new Receiver();
    358    const msg = crypto.randomBytes(200 * 1024);
    359 
    360    const list = Sender.frame(msg, {
    361      fin: true,
    362      rsv1: false,
    363      opcode: 0x02,
    364      mask: false,
    365      readOnly: true
    366    });
    367 
    368    const frame = Buffer.concat(list);
    369 
    370    receiver.on('message', (data, isBinary) => {
    371      assert.deepStrictEqual(data, msg);
    372      assert.ok(isBinary);
    373      done();
    374    });
    375 
    376    receiver.write(frame);
    377  });
    378 
    379  it('parses a compressed message', (done) => {
    380    const perMessageDeflate = new PerMessageDeflate();
    381    perMessageDeflate.accept([{}]);
    382 
    383    const receiver = new Receiver({
    384      extensions: {
    385        'permessage-deflate': perMessageDeflate
    386      }
    387    });
    388    const buf = Buffer.from('Hello');
    389 
    390    receiver.on('message', (data, isBinary) => {
    391      assert.deepStrictEqual(data, buf);
    392      assert.ok(!isBinary);
    393      done();
    394    });
    395 
    396    perMessageDeflate.compress(buf, true, (err, data) => {
    397      if (err) return done(err);
    398 
    399      receiver.write(Buffer.from([0xc1, data.length]));
    400      receiver.write(data);
    401    });
    402  });
    403 
    404  it('parses a compressed and fragmented message', (done) => {
    405    const perMessageDeflate = new PerMessageDeflate();
    406    perMessageDeflate.accept([{}]);
    407 
    408    const receiver = new Receiver({
    409      extensions: {
    410        'permessage-deflate': perMessageDeflate
    411      }
    412    });
    413    const buf1 = Buffer.from('foo');
    414    const buf2 = Buffer.from('bar');
    415 
    416    receiver.on('message', (data, isBinary) => {
    417      assert.deepStrictEqual(data, Buffer.concat([buf1, buf2]));
    418      assert.ok(!isBinary);
    419      done();
    420    });
    421 
    422    perMessageDeflate.compress(buf1, false, (err, fragment1) => {
    423      if (err) return done(err);
    424 
    425      receiver.write(Buffer.from([0x41, fragment1.length]));
    426      receiver.write(fragment1);
    427 
    428      perMessageDeflate.compress(buf2, true, (err, fragment2) => {
    429        if (err) return done(err);
    430 
    431        receiver.write(Buffer.from([0x80, fragment2.length]));
    432        receiver.write(fragment2);
    433      });
    434    });
    435  });
    436 
    437  it('parses a buffer with thousands of frames', (done) => {
    438    const buf = Buffer.allocUnsafe(40000);
    439 
    440    for (let i = 0; i < buf.length; i += 2) {
    441      buf[i] = 0x81;
    442      buf[i + 1] = 0x00;
    443    }
    444 
    445    const receiver = new Receiver();
    446    let counter = 0;
    447 
    448    receiver.on('message', (data, isBinary) => {
    449      assert.strictEqual(data, EMPTY_BUFFER);
    450      assert.ok(!isBinary);
    451      if (++counter === 20000) done();
    452    });
    453 
    454    receiver.write(buf);
    455  });
    456 
    457  it('resets `totalPayloadLength` only on final frame (unfragmented)', (done) => {
    458    const receiver = new Receiver({ maxPayload: 10 });
    459 
    460    receiver.on('message', (data, isBinary) => {
    461      assert.strictEqual(receiver._totalPayloadLength, 0);
    462      assert.deepStrictEqual(data, Buffer.from('Hello'));
    463      assert.ok(!isBinary);
    464      done();
    465    });
    466 
    467    assert.strictEqual(receiver._totalPayloadLength, 0);
    468    receiver.write(Buffer.from('810548656c6c6f', 'hex'));
    469  });
    470 
    471  it('resets `totalPayloadLength` only on final frame (fragmented)', (done) => {
    472    const receiver = new Receiver({ maxPayload: 10 });
    473 
    474    receiver.on('message', (data, isBinary) => {
    475      assert.strictEqual(receiver._totalPayloadLength, 0);
    476      assert.deepStrictEqual(data, Buffer.from('Hello'));
    477      assert.ok(!isBinary);
    478      done();
    479    });
    480 
    481    assert.strictEqual(receiver._totalPayloadLength, 0);
    482    receiver.write(Buffer.from('01024865', 'hex'));
    483    assert.strictEqual(receiver._totalPayloadLength, 2);
    484    receiver.write(Buffer.from('80036c6c6f', 'hex'));
    485  });
    486 
    487  it('resets `totalPayloadLength` only on final frame (fragmented + ping)', (done) => {
    488    const receiver = new Receiver({ maxPayload: 10 });
    489    let data;
    490 
    491    receiver.on('ping', (buf) => {
    492      assert.strictEqual(receiver._totalPayloadLength, 2);
    493      data = buf;
    494    });
    495    receiver.on('message', (buf, isBinary) => {
    496      assert.strictEqual(receiver._totalPayloadLength, 0);
    497      assert.deepStrictEqual(data, EMPTY_BUFFER);
    498      assert.deepStrictEqual(buf, Buffer.from('Hello'));
    499      assert.ok(isBinary);
    500      done();
    501    });
    502 
    503    assert.strictEqual(receiver._totalPayloadLength, 0);
    504    receiver.write(Buffer.from('02024865', 'hex'));
    505    receiver.write(Buffer.from('8900', 'hex'));
    506    receiver.write(Buffer.from('80036c6c6f', 'hex'));
    507  });
    508 
    509  it('ignores any data after a close frame', (done) => {
    510    const perMessageDeflate = new PerMessageDeflate();
    511    perMessageDeflate.accept([{}]);
    512 
    513    const receiver = new Receiver({
    514      extensions: {
    515        'permessage-deflate': perMessageDeflate
    516      }
    517    });
    518    const results = [];
    519    const push = results.push.bind(results);
    520 
    521    receiver.on('conclude', push).on('message', push);
    522    receiver.on('finish', () => {
    523      assert.deepStrictEqual(results, [
    524        EMPTY_BUFFER,
    525        false,
    526        1005,
    527        EMPTY_BUFFER
    528      ]);
    529      done();
    530    });
    531 
    532    receiver.write(Buffer.from([0xc1, 0x01, 0x00]));
    533    receiver.write(Buffer.from([0x88, 0x00]));
    534    receiver.write(Buffer.from([0x81, 0x00]));
    535  });
    536 
    537  it('emits an error if RSV1 is on and permessage-deflate is disabled', (done) => {
    538    const receiver = new Receiver();
    539 
    540    receiver.on('error', (err) => {
    541      assert.ok(err instanceof RangeError);
    542      assert.strictEqual(err.code, 'WS_ERR_UNEXPECTED_RSV_1');
    543      assert.strictEqual(
    544        err.message,
    545        'Invalid WebSocket frame: RSV1 must be clear'
    546      );
    547      assert.strictEqual(err[kStatusCode], 1002);
    548      done();
    549    });
    550 
    551    receiver.write(Buffer.from([0xc2, 0x80, 0x00, 0x00, 0x00, 0x00]));
    552  });
    553 
    554  it('emits an error if RSV1 is on and opcode is 0', (done) => {
    555    const perMessageDeflate = new PerMessageDeflate();
    556    perMessageDeflate.accept([{}]);
    557 
    558    const receiver = new Receiver({
    559      extensions: {
    560        'permessage-deflate': perMessageDeflate
    561      }
    562    });
    563 
    564    receiver.on('error', (err) => {
    565      assert.ok(err instanceof RangeError);
    566      assert.strictEqual(err.code, 'WS_ERR_UNEXPECTED_RSV_1');
    567      assert.strictEqual(
    568        err.message,
    569        'Invalid WebSocket frame: RSV1 must be clear'
    570      );
    571      assert.strictEqual(err[kStatusCode], 1002);
    572      done();
    573    });
    574 
    575    receiver.write(Buffer.from([0x40, 0x00]));
    576  });
    577 
    578  it('emits an error if RSV2 is on', (done) => {
    579    const receiver = new Receiver();
    580 
    581    receiver.on('error', (err) => {
    582      assert.ok(err instanceof RangeError);
    583      assert.strictEqual(err.code, 'WS_ERR_UNEXPECTED_RSV_2_3');
    584      assert.strictEqual(
    585        err.message,
    586        'Invalid WebSocket frame: RSV2 and RSV3 must be clear'
    587      );
    588      assert.strictEqual(err[kStatusCode], 1002);
    589      done();
    590    });
    591 
    592    receiver.write(Buffer.from([0xa2, 0x00]));
    593  });
    594 
    595  it('emits an error if RSV3 is on', (done) => {
    596    const receiver = new Receiver();
    597 
    598    receiver.on('error', (err) => {
    599      assert.ok(err instanceof RangeError);
    600      assert.strictEqual(err.code, 'WS_ERR_UNEXPECTED_RSV_2_3');
    601      assert.strictEqual(
    602        err.message,
    603        'Invalid WebSocket frame: RSV2 and RSV3 must be clear'
    604      );
    605      assert.strictEqual(err[kStatusCode], 1002);
    606      done();
    607    });
    608 
    609    receiver.write(Buffer.from([0x92, 0x00]));
    610  });
    611 
    612  it('emits an error if the first frame in a fragmented message has opcode 0', (done) => {
    613    const receiver = new Receiver();
    614 
    615    receiver.on('error', (err) => {
    616      assert.ok(err instanceof RangeError);
    617      assert.strictEqual(err.code, 'WS_ERR_INVALID_OPCODE');
    618      assert.strictEqual(
    619        err.message,
    620        'Invalid WebSocket frame: invalid opcode 0'
    621      );
    622      assert.strictEqual(err[kStatusCode], 1002);
    623      done();
    624    });
    625 
    626    receiver.write(Buffer.from([0x00, 0x00]));
    627  });
    628 
    629  it('emits an error if a frame has opcode 1 in the middle of a fragmented message', (done) => {
    630    const receiver = new Receiver();
    631 
    632    receiver.on('error', (err) => {
    633      assert.ok(err instanceof RangeError);
    634      assert.strictEqual(err.code, 'WS_ERR_INVALID_OPCODE');
    635      assert.strictEqual(
    636        err.message,
    637        'Invalid WebSocket frame: invalid opcode 1'
    638      );
    639      assert.strictEqual(err[kStatusCode], 1002);
    640      done();
    641    });
    642 
    643    receiver.write(Buffer.from([0x01, 0x00]));
    644    receiver.write(Buffer.from([0x01, 0x00]));
    645  });
    646 
    647  it('emits an error if a frame has opcode 2 in the middle of a fragmented message', (done) => {
    648    const receiver = new Receiver();
    649 
    650    receiver.on('error', (err) => {
    651      assert.ok(err instanceof RangeError);
    652      assert.strictEqual(err.code, 'WS_ERR_INVALID_OPCODE');
    653      assert.strictEqual(
    654        err.message,
    655        'Invalid WebSocket frame: invalid opcode 2'
    656      );
    657      assert.strictEqual(err[kStatusCode], 1002);
    658      done();
    659    });
    660 
    661    receiver.write(Buffer.from([0x01, 0x00]));
    662    receiver.write(Buffer.from([0x02, 0x00]));
    663  });
    664 
    665  it('emits an error if a control frame has the FIN bit off', (done) => {
    666    const receiver = new Receiver();
    667 
    668    receiver.on('error', (err) => {
    669      assert.ok(err instanceof RangeError);
    670      assert.strictEqual(err.code, 'WS_ERR_EXPECTED_FIN');
    671      assert.strictEqual(
    672        err.message,
    673        'Invalid WebSocket frame: FIN must be set'
    674      );
    675      assert.strictEqual(err[kStatusCode], 1002);
    676      done();
    677    });
    678 
    679    receiver.write(Buffer.from([0x09, 0x00]));
    680  });
    681 
    682  it('emits an error if a control frame has the RSV1 bit on', (done) => {
    683    const perMessageDeflate = new PerMessageDeflate();
    684    perMessageDeflate.accept([{}]);
    685 
    686    const receiver = new Receiver({
    687      extensions: {
    688        'permessage-deflate': perMessageDeflate
    689      }
    690    });
    691 
    692    receiver.on('error', (err) => {
    693      assert.ok(err instanceof RangeError);
    694      assert.strictEqual(err.code, 'WS_ERR_UNEXPECTED_RSV_1');
    695      assert.strictEqual(
    696        err.message,
    697        'Invalid WebSocket frame: RSV1 must be clear'
    698      );
    699      assert.strictEqual(err[kStatusCode], 1002);
    700      done();
    701    });
    702 
    703    receiver.write(Buffer.from([0xc9, 0x00]));
    704  });
    705 
    706  it('emits an error if a control frame has the FIN bit off', (done) => {
    707    const receiver = new Receiver();
    708 
    709    receiver.on('error', (err) => {
    710      assert.ok(err instanceof RangeError);
    711      assert.strictEqual(err.code, 'WS_ERR_EXPECTED_FIN');
    712      assert.strictEqual(
    713        err.message,
    714        'Invalid WebSocket frame: FIN must be set'
    715      );
    716      assert.strictEqual(err[kStatusCode], 1002);
    717      done();
    718    });
    719 
    720    receiver.write(Buffer.from([0x09, 0x00]));
    721  });
    722 
    723  it('emits an error if a frame has the MASK bit off (server mode)', (done) => {
    724    const receiver = new Receiver({ isServer: true });
    725 
    726    receiver.on('error', (err) => {
    727      assert.ok(err instanceof RangeError);
    728      assert.strictEqual(err.code, 'WS_ERR_EXPECTED_MASK');
    729      assert.strictEqual(
    730        err.message,
    731        'Invalid WebSocket frame: MASK must be set'
    732      );
    733      assert.strictEqual(err[kStatusCode], 1002);
    734      done();
    735    });
    736 
    737    receiver.write(Buffer.from([0x81, 0x02, 0x68, 0x69]));
    738  });
    739 
    740  it('emits an error if a frame has the MASK bit on (client mode)', (done) => {
    741    const receiver = new Receiver();
    742 
    743    receiver.on('error', (err) => {
    744      assert.ok(err instanceof RangeError);
    745      assert.strictEqual(err.code, 'WS_ERR_UNEXPECTED_MASK');
    746      assert.strictEqual(
    747        err.message,
    748        'Invalid WebSocket frame: MASK must be clear'
    749      );
    750      assert.strictEqual(err[kStatusCode], 1002);
    751      done();
    752    });
    753 
    754    receiver.write(
    755      Buffer.from([0x81, 0x82, 0x56, 0x3a, 0xac, 0x80, 0x3e, 0x53])
    756    );
    757  });
    758 
    759  it('emits an error if a control frame has a payload bigger than 125 B', (done) => {
    760    const receiver = new Receiver();
    761 
    762    receiver.on('error', (err) => {
    763      assert.ok(err instanceof RangeError);
    764      assert.strictEqual(err.code, 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH');
    765      assert.strictEqual(
    766        err.message,
    767        'Invalid WebSocket frame: invalid payload length 126'
    768      );
    769      assert.strictEqual(err[kStatusCode], 1002);
    770      done();
    771    });
    772 
    773    receiver.write(Buffer.from([0x89, 0x7e]));
    774  });
    775 
    776  it('emits an error if a data frame has a payload bigger than 2^53 - 1 B', (done) => {
    777    const receiver = new Receiver();
    778 
    779    receiver.on('error', (err) => {
    780      assert.ok(err instanceof RangeError);
    781      assert.strictEqual(err.code, 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH');
    782      assert.strictEqual(
    783        err.message,
    784        'Unsupported WebSocket frame: payload length > 2^53 - 1'
    785      );
    786      assert.strictEqual(err[kStatusCode], 1009);
    787      done();
    788    });
    789 
    790    receiver.write(Buffer.from([0x82, 0x7f]));
    791    setImmediate(() =>
    792      receiver.write(
    793        Buffer.from([0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    794      )
    795    );
    796  });
    797 
    798  it('emits an error if a text frame contains invalid UTF-8 data (1/2)', (done) => {
    799    const receiver = new Receiver();
    800 
    801    receiver.on('error', (err) => {
    802      assert.ok(err instanceof Error);
    803      assert.strictEqual(err.code, 'WS_ERR_INVALID_UTF8');
    804      assert.strictEqual(
    805        err.message,
    806        'Invalid WebSocket frame: invalid UTF-8 sequence'
    807      );
    808      assert.strictEqual(err[kStatusCode], 1007);
    809      done();
    810    });
    811 
    812    receiver.write(Buffer.from([0x81, 0x04, 0xce, 0xba, 0xe1, 0xbd]));
    813  });
    814 
    815  it('emits an error if a text frame contains invalid UTF-8 data (2/2)', (done) => {
    816    const perMessageDeflate = new PerMessageDeflate();
    817    perMessageDeflate.accept([{}]);
    818 
    819    const receiver = new Receiver({
    820      extensions: {
    821        'permessage-deflate': perMessageDeflate
    822      }
    823    });
    824    const buf = Buffer.from([0xce, 0xba, 0xe1, 0xbd]);
    825 
    826    receiver.on('error', (err) => {
    827      assert.ok(err instanceof Error);
    828      assert.strictEqual(err.code, 'WS_ERR_INVALID_UTF8');
    829      assert.strictEqual(
    830        err.message,
    831        'Invalid WebSocket frame: invalid UTF-8 sequence'
    832      );
    833      assert.strictEqual(err[kStatusCode], 1007);
    834      done();
    835    });
    836 
    837    perMessageDeflate.compress(buf, true, (err, data) => {
    838      if (err) return done(err);
    839 
    840      receiver.write(Buffer.from([0xc1, data.length]));
    841      receiver.write(data);
    842    });
    843  });
    844 
    845  it('emits an error if a close frame has a payload of 1 B', (done) => {
    846    const receiver = new Receiver();
    847 
    848    receiver.on('error', (err) => {
    849      assert.ok(err instanceof RangeError);
    850      assert.strictEqual(err.code, 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH');
    851      assert.strictEqual(
    852        err.message,
    853        'Invalid WebSocket frame: invalid payload length 1'
    854      );
    855      assert.strictEqual(err[kStatusCode], 1002);
    856      done();
    857    });
    858 
    859    receiver.write(Buffer.from([0x88, 0x01, 0x00]));
    860  });
    861 
    862  it('emits an error if a close frame contains an invalid close code', (done) => {
    863    const receiver = new Receiver();
    864 
    865    receiver.on('error', (err) => {
    866      assert.ok(err instanceof RangeError);
    867      assert.strictEqual(err.code, 'WS_ERR_INVALID_CLOSE_CODE');
    868      assert.strictEqual(
    869        err.message,
    870        'Invalid WebSocket frame: invalid status code 0'
    871      );
    872      assert.strictEqual(err[kStatusCode], 1002);
    873      done();
    874    });
    875 
    876    receiver.write(Buffer.from([0x88, 0x02, 0x00, 0x00]));
    877  });
    878 
    879  it('emits an error if a close frame contains invalid UTF-8 data', (done) => {
    880    const receiver = new Receiver();
    881 
    882    receiver.on('error', (err) => {
    883      assert.ok(err instanceof Error);
    884      assert.strictEqual(err.code, 'WS_ERR_INVALID_UTF8');
    885      assert.strictEqual(
    886        err.message,
    887        'Invalid WebSocket frame: invalid UTF-8 sequence'
    888      );
    889      assert.strictEqual(err[kStatusCode], 1007);
    890      done();
    891    });
    892 
    893    receiver.write(
    894      Buffer.from([0x88, 0x06, 0x03, 0xef, 0xce, 0xba, 0xe1, 0xbd])
    895    );
    896  });
    897 
    898  it('emits an error if a frame payload length is bigger than `maxPayload`', (done) => {
    899    const receiver = new Receiver({ isServer: true, maxPayload: 20 * 1024 });
    900    const msg = crypto.randomBytes(200 * 1024);
    901 
    902    const list = Sender.frame(msg, {
    903      fin: true,
    904      rsv1: false,
    905      opcode: 0x02,
    906      mask: true,
    907      readOnly: true
    908    });
    909 
    910    const frame = Buffer.concat(list);
    911 
    912    receiver.on('error', (err) => {
    913      assert.ok(err instanceof RangeError);
    914      assert.strictEqual(err.code, 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH');
    915      assert.strictEqual(err.message, 'Max payload size exceeded');
    916      assert.strictEqual(err[kStatusCode], 1009);
    917      done();
    918    });
    919 
    920    receiver.write(frame);
    921  });
    922 
    923  it('emits an error if the message length exceeds `maxPayload`', (done) => {
    924    const perMessageDeflate = new PerMessageDeflate({}, false, 25);
    925    perMessageDeflate.accept([{}]);
    926 
    927    const receiver = new Receiver({
    928      extensions: { 'permessage-deflate': perMessageDeflate },
    929      isServer: false,
    930      maxPayload: 25
    931    });
    932    const buf = Buffer.from('A'.repeat(50));
    933 
    934    receiver.on('error', (err) => {
    935      assert.ok(err instanceof RangeError);
    936      assert.strictEqual(err.code, 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH');
    937      assert.strictEqual(err.message, 'Max payload size exceeded');
    938      assert.strictEqual(err[kStatusCode], 1009);
    939      done();
    940    });
    941 
    942    perMessageDeflate.compress(buf, true, (err, data) => {
    943      if (err) return done(err);
    944 
    945      receiver.write(Buffer.from([0xc1, data.length]));
    946      receiver.write(data);
    947    });
    948  });
    949 
    950  it('emits an error if the sum of fragment lengths exceeds `maxPayload`', (done) => {
    951    const perMessageDeflate = new PerMessageDeflate({}, false, 25);
    952    perMessageDeflate.accept([{}]);
    953 
    954    const receiver = new Receiver({
    955      extensions: { 'permessage-deflate': perMessageDeflate },
    956      isServer: false,
    957      maxPayload: 25
    958    });
    959    const buf = Buffer.from('A'.repeat(15));
    960 
    961    receiver.on('error', (err) => {
    962      assert.ok(err instanceof RangeError);
    963      assert.strictEqual(err.code, 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH');
    964      assert.strictEqual(err.message, 'Max payload size exceeded');
    965      assert.strictEqual(err[kStatusCode], 1009);
    966      done();
    967    });
    968 
    969    perMessageDeflate.compress(buf, false, (err, fragment1) => {
    970      if (err) return done(err);
    971 
    972      receiver.write(Buffer.from([0x41, fragment1.length]));
    973      receiver.write(fragment1);
    974 
    975      perMessageDeflate.compress(buf, true, (err, fragment2) => {
    976        if (err) return done(err);
    977 
    978        receiver.write(Buffer.from([0x80, fragment2.length]));
    979        receiver.write(fragment2);
    980      });
    981    });
    982  });
    983 
    984  it("honors the 'nodebuffer' binary type", (done) => {
    985    const receiver = new Receiver();
    986    const frags = [
    987      crypto.randomBytes(7321),
    988      crypto.randomBytes(137),
    989      crypto.randomBytes(285787),
    990      crypto.randomBytes(3)
    991    ];
    992 
    993    receiver.on('message', (data, isBinary) => {
    994      assert.deepStrictEqual(data, Buffer.concat(frags));
    995      assert.ok(isBinary);
    996      done();
    997    });
    998 
    999    frags.forEach((frag, i) => {
   1000      Sender.frame(frag, {
   1001        fin: i === frags.length - 1,
   1002        opcode: i === 0 ? 2 : 0,
   1003        readOnly: true,
   1004        mask: false,
   1005        rsv1: false
   1006      }).forEach((buf) => receiver.write(buf));
   1007    });
   1008  });
   1009 
   1010  it("honors the 'arraybuffer' binary type", (done) => {
   1011    const receiver = new Receiver({ binaryType: 'arraybuffer' });
   1012    const frags = [
   1013      crypto.randomBytes(19221),
   1014      crypto.randomBytes(954),
   1015      crypto.randomBytes(623987)
   1016    ];
   1017 
   1018    receiver.on('message', (data, isBinary) => {
   1019      assert.ok(data instanceof ArrayBuffer);
   1020      assert.deepStrictEqual(Buffer.from(data), Buffer.concat(frags));
   1021      assert.ok(isBinary);
   1022      done();
   1023    });
   1024 
   1025    frags.forEach((frag, i) => {
   1026      Sender.frame(frag, {
   1027        fin: i === frags.length - 1,
   1028        opcode: i === 0 ? 2 : 0,
   1029        readOnly: true,
   1030        mask: false,
   1031        rsv1: false
   1032      }).forEach((buf) => receiver.write(buf));
   1033    });
   1034  });
   1035 
   1036  it("honors the 'fragments' binary type", (done) => {
   1037    const receiver = new Receiver({ binaryType: 'fragments' });
   1038    const frags = [
   1039      crypto.randomBytes(17),
   1040      crypto.randomBytes(419872),
   1041      crypto.randomBytes(83),
   1042      crypto.randomBytes(9928),
   1043      crypto.randomBytes(1)
   1044    ];
   1045 
   1046    receiver.on('message', (data, isBinary) => {
   1047      assert.deepStrictEqual(data, frags);
   1048      assert.ok(isBinary);
   1049      done();
   1050    });
   1051 
   1052    frags.forEach((frag, i) => {
   1053      Sender.frame(frag, {
   1054        fin: i === frags.length - 1,
   1055        opcode: i === 0 ? 2 : 0,
   1056        readOnly: true,
   1057        mask: false,
   1058        rsv1: false
   1059      }).forEach((buf) => receiver.write(buf));
   1060    });
   1061  });
   1062 
   1063  it('honors the `skipUTF8Validation` option (1/2)', (done) => {
   1064    const receiver = new Receiver({ skipUTF8Validation: true });
   1065 
   1066    receiver.on('message', (data, isBinary) => {
   1067      assert.deepStrictEqual(data, Buffer.from([0xf8]));
   1068      assert.ok(!isBinary);
   1069      done();
   1070    });
   1071 
   1072    receiver.write(Buffer.from([0x81, 0x01, 0xf8]));
   1073  });
   1074 
   1075  it('honors the `skipUTF8Validation` option (2/2)', (done) => {
   1076    const receiver = new Receiver({ skipUTF8Validation: true });
   1077 
   1078    receiver.on('conclude', (code, data) => {
   1079      assert.strictEqual(code, 1000);
   1080      assert.deepStrictEqual(data, Buffer.from([0xf8]));
   1081      done();
   1082    });
   1083 
   1084    receiver.write(Buffer.from([0x88, 0x03, 0x03, 0xe8, 0xf8]));
   1085  });
   1086 });