@babylonjs/inspector 9.5.0 → 9.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/inspector-bridge.mjs +1604 -973
- package/bin/inspector-cli.mjs +1395 -1372
- package/lib/components/properties/materials/openpbrMaterialProperties.d.ts +8 -0
- package/lib/{extensionsListService-BKejb6t7.js → extensionsListService-C33SU1_a.js} +2 -2
- package/lib/{extensionsListService-BKejb6t7.js.map → extensionsListService-C33SU1_a.js.map} +1 -1
- package/lib/{index-BMRc-fS9.js → index-D0JXVQQf.js} +108 -80
- package/lib/{index-BMRc-fS9.js.map → index-D0JXVQQf.js.map} +1 -1
- package/lib/index.js +1 -1
- package/lib/{quickCreateToolsService-ACqRLMi-.js → quickCreateToolsService-pBNUavZe.js} +2 -2
- package/lib/{quickCreateToolsService-ACqRLMi-.js.map → quickCreateToolsService-pBNUavZe.js.map} +1 -1
- package/lib/{reflectorService-rMnq6uTv.js → reflectorService-CAi2NPRy.js} +2 -2
- package/lib/{reflectorService-rMnq6uTv.js.map → reflectorService-CAi2NPRy.js.map} +1 -1
- package/package.json +1 -1
package/bin/inspector-cli.mjs
CHANGED
|
@@ -5,15 +5,16 @@ import require$$1, { join, dirname, resolve } from 'path';
|
|
|
5
5
|
import require$$0, { readFileSync, existsSync } from 'fs';
|
|
6
6
|
import require$$7, { fileURLToPath } from 'url';
|
|
7
7
|
import { parseArgs } from 'util';
|
|
8
|
-
import require$$0$
|
|
9
|
-
import require$$1$
|
|
8
|
+
import require$$0$4 from 'events';
|
|
9
|
+
import require$$1$2 from 'https';
|
|
10
10
|
import require$$2$1 from 'http';
|
|
11
11
|
import require$$3 from 'net';
|
|
12
12
|
import require$$4 from 'tls';
|
|
13
|
-
import require$$
|
|
14
|
-
import require$$0$
|
|
13
|
+
import require$$1$1 from 'crypto';
|
|
14
|
+
import require$$0$3 from 'stream';
|
|
15
15
|
import require$$0$1 from 'zlib';
|
|
16
16
|
import require$$2 from 'os';
|
|
17
|
+
import require$$0$2 from 'buffer';
|
|
17
18
|
|
|
18
19
|
function getDefaultExportFromCjs (x) {
|
|
19
20
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -21,12 +22,21 @@ function getDefaultExportFromCjs (x) {
|
|
|
21
22
|
|
|
22
23
|
var bufferUtil$1 = {exports: {}};
|
|
23
24
|
|
|
25
|
+
const BINARY_TYPES$2 = ['nodebuffer', 'arraybuffer', 'fragments'];
|
|
26
|
+
const hasBlob$1 = typeof Blob !== 'undefined';
|
|
27
|
+
|
|
28
|
+
if (hasBlob$1) BINARY_TYPES$2.push('blob');
|
|
29
|
+
|
|
24
30
|
var constants = {
|
|
25
|
-
BINARY_TYPES:
|
|
31
|
+
BINARY_TYPES: BINARY_TYPES$2,
|
|
32
|
+
CLOSE_TIMEOUT: 30000,
|
|
33
|
+
EMPTY_BUFFER: Buffer.alloc(0),
|
|
26
34
|
GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
|
|
35
|
+
hasBlob: hasBlob$1,
|
|
36
|
+
kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),
|
|
37
|
+
kListener: Symbol('kListener'),
|
|
27
38
|
kStatusCode: Symbol('status-code'),
|
|
28
39
|
kWebSocket: Symbol('websocket'),
|
|
29
|
-
EMPTY_BUFFER: Buffer.alloc(0),
|
|
30
40
|
NOOP: () => {}
|
|
31
41
|
};
|
|
32
42
|
|
|
@@ -324,8 +334,13 @@ function requireBufferutil () {
|
|
|
324
334
|
return bufferutil.exports;
|
|
325
335
|
}
|
|
326
336
|
|
|
337
|
+
var unmask$1;
|
|
338
|
+
var mask;
|
|
339
|
+
|
|
327
340
|
const { EMPTY_BUFFER: EMPTY_BUFFER$3 } = constants;
|
|
328
341
|
|
|
342
|
+
const FastBuffer$2 = Buffer[Symbol.species];
|
|
343
|
+
|
|
329
344
|
/**
|
|
330
345
|
* Merges an array of buffers into a new buffer.
|
|
331
346
|
*
|
|
@@ -347,7 +362,9 @@ function concat$1(list, totalLength) {
|
|
|
347
362
|
offset += buf.length;
|
|
348
363
|
}
|
|
349
364
|
|
|
350
|
-
if (offset < totalLength)
|
|
365
|
+
if (offset < totalLength) {
|
|
366
|
+
return new FastBuffer$2(target.buffer, target.byteOffset, offset);
|
|
367
|
+
}
|
|
351
368
|
|
|
352
369
|
return target;
|
|
353
370
|
}
|
|
@@ -376,9 +393,7 @@ function _mask(source, mask, output, offset, length) {
|
|
|
376
393
|
* @public
|
|
377
394
|
*/
|
|
378
395
|
function _unmask(buffer, mask) {
|
|
379
|
-
|
|
380
|
-
const length = buffer.length;
|
|
381
|
-
for (let i = 0; i < length; i++) {
|
|
396
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
382
397
|
buffer[i] ^= mask[i & 3];
|
|
383
398
|
}
|
|
384
399
|
}
|
|
@@ -391,11 +406,11 @@ function _unmask(buffer, mask) {
|
|
|
391
406
|
* @public
|
|
392
407
|
*/
|
|
393
408
|
function toArrayBuffer$1(buf) {
|
|
394
|
-
if (buf.
|
|
409
|
+
if (buf.length === buf.buffer.byteLength) {
|
|
395
410
|
return buf.buffer;
|
|
396
411
|
}
|
|
397
412
|
|
|
398
|
-
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.
|
|
413
|
+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);
|
|
399
414
|
}
|
|
400
415
|
|
|
401
416
|
/**
|
|
@@ -414,9 +429,9 @@ function toBuffer$2(data) {
|
|
|
414
429
|
let buf;
|
|
415
430
|
|
|
416
431
|
if (data instanceof ArrayBuffer) {
|
|
417
|
-
buf =
|
|
432
|
+
buf = new FastBuffer$2(data);
|
|
418
433
|
} else if (ArrayBuffer.isView(data)) {
|
|
419
|
-
buf =
|
|
434
|
+
buf = new FastBuffer$2(data.buffer, data.byteOffset, data.byteLength);
|
|
420
435
|
} else {
|
|
421
436
|
buf = Buffer.from(data);
|
|
422
437
|
toBuffer$2.readOnly = false;
|
|
@@ -425,31 +440,31 @@ function toBuffer$2(data) {
|
|
|
425
440
|
return buf;
|
|
426
441
|
}
|
|
427
442
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
443
|
+
bufferUtil$1.exports = {
|
|
444
|
+
concat: concat$1,
|
|
445
|
+
mask: _mask,
|
|
446
|
+
toArrayBuffer: toArrayBuffer$1,
|
|
447
|
+
toBuffer: toBuffer$2,
|
|
448
|
+
unmask: _unmask
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
/* istanbul ignore else */
|
|
452
|
+
if (!process.env.WS_NO_BUFFER_UTIL) {
|
|
453
|
+
try {
|
|
454
|
+
const bufferUtil = requireBufferutil();
|
|
431
455
|
|
|
432
|
-
|
|
433
|
-
concat: concat$1,
|
|
434
|
-
mask(source, mask, output, offset, length) {
|
|
456
|
+
mask = bufferUtil$1.exports.mask = function (source, mask, output, offset, length) {
|
|
435
457
|
if (length < 48) _mask(source, mask, output, offset, length);
|
|
436
|
-
else
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
unmask(buffer, mask) {
|
|
458
|
+
else bufferUtil.mask(source, mask, output, offset, length);
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
unmask$1 = bufferUtil$1.exports.unmask = function (buffer, mask) {
|
|
441
462
|
if (buffer.length < 32) _unmask(buffer, mask);
|
|
442
|
-
else
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
concat: concat$1,
|
|
448
|
-
mask: _mask,
|
|
449
|
-
toArrayBuffer: toArrayBuffer$1,
|
|
450
|
-
toBuffer: toBuffer$2,
|
|
451
|
-
unmask: _unmask
|
|
452
|
-
};
|
|
463
|
+
else bufferUtil.unmask(buffer, mask);
|
|
464
|
+
};
|
|
465
|
+
} catch (e) {
|
|
466
|
+
// Continue regardless of the error.
|
|
467
|
+
}
|
|
453
468
|
}
|
|
454
469
|
|
|
455
470
|
var bufferUtilExports = bufferUtil$1.exports;
|
|
@@ -512,14 +527,15 @@ const zlib = require$$0$1;
|
|
|
512
527
|
|
|
513
528
|
const bufferUtil = bufferUtilExports;
|
|
514
529
|
const Limiter = limiter;
|
|
515
|
-
const { kStatusCode: kStatusCode$2
|
|
530
|
+
const { kStatusCode: kStatusCode$2 } = constants;
|
|
516
531
|
|
|
532
|
+
const FastBuffer$1 = Buffer[Symbol.species];
|
|
517
533
|
const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
|
|
518
534
|
const kPerMessageDeflate = Symbol('permessage-deflate');
|
|
519
535
|
const kTotalLength = Symbol('total-length');
|
|
520
536
|
const kCallback = Symbol('callback');
|
|
521
537
|
const kBuffers = Symbol('buffers');
|
|
522
|
-
const kError = Symbol('error');
|
|
538
|
+
const kError$1 = Symbol('error');
|
|
523
539
|
|
|
524
540
|
//
|
|
525
541
|
// We limit zlib concurrency, which prevents severe memory fragmentation
|
|
@@ -533,37 +549,37 @@ let zlibLimiter;
|
|
|
533
549
|
/**
|
|
534
550
|
* permessage-deflate implementation.
|
|
535
551
|
*/
|
|
536
|
-
let PerMessageDeflate$
|
|
552
|
+
let PerMessageDeflate$3 = class PerMessageDeflate {
|
|
537
553
|
/**
|
|
538
554
|
* Creates a PerMessageDeflate instance.
|
|
539
555
|
*
|
|
540
556
|
* @param {Object} [options] Configuration options
|
|
541
|
-
* @param {Boolean} [options.
|
|
542
|
-
*
|
|
557
|
+
* @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support
|
|
558
|
+
* for, or request, a custom client window size
|
|
543
559
|
* @param {Boolean} [options.clientNoContextTakeover=false] Advertise/
|
|
544
560
|
* acknowledge disabling of client context takeover
|
|
561
|
+
* @param {Number} [options.concurrencyLimit=10] The number of concurrent
|
|
562
|
+
* calls to zlib
|
|
563
|
+
* @param {Boolean} [options.isServer=false] Create the instance in either
|
|
564
|
+
* server or client mode
|
|
565
|
+
* @param {Number} [options.maxPayload=0] The maximum allowed message length
|
|
545
566
|
* @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
|
|
546
567
|
* use of a custom server window size
|
|
547
|
-
* @param {
|
|
548
|
-
*
|
|
568
|
+
* @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
|
|
569
|
+
* disabling of server context takeover
|
|
570
|
+
* @param {Number} [options.threshold=1024] Size (in bytes) below which
|
|
571
|
+
* messages should not be compressed if context takeover is disabled
|
|
549
572
|
* @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on
|
|
550
573
|
* deflate
|
|
551
574
|
* @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
|
|
552
575
|
* inflate
|
|
553
|
-
* @param {Number} [options.threshold=1024] Size (in bytes) below which
|
|
554
|
-
* messages should not be compressed
|
|
555
|
-
* @param {Number} [options.concurrencyLimit=10] The number of concurrent
|
|
556
|
-
* calls to zlib
|
|
557
|
-
* @param {Boolean} [isServer=false] Create the instance in either server or
|
|
558
|
-
* client mode
|
|
559
|
-
* @param {Number} [maxPayload=0] The maximum allowed message length
|
|
560
576
|
*/
|
|
561
|
-
constructor(options
|
|
562
|
-
this._maxPayload = maxPayload | 0;
|
|
577
|
+
constructor(options) {
|
|
563
578
|
this._options = options || {};
|
|
564
579
|
this._threshold =
|
|
565
580
|
this._options.threshold !== undefined ? this._options.threshold : 1024;
|
|
566
|
-
this.
|
|
581
|
+
this._maxPayload = this._options.maxPayload | 0;
|
|
582
|
+
this._isServer = !!this._options.isServer;
|
|
567
583
|
this._deflate = null;
|
|
568
584
|
this._inflate = null;
|
|
569
585
|
|
|
@@ -821,7 +837,7 @@ let PerMessageDeflate$4 = class PerMessageDeflate {
|
|
|
821
837
|
/**
|
|
822
838
|
* Compress data. Concurrency limited.
|
|
823
839
|
*
|
|
824
|
-
* @param {Buffer} data Data to compress
|
|
840
|
+
* @param {(Buffer|String)} data Data to compress
|
|
825
841
|
* @param {Boolean} fin Specifies whether or not this is the last fragment
|
|
826
842
|
* @param {Function} callback Callback
|
|
827
843
|
* @public
|
|
@@ -870,7 +886,7 @@ let PerMessageDeflate$4 = class PerMessageDeflate {
|
|
|
870
886
|
if (fin) this._inflate.write(TRAILER);
|
|
871
887
|
|
|
872
888
|
this._inflate.flush(() => {
|
|
873
|
-
const err = this._inflate[kError];
|
|
889
|
+
const err = this._inflate[kError$1];
|
|
874
890
|
|
|
875
891
|
if (err) {
|
|
876
892
|
this._inflate.close();
|
|
@@ -903,7 +919,7 @@ let PerMessageDeflate$4 = class PerMessageDeflate {
|
|
|
903
919
|
/**
|
|
904
920
|
* Compress data.
|
|
905
921
|
*
|
|
906
|
-
* @param {Buffer} data Data to compress
|
|
922
|
+
* @param {(Buffer|String)} data Data to compress
|
|
907
923
|
* @param {Boolean} fin Specifies whether or not this is the last fragment
|
|
908
924
|
* @param {Function} callback Callback
|
|
909
925
|
* @private
|
|
@@ -926,13 +942,6 @@ let PerMessageDeflate$4 = class PerMessageDeflate {
|
|
|
926
942
|
this._deflate[kTotalLength] = 0;
|
|
927
943
|
this._deflate[kBuffers] = [];
|
|
928
944
|
|
|
929
|
-
//
|
|
930
|
-
// An `'error'` event is emitted, only on Node.js < 10.0.0, if the
|
|
931
|
-
// `zlib.DeflateRaw` instance is closed while data is being processed.
|
|
932
|
-
// This can happen if `PerMessageDeflate#cleanup()` is called at the wrong
|
|
933
|
-
// time due to an abnormal WebSocket closure.
|
|
934
|
-
//
|
|
935
|
-
this._deflate.on('error', NOOP$1);
|
|
936
945
|
this._deflate.on('data', deflateOnData);
|
|
937
946
|
}
|
|
938
947
|
|
|
@@ -952,7 +961,9 @@ let PerMessageDeflate$4 = class PerMessageDeflate {
|
|
|
952
961
|
this._deflate[kTotalLength]
|
|
953
962
|
);
|
|
954
963
|
|
|
955
|
-
if (fin)
|
|
964
|
+
if (fin) {
|
|
965
|
+
data = new FastBuffer$1(data.buffer, data.byteOffset, data.length - 4);
|
|
966
|
+
}
|
|
956
967
|
|
|
957
968
|
//
|
|
958
969
|
// Ensure that the callback will not be called again in
|
|
@@ -972,7 +983,7 @@ let PerMessageDeflate$4 = class PerMessageDeflate {
|
|
|
972
983
|
}
|
|
973
984
|
};
|
|
974
985
|
|
|
975
|
-
var permessageDeflate = PerMessageDeflate$
|
|
986
|
+
var permessageDeflate = PerMessageDeflate$3;
|
|
976
987
|
|
|
977
988
|
/**
|
|
978
989
|
* The listener of the `zlib.DeflateRaw` stream `'data'` event.
|
|
@@ -1002,10 +1013,18 @@ function inflateOnData(chunk) {
|
|
|
1002
1013
|
return;
|
|
1003
1014
|
}
|
|
1004
1015
|
|
|
1005
|
-
this[kError] = new RangeError('Max payload size exceeded');
|
|
1006
|
-
this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';
|
|
1007
|
-
this[kError][kStatusCode$2] = 1009;
|
|
1016
|
+
this[kError$1] = new RangeError('Max payload size exceeded');
|
|
1017
|
+
this[kError$1].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';
|
|
1018
|
+
this[kError$1][kStatusCode$2] = 1009;
|
|
1008
1019
|
this.removeListener('data', inflateOnData);
|
|
1020
|
+
|
|
1021
|
+
//
|
|
1022
|
+
// The choice to employ `zlib.reset()` over `zlib.close()` is dictated by the
|
|
1023
|
+
// fact that in Node.js versions prior to 13.10.0, the callback for
|
|
1024
|
+
// `zlib.flush()` is not called if `zlib.close()` is used. Utilizing
|
|
1025
|
+
// `zlib.reset()` ensures that either the callback is invoked or an error is
|
|
1026
|
+
// emitted.
|
|
1027
|
+
//
|
|
1009
1028
|
this.reset();
|
|
1010
1029
|
}
|
|
1011
1030
|
|
|
@@ -1021,6 +1040,12 @@ function inflateOnError(err) {
|
|
|
1021
1040
|
// closed when an error is emitted.
|
|
1022
1041
|
//
|
|
1023
1042
|
this[kPerMessageDeflate]._inflate = null;
|
|
1043
|
+
|
|
1044
|
+
if (this[kError$1]) {
|
|
1045
|
+
this[kCallback](this[kError$1]);
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1024
1049
|
err[kStatusCode$2] = 1007;
|
|
1025
1050
|
this[kCallback](err);
|
|
1026
1051
|
}
|
|
@@ -1113,6 +1138,35 @@ function requireUtf8Validate () {
|
|
|
1113
1138
|
return utf8Validate.exports;
|
|
1114
1139
|
}
|
|
1115
1140
|
|
|
1141
|
+
var isValidUTF8_1;
|
|
1142
|
+
|
|
1143
|
+
const { isUtf8 } = require$$0$2;
|
|
1144
|
+
|
|
1145
|
+
const { hasBlob } = constants;
|
|
1146
|
+
|
|
1147
|
+
//
|
|
1148
|
+
// Allowed token characters:
|
|
1149
|
+
//
|
|
1150
|
+
// '!', '#', '$', '%', '&', ''', '*', '+', '-',
|
|
1151
|
+
// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'
|
|
1152
|
+
//
|
|
1153
|
+
// tokenChars[32] === 0 // ' '
|
|
1154
|
+
// tokenChars[33] === 1 // '!'
|
|
1155
|
+
// tokenChars[34] === 0 // '"'
|
|
1156
|
+
// ...
|
|
1157
|
+
//
|
|
1158
|
+
// prettier-ignore
|
|
1159
|
+
const tokenChars$2 = [
|
|
1160
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15
|
|
1161
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
|
|
1162
|
+
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47
|
|
1163
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63
|
|
1164
|
+
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
|
|
1165
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95
|
|
1166
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
|
|
1167
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127
|
|
1168
|
+
];
|
|
1169
|
+
|
|
1116
1170
|
/**
|
|
1117
1171
|
* Checks if a status code is allowed in a close frame.
|
|
1118
1172
|
*
|
|
@@ -1195,47 +1249,71 @@ function _isValidUTF8(buf) {
|
|
|
1195
1249
|
return true;
|
|
1196
1250
|
}
|
|
1197
1251
|
|
|
1198
|
-
|
|
1199
|
-
|
|
1252
|
+
/**
|
|
1253
|
+
* Determines whether a value is a `Blob`.
|
|
1254
|
+
*
|
|
1255
|
+
* @param {*} value The value to be tested
|
|
1256
|
+
* @return {Boolean} `true` if `value` is a `Blob`, else `false`
|
|
1257
|
+
* @private
|
|
1258
|
+
*/
|
|
1259
|
+
function isBlob$2(value) {
|
|
1260
|
+
return (
|
|
1261
|
+
hasBlob &&
|
|
1262
|
+
typeof value === 'object' &&
|
|
1263
|
+
typeof value.arrayBuffer === 'function' &&
|
|
1264
|
+
typeof value.type === 'string' &&
|
|
1265
|
+
typeof value.stream === 'function' &&
|
|
1266
|
+
(value[Symbol.toStringTag] === 'Blob' ||
|
|
1267
|
+
value[Symbol.toStringTag] === 'File')
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1200
1270
|
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1271
|
+
validation.exports = {
|
|
1272
|
+
isBlob: isBlob$2,
|
|
1273
|
+
isValidStatusCode: isValidStatusCode$2,
|
|
1274
|
+
isValidUTF8: _isValidUTF8,
|
|
1275
|
+
tokenChars: tokenChars$2
|
|
1276
|
+
};
|
|
1205
1277
|
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf);
|
|
1210
|
-
}
|
|
1211
|
-
};
|
|
1212
|
-
} catch (e) /* istanbul ignore next */ {
|
|
1213
|
-
validation.exports = {
|
|
1214
|
-
isValidStatusCode: isValidStatusCode$2,
|
|
1215
|
-
isValidUTF8: _isValidUTF8
|
|
1278
|
+
if (isUtf8) {
|
|
1279
|
+
isValidUTF8_1 = validation.exports.isValidUTF8 = function (buf) {
|
|
1280
|
+
return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);
|
|
1216
1281
|
};
|
|
1282
|
+
} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) {
|
|
1283
|
+
try {
|
|
1284
|
+
const isValidUTF8 = requireUtf8Validate();
|
|
1285
|
+
|
|
1286
|
+
isValidUTF8_1 = validation.exports.isValidUTF8 = function (buf) {
|
|
1287
|
+
return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);
|
|
1288
|
+
};
|
|
1289
|
+
} catch (e) {
|
|
1290
|
+
// Continue regardless of the error.
|
|
1291
|
+
}
|
|
1217
1292
|
}
|
|
1218
1293
|
|
|
1219
1294
|
var validationExports = validation.exports;
|
|
1220
1295
|
|
|
1221
|
-
const { Writable } = require$$0$
|
|
1296
|
+
const { Writable } = require$$0$3;
|
|
1222
1297
|
|
|
1223
|
-
const PerMessageDeflate$
|
|
1298
|
+
const PerMessageDeflate$2 = permessageDeflate;
|
|
1224
1299
|
const {
|
|
1225
1300
|
BINARY_TYPES: BINARY_TYPES$1,
|
|
1226
1301
|
EMPTY_BUFFER: EMPTY_BUFFER$2,
|
|
1227
1302
|
kStatusCode: kStatusCode$1,
|
|
1228
|
-
kWebSocket: kWebSocket$
|
|
1303
|
+
kWebSocket: kWebSocket$3
|
|
1229
1304
|
} = constants;
|
|
1230
1305
|
const { concat, toArrayBuffer, unmask } = bufferUtilExports;
|
|
1231
1306
|
const { isValidStatusCode: isValidStatusCode$1, isValidUTF8 } = validationExports;
|
|
1232
1307
|
|
|
1308
|
+
const FastBuffer = Buffer[Symbol.species];
|
|
1309
|
+
|
|
1233
1310
|
const GET_INFO = 0;
|
|
1234
1311
|
const GET_PAYLOAD_LENGTH_16 = 1;
|
|
1235
1312
|
const GET_PAYLOAD_LENGTH_64 = 2;
|
|
1236
1313
|
const GET_MASK = 3;
|
|
1237
1314
|
const GET_DATA = 4;
|
|
1238
1315
|
const INFLATING = 5;
|
|
1316
|
+
const DEFER_EVENT = 6;
|
|
1239
1317
|
|
|
1240
1318
|
/**
|
|
1241
1319
|
* HyBi Receiver implementation.
|
|
@@ -1246,20 +1324,32 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1246
1324
|
/**
|
|
1247
1325
|
* Creates a Receiver instance.
|
|
1248
1326
|
*
|
|
1249
|
-
* @param {
|
|
1250
|
-
* @param {
|
|
1251
|
-
*
|
|
1252
|
-
*
|
|
1253
|
-
* @param {
|
|
1327
|
+
* @param {Object} [options] Options object
|
|
1328
|
+
* @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
|
|
1329
|
+
* any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
|
|
1330
|
+
* multiple times in the same tick
|
|
1331
|
+
* @param {String} [options.binaryType=nodebuffer] The type for binary data
|
|
1332
|
+
* @param {Object} [options.extensions] An object containing the negotiated
|
|
1333
|
+
* extensions
|
|
1334
|
+
* @param {Boolean} [options.isServer=false] Specifies whether to operate in
|
|
1335
|
+
* client or server mode
|
|
1336
|
+
* @param {Number} [options.maxPayload=0] The maximum allowed message length
|
|
1337
|
+
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
|
|
1338
|
+
* not to skip UTF-8 validation for text and close messages
|
|
1254
1339
|
*/
|
|
1255
|
-
constructor(
|
|
1340
|
+
constructor(options = {}) {
|
|
1256
1341
|
super();
|
|
1257
1342
|
|
|
1258
|
-
this.
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
this.
|
|
1343
|
+
this._allowSynchronousEvents =
|
|
1344
|
+
options.allowSynchronousEvents !== undefined
|
|
1345
|
+
? options.allowSynchronousEvents
|
|
1346
|
+
: true;
|
|
1347
|
+
this._binaryType = options.binaryType || BINARY_TYPES$1[0];
|
|
1348
|
+
this._extensions = options.extensions || {};
|
|
1349
|
+
this._isServer = !!options.isServer;
|
|
1350
|
+
this._maxPayload = options.maxPayload | 0;
|
|
1351
|
+
this._skipUTF8Validation = !!options.skipUTF8Validation;
|
|
1352
|
+
this[kWebSocket$3] = undefined;
|
|
1263
1353
|
|
|
1264
1354
|
this._bufferedBytes = 0;
|
|
1265
1355
|
this._buffers = [];
|
|
@@ -1276,8 +1366,9 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1276
1366
|
this._messageLength = 0;
|
|
1277
1367
|
this._fragments = [];
|
|
1278
1368
|
|
|
1279
|
-
this.
|
|
1369
|
+
this._errored = false;
|
|
1280
1370
|
this._loop = false;
|
|
1371
|
+
this._state = GET_INFO;
|
|
1281
1372
|
}
|
|
1282
1373
|
|
|
1283
1374
|
/**
|
|
@@ -1310,8 +1401,13 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1310
1401
|
|
|
1311
1402
|
if (n < this._buffers[0].length) {
|
|
1312
1403
|
const buf = this._buffers[0];
|
|
1313
|
-
this._buffers[0] =
|
|
1314
|
-
|
|
1404
|
+
this._buffers[0] = new FastBuffer(
|
|
1405
|
+
buf.buffer,
|
|
1406
|
+
buf.byteOffset + n,
|
|
1407
|
+
buf.length - n
|
|
1408
|
+
);
|
|
1409
|
+
|
|
1410
|
+
return new FastBuffer(buf.buffer, buf.byteOffset, n);
|
|
1315
1411
|
}
|
|
1316
1412
|
|
|
1317
1413
|
const dst = Buffer.allocUnsafe(n);
|
|
@@ -1324,7 +1420,11 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1324
1420
|
dst.set(this._buffers.shift(), offset);
|
|
1325
1421
|
} else {
|
|
1326
1422
|
dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
|
|
1327
|
-
this._buffers[0] =
|
|
1423
|
+
this._buffers[0] = new FastBuffer(
|
|
1424
|
+
buf.buffer,
|
|
1425
|
+
buf.byteOffset + n,
|
|
1426
|
+
buf.length - n
|
|
1427
|
+
);
|
|
1328
1428
|
}
|
|
1329
1429
|
|
|
1330
1430
|
n -= buf.length;
|
|
@@ -1340,43 +1440,42 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1340
1440
|
* @private
|
|
1341
1441
|
*/
|
|
1342
1442
|
startLoop(cb) {
|
|
1343
|
-
let err;
|
|
1344
1443
|
this._loop = true;
|
|
1345
1444
|
|
|
1346
1445
|
do {
|
|
1347
1446
|
switch (this._state) {
|
|
1348
1447
|
case GET_INFO:
|
|
1349
|
-
|
|
1448
|
+
this.getInfo(cb);
|
|
1350
1449
|
break;
|
|
1351
1450
|
case GET_PAYLOAD_LENGTH_16:
|
|
1352
|
-
|
|
1451
|
+
this.getPayloadLength16(cb);
|
|
1353
1452
|
break;
|
|
1354
1453
|
case GET_PAYLOAD_LENGTH_64:
|
|
1355
|
-
|
|
1454
|
+
this.getPayloadLength64(cb);
|
|
1356
1455
|
break;
|
|
1357
1456
|
case GET_MASK:
|
|
1358
1457
|
this.getMask();
|
|
1359
1458
|
break;
|
|
1360
1459
|
case GET_DATA:
|
|
1361
|
-
|
|
1460
|
+
this.getData(cb);
|
|
1362
1461
|
break;
|
|
1363
|
-
|
|
1364
|
-
|
|
1462
|
+
case INFLATING:
|
|
1463
|
+
case DEFER_EVENT:
|
|
1365
1464
|
this._loop = false;
|
|
1366
1465
|
return;
|
|
1367
1466
|
}
|
|
1368
1467
|
} while (this._loop);
|
|
1369
1468
|
|
|
1370
|
-
cb(
|
|
1469
|
+
if (!this._errored) cb();
|
|
1371
1470
|
}
|
|
1372
1471
|
|
|
1373
1472
|
/**
|
|
1374
1473
|
* Reads the first two bytes of a frame.
|
|
1375
1474
|
*
|
|
1376
|
-
* @
|
|
1475
|
+
* @param {Function} cb Callback
|
|
1377
1476
|
* @private
|
|
1378
1477
|
*/
|
|
1379
|
-
getInfo() {
|
|
1478
|
+
getInfo(cb) {
|
|
1380
1479
|
if (this._bufferedBytes < 2) {
|
|
1381
1480
|
this._loop = false;
|
|
1382
1481
|
return;
|
|
@@ -1385,27 +1484,31 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1385
1484
|
const buf = this.consume(2);
|
|
1386
1485
|
|
|
1387
1486
|
if ((buf[0] & 0x30) !== 0x00) {
|
|
1388
|
-
|
|
1389
|
-
return error(
|
|
1487
|
+
const error = this.createError(
|
|
1390
1488
|
RangeError,
|
|
1391
1489
|
'RSV2 and RSV3 must be clear',
|
|
1392
1490
|
true,
|
|
1393
1491
|
1002,
|
|
1394
1492
|
'WS_ERR_UNEXPECTED_RSV_2_3'
|
|
1395
1493
|
);
|
|
1494
|
+
|
|
1495
|
+
cb(error);
|
|
1496
|
+
return;
|
|
1396
1497
|
}
|
|
1397
1498
|
|
|
1398
1499
|
const compressed = (buf[0] & 0x40) === 0x40;
|
|
1399
1500
|
|
|
1400
|
-
if (compressed && !this._extensions[PerMessageDeflate$
|
|
1401
|
-
|
|
1402
|
-
return error(
|
|
1501
|
+
if (compressed && !this._extensions[PerMessageDeflate$2.extensionName]) {
|
|
1502
|
+
const error = this.createError(
|
|
1403
1503
|
RangeError,
|
|
1404
1504
|
'RSV1 must be clear',
|
|
1405
1505
|
true,
|
|
1406
1506
|
1002,
|
|
1407
1507
|
'WS_ERR_UNEXPECTED_RSV_1'
|
|
1408
1508
|
);
|
|
1509
|
+
|
|
1510
|
+
cb(error);
|
|
1511
|
+
return;
|
|
1409
1512
|
}
|
|
1410
1513
|
|
|
1411
1514
|
this._fin = (buf[0] & 0x80) === 0x80;
|
|
@@ -1414,83 +1517,100 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1414
1517
|
|
|
1415
1518
|
if (this._opcode === 0x00) {
|
|
1416
1519
|
if (compressed) {
|
|
1417
|
-
|
|
1418
|
-
return error(
|
|
1520
|
+
const error = this.createError(
|
|
1419
1521
|
RangeError,
|
|
1420
1522
|
'RSV1 must be clear',
|
|
1421
1523
|
true,
|
|
1422
1524
|
1002,
|
|
1423
1525
|
'WS_ERR_UNEXPECTED_RSV_1'
|
|
1424
1526
|
);
|
|
1527
|
+
|
|
1528
|
+
cb(error);
|
|
1529
|
+
return;
|
|
1425
1530
|
}
|
|
1426
1531
|
|
|
1427
1532
|
if (!this._fragmented) {
|
|
1428
|
-
|
|
1429
|
-
return error(
|
|
1533
|
+
const error = this.createError(
|
|
1430
1534
|
RangeError,
|
|
1431
1535
|
'invalid opcode 0',
|
|
1432
1536
|
true,
|
|
1433
1537
|
1002,
|
|
1434
1538
|
'WS_ERR_INVALID_OPCODE'
|
|
1435
1539
|
);
|
|
1540
|
+
|
|
1541
|
+
cb(error);
|
|
1542
|
+
return;
|
|
1436
1543
|
}
|
|
1437
1544
|
|
|
1438
1545
|
this._opcode = this._fragmented;
|
|
1439
1546
|
} else if (this._opcode === 0x01 || this._opcode === 0x02) {
|
|
1440
1547
|
if (this._fragmented) {
|
|
1441
|
-
|
|
1442
|
-
return error(
|
|
1548
|
+
const error = this.createError(
|
|
1443
1549
|
RangeError,
|
|
1444
1550
|
`invalid opcode ${this._opcode}`,
|
|
1445
1551
|
true,
|
|
1446
1552
|
1002,
|
|
1447
1553
|
'WS_ERR_INVALID_OPCODE'
|
|
1448
1554
|
);
|
|
1555
|
+
|
|
1556
|
+
cb(error);
|
|
1557
|
+
return;
|
|
1449
1558
|
}
|
|
1450
1559
|
|
|
1451
1560
|
this._compressed = compressed;
|
|
1452
1561
|
} else if (this._opcode > 0x07 && this._opcode < 0x0b) {
|
|
1453
1562
|
if (!this._fin) {
|
|
1454
|
-
|
|
1455
|
-
return error(
|
|
1563
|
+
const error = this.createError(
|
|
1456
1564
|
RangeError,
|
|
1457
1565
|
'FIN must be set',
|
|
1458
1566
|
true,
|
|
1459
1567
|
1002,
|
|
1460
1568
|
'WS_ERR_EXPECTED_FIN'
|
|
1461
1569
|
);
|
|
1570
|
+
|
|
1571
|
+
cb(error);
|
|
1572
|
+
return;
|
|
1462
1573
|
}
|
|
1463
1574
|
|
|
1464
1575
|
if (compressed) {
|
|
1465
|
-
|
|
1466
|
-
return error(
|
|
1576
|
+
const error = this.createError(
|
|
1467
1577
|
RangeError,
|
|
1468
1578
|
'RSV1 must be clear',
|
|
1469
1579
|
true,
|
|
1470
1580
|
1002,
|
|
1471
1581
|
'WS_ERR_UNEXPECTED_RSV_1'
|
|
1472
1582
|
);
|
|
1583
|
+
|
|
1584
|
+
cb(error);
|
|
1585
|
+
return;
|
|
1473
1586
|
}
|
|
1474
1587
|
|
|
1475
|
-
if (
|
|
1476
|
-
this.
|
|
1477
|
-
|
|
1588
|
+
if (
|
|
1589
|
+
this._payloadLength > 0x7d ||
|
|
1590
|
+
(this._opcode === 0x08 && this._payloadLength === 1)
|
|
1591
|
+
) {
|
|
1592
|
+
const error = this.createError(
|
|
1478
1593
|
RangeError,
|
|
1479
1594
|
`invalid payload length ${this._payloadLength}`,
|
|
1480
1595
|
true,
|
|
1481
1596
|
1002,
|
|
1482
1597
|
'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'
|
|
1483
1598
|
);
|
|
1599
|
+
|
|
1600
|
+
cb(error);
|
|
1601
|
+
return;
|
|
1484
1602
|
}
|
|
1485
1603
|
} else {
|
|
1486
|
-
|
|
1487
|
-
return error(
|
|
1604
|
+
const error = this.createError(
|
|
1488
1605
|
RangeError,
|
|
1489
1606
|
`invalid opcode ${this._opcode}`,
|
|
1490
1607
|
true,
|
|
1491
1608
|
1002,
|
|
1492
1609
|
'WS_ERR_INVALID_OPCODE'
|
|
1493
1610
|
);
|
|
1611
|
+
|
|
1612
|
+
cb(error);
|
|
1613
|
+
return;
|
|
1494
1614
|
}
|
|
1495
1615
|
|
|
1496
1616
|
if (!this._fin && !this._fragmented) this._fragmented = this._opcode;
|
|
@@ -1498,54 +1618,58 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1498
1618
|
|
|
1499
1619
|
if (this._isServer) {
|
|
1500
1620
|
if (!this._masked) {
|
|
1501
|
-
|
|
1502
|
-
return error(
|
|
1621
|
+
const error = this.createError(
|
|
1503
1622
|
RangeError,
|
|
1504
1623
|
'MASK must be set',
|
|
1505
1624
|
true,
|
|
1506
1625
|
1002,
|
|
1507
1626
|
'WS_ERR_EXPECTED_MASK'
|
|
1508
1627
|
);
|
|
1628
|
+
|
|
1629
|
+
cb(error);
|
|
1630
|
+
return;
|
|
1509
1631
|
}
|
|
1510
1632
|
} else if (this._masked) {
|
|
1511
|
-
|
|
1512
|
-
return error(
|
|
1633
|
+
const error = this.createError(
|
|
1513
1634
|
RangeError,
|
|
1514
1635
|
'MASK must be clear',
|
|
1515
1636
|
true,
|
|
1516
1637
|
1002,
|
|
1517
1638
|
'WS_ERR_UNEXPECTED_MASK'
|
|
1518
1639
|
);
|
|
1640
|
+
|
|
1641
|
+
cb(error);
|
|
1642
|
+
return;
|
|
1519
1643
|
}
|
|
1520
1644
|
|
|
1521
1645
|
if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;
|
|
1522
1646
|
else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;
|
|
1523
|
-
else
|
|
1647
|
+
else this.haveLength(cb);
|
|
1524
1648
|
}
|
|
1525
1649
|
|
|
1526
1650
|
/**
|
|
1527
1651
|
* Gets extended payload length (7+16).
|
|
1528
1652
|
*
|
|
1529
|
-
* @
|
|
1653
|
+
* @param {Function} cb Callback
|
|
1530
1654
|
* @private
|
|
1531
1655
|
*/
|
|
1532
|
-
getPayloadLength16() {
|
|
1656
|
+
getPayloadLength16(cb) {
|
|
1533
1657
|
if (this._bufferedBytes < 2) {
|
|
1534
1658
|
this._loop = false;
|
|
1535
1659
|
return;
|
|
1536
1660
|
}
|
|
1537
1661
|
|
|
1538
1662
|
this._payloadLength = this.consume(2).readUInt16BE(0);
|
|
1539
|
-
|
|
1663
|
+
this.haveLength(cb);
|
|
1540
1664
|
}
|
|
1541
1665
|
|
|
1542
1666
|
/**
|
|
1543
1667
|
* Gets extended payload length (7+64).
|
|
1544
1668
|
*
|
|
1545
|
-
* @
|
|
1669
|
+
* @param {Function} cb Callback
|
|
1546
1670
|
* @private
|
|
1547
1671
|
*/
|
|
1548
|
-
getPayloadLength64() {
|
|
1672
|
+
getPayloadLength64(cb) {
|
|
1549
1673
|
if (this._bufferedBytes < 8) {
|
|
1550
1674
|
this._loop = false;
|
|
1551
1675
|
return;
|
|
@@ -1559,38 +1683,42 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1559
1683
|
// if payload length is greater than this number.
|
|
1560
1684
|
//
|
|
1561
1685
|
if (num > Math.pow(2, 53 - 32) - 1) {
|
|
1562
|
-
|
|
1563
|
-
return error(
|
|
1686
|
+
const error = this.createError(
|
|
1564
1687
|
RangeError,
|
|
1565
1688
|
'Unsupported WebSocket frame: payload length > 2^53 - 1',
|
|
1566
1689
|
false,
|
|
1567
1690
|
1009,
|
|
1568
1691
|
'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'
|
|
1569
1692
|
);
|
|
1693
|
+
|
|
1694
|
+
cb(error);
|
|
1695
|
+
return;
|
|
1570
1696
|
}
|
|
1571
1697
|
|
|
1572
1698
|
this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);
|
|
1573
|
-
|
|
1699
|
+
this.haveLength(cb);
|
|
1574
1700
|
}
|
|
1575
1701
|
|
|
1576
1702
|
/**
|
|
1577
1703
|
* Payload length has been read.
|
|
1578
1704
|
*
|
|
1579
|
-
* @
|
|
1705
|
+
* @param {Function} cb Callback
|
|
1580
1706
|
* @private
|
|
1581
1707
|
*/
|
|
1582
|
-
haveLength() {
|
|
1708
|
+
haveLength(cb) {
|
|
1583
1709
|
if (this._payloadLength && this._opcode < 0x08) {
|
|
1584
1710
|
this._totalPayloadLength += this._payloadLength;
|
|
1585
1711
|
if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
|
|
1586
|
-
|
|
1587
|
-
return error(
|
|
1712
|
+
const error = this.createError(
|
|
1588
1713
|
RangeError,
|
|
1589
1714
|
'Max payload size exceeded',
|
|
1590
1715
|
false,
|
|
1591
1716
|
1009,
|
|
1592
1717
|
'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'
|
|
1593
1718
|
);
|
|
1719
|
+
|
|
1720
|
+
cb(error);
|
|
1721
|
+
return;
|
|
1594
1722
|
}
|
|
1595
1723
|
}
|
|
1596
1724
|
|
|
@@ -1617,7 +1745,6 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1617
1745
|
* Reads data bytes.
|
|
1618
1746
|
*
|
|
1619
1747
|
* @param {Function} cb Callback
|
|
1620
|
-
* @return {(Error|RangeError|undefined)} A possible error
|
|
1621
1748
|
* @private
|
|
1622
1749
|
*/
|
|
1623
1750
|
getData(cb) {
|
|
@@ -1630,10 +1757,19 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1630
1757
|
}
|
|
1631
1758
|
|
|
1632
1759
|
data = this.consume(this._payloadLength);
|
|
1633
|
-
|
|
1760
|
+
|
|
1761
|
+
if (
|
|
1762
|
+
this._masked &&
|
|
1763
|
+
(this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0
|
|
1764
|
+
) {
|
|
1765
|
+
unmask(data, this._mask);
|
|
1766
|
+
}
|
|
1634
1767
|
}
|
|
1635
1768
|
|
|
1636
|
-
if (this._opcode > 0x07)
|
|
1769
|
+
if (this._opcode > 0x07) {
|
|
1770
|
+
this.controlMessage(data, cb);
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1637
1773
|
|
|
1638
1774
|
if (this._compressed) {
|
|
1639
1775
|
this._state = INFLATING;
|
|
@@ -1643,14 +1779,14 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1643
1779
|
|
|
1644
1780
|
if (data.length) {
|
|
1645
1781
|
//
|
|
1646
|
-
// This message is not compressed so its
|
|
1782
|
+
// This message is not compressed so its length is the sum of the payload
|
|
1647
1783
|
// length of all fragments.
|
|
1648
1784
|
//
|
|
1649
1785
|
this._messageLength = this._totalPayloadLength;
|
|
1650
1786
|
this._fragments.push(data);
|
|
1651
1787
|
}
|
|
1652
1788
|
|
|
1653
|
-
|
|
1789
|
+
this.dataMessage(cb);
|
|
1654
1790
|
}
|
|
1655
1791
|
|
|
1656
1792
|
/**
|
|
@@ -1661,7 +1797,7 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1661
1797
|
* @private
|
|
1662
1798
|
*/
|
|
1663
1799
|
decompress(data, cb) {
|
|
1664
|
-
const perMessageDeflate = this._extensions[PerMessageDeflate$
|
|
1800
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate$2.extensionName];
|
|
1665
1801
|
|
|
1666
1802
|
perMessageDeflate.decompress(data, this._fin, (err, buf) => {
|
|
1667
1803
|
if (err) return cb(err);
|
|
@@ -1669,74 +1805,98 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1669
1805
|
if (buf.length) {
|
|
1670
1806
|
this._messageLength += buf.length;
|
|
1671
1807
|
if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'
|
|
1679
|
-
)
|
|
1808
|
+
const error = this.createError(
|
|
1809
|
+
RangeError,
|
|
1810
|
+
'Max payload size exceeded',
|
|
1811
|
+
false,
|
|
1812
|
+
1009,
|
|
1813
|
+
'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'
|
|
1680
1814
|
);
|
|
1815
|
+
|
|
1816
|
+
cb(error);
|
|
1817
|
+
return;
|
|
1681
1818
|
}
|
|
1682
1819
|
|
|
1683
1820
|
this._fragments.push(buf);
|
|
1684
1821
|
}
|
|
1685
1822
|
|
|
1686
|
-
|
|
1687
|
-
if (
|
|
1688
|
-
|
|
1689
|
-
this.startLoop(cb);
|
|
1823
|
+
this.dataMessage(cb);
|
|
1824
|
+
if (this._state === GET_INFO) this.startLoop(cb);
|
|
1690
1825
|
});
|
|
1691
1826
|
}
|
|
1692
1827
|
|
|
1693
1828
|
/**
|
|
1694
1829
|
* Handles a data message.
|
|
1695
1830
|
*
|
|
1696
|
-
* @
|
|
1831
|
+
* @param {Function} cb Callback
|
|
1697
1832
|
* @private
|
|
1698
1833
|
*/
|
|
1699
|
-
dataMessage() {
|
|
1700
|
-
if (this._fin) {
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
if (this._binaryType === 'nodebuffer') {
|
|
1713
|
-
data = concat(fragments, messageLength);
|
|
1714
|
-
} else if (this._binaryType === 'arraybuffer') {
|
|
1715
|
-
data = toArrayBuffer(concat(fragments, messageLength));
|
|
1716
|
-
} else {
|
|
1717
|
-
data = fragments;
|
|
1718
|
-
}
|
|
1834
|
+
dataMessage(cb) {
|
|
1835
|
+
if (!this._fin) {
|
|
1836
|
+
this._state = GET_INFO;
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
const messageLength = this._messageLength;
|
|
1841
|
+
const fragments = this._fragments;
|
|
1842
|
+
|
|
1843
|
+
this._totalPayloadLength = 0;
|
|
1844
|
+
this._messageLength = 0;
|
|
1845
|
+
this._fragmented = 0;
|
|
1846
|
+
this._fragments = [];
|
|
1719
1847
|
|
|
1720
|
-
|
|
1848
|
+
if (this._opcode === 2) {
|
|
1849
|
+
let data;
|
|
1850
|
+
|
|
1851
|
+
if (this._binaryType === 'nodebuffer') {
|
|
1852
|
+
data = concat(fragments, messageLength);
|
|
1853
|
+
} else if (this._binaryType === 'arraybuffer') {
|
|
1854
|
+
data = toArrayBuffer(concat(fragments, messageLength));
|
|
1855
|
+
} else if (this._binaryType === 'blob') {
|
|
1856
|
+
data = new Blob(fragments);
|
|
1721
1857
|
} else {
|
|
1722
|
-
|
|
1858
|
+
data = fragments;
|
|
1859
|
+
}
|
|
1723
1860
|
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
);
|
|
1733
|
-
}
|
|
1861
|
+
if (this._allowSynchronousEvents) {
|
|
1862
|
+
this.emit('message', data, true);
|
|
1863
|
+
this._state = GET_INFO;
|
|
1864
|
+
} else {
|
|
1865
|
+
this._state = DEFER_EVENT;
|
|
1866
|
+
setImmediate(() => {
|
|
1867
|
+
this.emit('message', data, true);
|
|
1868
|
+
this._state = GET_INFO;
|
|
1869
|
+
this.startLoop(cb);
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1872
|
+
} else {
|
|
1873
|
+
const buf = concat(fragments, messageLength);
|
|
1734
1874
|
|
|
1735
|
-
|
|
1875
|
+
if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
|
|
1876
|
+
const error = this.createError(
|
|
1877
|
+
Error,
|
|
1878
|
+
'invalid UTF-8 sequence',
|
|
1879
|
+
true,
|
|
1880
|
+
1007,
|
|
1881
|
+
'WS_ERR_INVALID_UTF8'
|
|
1882
|
+
);
|
|
1883
|
+
|
|
1884
|
+
cb(error);
|
|
1885
|
+
return;
|
|
1736
1886
|
}
|
|
1737
|
-
}
|
|
1738
1887
|
|
|
1739
|
-
|
|
1888
|
+
if (this._state === INFLATING || this._allowSynchronousEvents) {
|
|
1889
|
+
this.emit('message', buf, false);
|
|
1890
|
+
this._state = GET_INFO;
|
|
1891
|
+
} else {
|
|
1892
|
+
this._state = DEFER_EVENT;
|
|
1893
|
+
setImmediate(() => {
|
|
1894
|
+
this.emit('message', buf, false);
|
|
1895
|
+
this._state = GET_INFO;
|
|
1896
|
+
this.startLoop(cb);
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1740
1900
|
}
|
|
1741
1901
|
|
|
1742
1902
|
/**
|
|
@@ -1746,93 +1906,117 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1746
1906
|
* @return {(Error|RangeError|undefined)} A possible error
|
|
1747
1907
|
* @private
|
|
1748
1908
|
*/
|
|
1749
|
-
controlMessage(data) {
|
|
1909
|
+
controlMessage(data, cb) {
|
|
1750
1910
|
if (this._opcode === 0x08) {
|
|
1751
|
-
this._loop = false;
|
|
1752
|
-
|
|
1753
1911
|
if (data.length === 0) {
|
|
1754
|
-
this.
|
|
1912
|
+
this._loop = false;
|
|
1913
|
+
this.emit('conclude', 1005, EMPTY_BUFFER$2);
|
|
1755
1914
|
this.end();
|
|
1756
|
-
} else if (data.length === 1) {
|
|
1757
|
-
return error(
|
|
1758
|
-
RangeError,
|
|
1759
|
-
'invalid payload length 1',
|
|
1760
|
-
true,
|
|
1761
|
-
1002,
|
|
1762
|
-
'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'
|
|
1763
|
-
);
|
|
1764
1915
|
} else {
|
|
1765
1916
|
const code = data.readUInt16BE(0);
|
|
1766
1917
|
|
|
1767
1918
|
if (!isValidStatusCode$1(code)) {
|
|
1768
|
-
|
|
1919
|
+
const error = this.createError(
|
|
1769
1920
|
RangeError,
|
|
1770
1921
|
`invalid status code ${code}`,
|
|
1771
1922
|
true,
|
|
1772
1923
|
1002,
|
|
1773
1924
|
'WS_ERR_INVALID_CLOSE_CODE'
|
|
1774
1925
|
);
|
|
1926
|
+
|
|
1927
|
+
cb(error);
|
|
1928
|
+
return;
|
|
1775
1929
|
}
|
|
1776
1930
|
|
|
1777
|
-
const buf =
|
|
1931
|
+
const buf = new FastBuffer(
|
|
1932
|
+
data.buffer,
|
|
1933
|
+
data.byteOffset + 2,
|
|
1934
|
+
data.length - 2
|
|
1935
|
+
);
|
|
1778
1936
|
|
|
1779
|
-
if (!isValidUTF8(buf)) {
|
|
1780
|
-
|
|
1937
|
+
if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
|
|
1938
|
+
const error = this.createError(
|
|
1781
1939
|
Error,
|
|
1782
1940
|
'invalid UTF-8 sequence',
|
|
1783
1941
|
true,
|
|
1784
1942
|
1007,
|
|
1785
1943
|
'WS_ERR_INVALID_UTF8'
|
|
1786
1944
|
);
|
|
1945
|
+
|
|
1946
|
+
cb(error);
|
|
1947
|
+
return;
|
|
1787
1948
|
}
|
|
1788
1949
|
|
|
1789
|
-
this.
|
|
1950
|
+
this._loop = false;
|
|
1951
|
+
this.emit('conclude', code, buf);
|
|
1790
1952
|
this.end();
|
|
1791
1953
|
}
|
|
1792
|
-
|
|
1793
|
-
this.
|
|
1954
|
+
|
|
1955
|
+
this._state = GET_INFO;
|
|
1956
|
+
return;
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
if (this._allowSynchronousEvents) {
|
|
1960
|
+
this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);
|
|
1961
|
+
this._state = GET_INFO;
|
|
1794
1962
|
} else {
|
|
1795
|
-
this.
|
|
1963
|
+
this._state = DEFER_EVENT;
|
|
1964
|
+
setImmediate(() => {
|
|
1965
|
+
this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);
|
|
1966
|
+
this._state = GET_INFO;
|
|
1967
|
+
this.startLoop(cb);
|
|
1968
|
+
});
|
|
1796
1969
|
}
|
|
1970
|
+
}
|
|
1797
1971
|
|
|
1798
|
-
|
|
1972
|
+
/**
|
|
1973
|
+
* Builds an error object.
|
|
1974
|
+
*
|
|
1975
|
+
* @param {function(new:Error|RangeError)} ErrorCtor The error constructor
|
|
1976
|
+
* @param {String} message The error message
|
|
1977
|
+
* @param {Boolean} prefix Specifies whether or not to add a default prefix to
|
|
1978
|
+
* `message`
|
|
1979
|
+
* @param {Number} statusCode The status code
|
|
1980
|
+
* @param {String} errorCode The exposed error code
|
|
1981
|
+
* @return {(Error|RangeError)} The error
|
|
1982
|
+
* @private
|
|
1983
|
+
*/
|
|
1984
|
+
createError(ErrorCtor, message, prefix, statusCode, errorCode) {
|
|
1985
|
+
this._loop = false;
|
|
1986
|
+
this._errored = true;
|
|
1987
|
+
|
|
1988
|
+
const err = new ErrorCtor(
|
|
1989
|
+
prefix ? `Invalid WebSocket frame: ${message}` : message
|
|
1990
|
+
);
|
|
1991
|
+
|
|
1992
|
+
Error.captureStackTrace(err, this.createError);
|
|
1993
|
+
err.code = errorCode;
|
|
1994
|
+
err[kStatusCode$1] = statusCode;
|
|
1995
|
+
return err;
|
|
1799
1996
|
}
|
|
1800
1997
|
};
|
|
1801
1998
|
|
|
1802
1999
|
var receiver = Receiver$1;
|
|
1803
2000
|
|
|
1804
|
-
|
|
1805
|
-
* Builds an error object.
|
|
1806
|
-
*
|
|
1807
|
-
* @param {function(new:Error|RangeError)} ErrorCtor The error constructor
|
|
1808
|
-
* @param {String} message The error message
|
|
1809
|
-
* @param {Boolean} prefix Specifies whether or not to add a default prefix to
|
|
1810
|
-
* `message`
|
|
1811
|
-
* @param {Number} statusCode The status code
|
|
1812
|
-
* @param {String} errorCode The exposed error code
|
|
1813
|
-
* @return {(Error|RangeError)} The error
|
|
1814
|
-
* @private
|
|
1815
|
-
*/
|
|
1816
|
-
function error(ErrorCtor, message, prefix, statusCode, errorCode) {
|
|
1817
|
-
const err = new ErrorCtor(
|
|
1818
|
-
prefix ? `Invalid WebSocket frame: ${message}` : message
|
|
1819
|
-
);
|
|
1820
|
-
|
|
1821
|
-
Error.captureStackTrace(err, error);
|
|
1822
|
-
err.code = errorCode;
|
|
1823
|
-
err[kStatusCode$1] = statusCode;
|
|
1824
|
-
return err;
|
|
1825
|
-
}
|
|
2001
|
+
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex" }] */
|
|
1826
2002
|
|
|
1827
|
-
|
|
1828
|
-
const { randomFillSync } = require$$
|
|
2003
|
+
const { Duplex: Duplex$3 } = require$$0$3;
|
|
2004
|
+
const { randomFillSync } = require$$1$1;
|
|
1829
2005
|
|
|
1830
|
-
const PerMessageDeflate$
|
|
1831
|
-
const { EMPTY_BUFFER: EMPTY_BUFFER$1 } = constants;
|
|
1832
|
-
const { isValidStatusCode } = validationExports;
|
|
2006
|
+
const PerMessageDeflate$1 = permessageDeflate;
|
|
2007
|
+
const { EMPTY_BUFFER: EMPTY_BUFFER$1, kWebSocket: kWebSocket$2, NOOP: NOOP$1 } = constants;
|
|
2008
|
+
const { isBlob: isBlob$1, isValidStatusCode } = validationExports;
|
|
1833
2009
|
const { mask: applyMask, toBuffer: toBuffer$1 } = bufferUtilExports;
|
|
1834
2010
|
|
|
1835
|
-
const
|
|
2011
|
+
const kByteLength = Symbol('kByteLength');
|
|
2012
|
+
const maskBuffer = Buffer.alloc(4);
|
|
2013
|
+
const RANDOM_POOL_SIZE = 8 * 1024;
|
|
2014
|
+
let randomPool;
|
|
2015
|
+
let randomPoolPointer = RANDOM_POOL_SIZE;
|
|
2016
|
+
|
|
2017
|
+
const DEFAULT = 0;
|
|
2018
|
+
const DEFLATING = 1;
|
|
2019
|
+
const GET_BLOB_DATA = 2;
|
|
1836
2020
|
|
|
1837
2021
|
/**
|
|
1838
2022
|
* HyBi Sender implementation.
|
|
@@ -1841,52 +2025,116 @@ let Sender$1 = class Sender {
|
|
|
1841
2025
|
/**
|
|
1842
2026
|
* Creates a Sender instance.
|
|
1843
2027
|
*
|
|
1844
|
-
* @param {
|
|
2028
|
+
* @param {Duplex} socket The connection socket
|
|
1845
2029
|
* @param {Object} [extensions] An object containing the negotiated extensions
|
|
2030
|
+
* @param {Function} [generateMask] The function used to generate the masking
|
|
2031
|
+
* key
|
|
1846
2032
|
*/
|
|
1847
|
-
constructor(socket, extensions) {
|
|
2033
|
+
constructor(socket, extensions, generateMask) {
|
|
1848
2034
|
this._extensions = extensions || {};
|
|
2035
|
+
|
|
2036
|
+
if (generateMask) {
|
|
2037
|
+
this._generateMask = generateMask;
|
|
2038
|
+
this._maskBuffer = Buffer.alloc(4);
|
|
2039
|
+
}
|
|
2040
|
+
|
|
1849
2041
|
this._socket = socket;
|
|
1850
2042
|
|
|
1851
2043
|
this._firstFragment = true;
|
|
1852
2044
|
this._compress = false;
|
|
1853
2045
|
|
|
1854
2046
|
this._bufferedBytes = 0;
|
|
1855
|
-
this._deflating = false;
|
|
1856
2047
|
this._queue = [];
|
|
2048
|
+
this._state = DEFAULT;
|
|
2049
|
+
this.onerror = NOOP$1;
|
|
2050
|
+
this[kWebSocket$2] = undefined;
|
|
1857
2051
|
}
|
|
1858
2052
|
|
|
1859
2053
|
/**
|
|
1860
2054
|
* Frames a piece of data according to the HyBi WebSocket protocol.
|
|
1861
2055
|
*
|
|
1862
|
-
* @param {Buffer} data The data to frame
|
|
2056
|
+
* @param {(Buffer|String)} data The data to frame
|
|
1863
2057
|
* @param {Object} options Options object
|
|
1864
|
-
* @param {Number} options.opcode The opcode
|
|
1865
|
-
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
|
|
1866
|
-
* modified
|
|
1867
2058
|
* @param {Boolean} [options.fin=false] Specifies whether or not to set the
|
|
1868
2059
|
* FIN bit
|
|
2060
|
+
* @param {Function} [options.generateMask] The function used to generate the
|
|
2061
|
+
* masking key
|
|
1869
2062
|
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
|
|
1870
2063
|
* `data`
|
|
2064
|
+
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking
|
|
2065
|
+
* key
|
|
2066
|
+
* @param {Number} options.opcode The opcode
|
|
2067
|
+
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
|
|
2068
|
+
* modified
|
|
1871
2069
|
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
|
|
1872
2070
|
* RSV1 bit
|
|
1873
|
-
* @return {Buffer[]} The framed data
|
|
2071
|
+
* @return {(Buffer|String)[]} The framed data
|
|
1874
2072
|
* @public
|
|
1875
2073
|
*/
|
|
1876
2074
|
static frame(data, options) {
|
|
1877
|
-
|
|
1878
|
-
let
|
|
1879
|
-
let
|
|
2075
|
+
let mask;
|
|
2076
|
+
let merge = false;
|
|
2077
|
+
let offset = 2;
|
|
2078
|
+
let skipMasking = false;
|
|
2079
|
+
|
|
2080
|
+
if (options.mask) {
|
|
2081
|
+
mask = options.maskBuffer || maskBuffer;
|
|
2082
|
+
|
|
2083
|
+
if (options.generateMask) {
|
|
2084
|
+
options.generateMask(mask);
|
|
2085
|
+
} else {
|
|
2086
|
+
if (randomPoolPointer === RANDOM_POOL_SIZE) {
|
|
2087
|
+
/* istanbul ignore else */
|
|
2088
|
+
if (randomPool === undefined) {
|
|
2089
|
+
//
|
|
2090
|
+
// This is lazily initialized because server-sent frames must not
|
|
2091
|
+
// be masked so it may never be used.
|
|
2092
|
+
//
|
|
2093
|
+
randomPool = Buffer.alloc(RANDOM_POOL_SIZE);
|
|
2094
|
+
}
|
|
1880
2095
|
|
|
1881
|
-
|
|
2096
|
+
randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);
|
|
2097
|
+
randomPoolPointer = 0;
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
mask[0] = randomPool[randomPoolPointer++];
|
|
2101
|
+
mask[1] = randomPool[randomPoolPointer++];
|
|
2102
|
+
mask[2] = randomPool[randomPoolPointer++];
|
|
2103
|
+
mask[3] = randomPool[randomPoolPointer++];
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
|
|
2107
|
+
offset = 6;
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
let dataLength;
|
|
2111
|
+
|
|
2112
|
+
if (typeof data === 'string') {
|
|
2113
|
+
if (
|
|
2114
|
+
(!options.mask || skipMasking) &&
|
|
2115
|
+
options[kByteLength] !== undefined
|
|
2116
|
+
) {
|
|
2117
|
+
dataLength = options[kByteLength];
|
|
2118
|
+
} else {
|
|
2119
|
+
data = Buffer.from(data);
|
|
2120
|
+
dataLength = data.length;
|
|
2121
|
+
}
|
|
2122
|
+
} else {
|
|
2123
|
+
dataLength = data.length;
|
|
2124
|
+
merge = options.mask && options.readOnly && !skipMasking;
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
let payloadLength = dataLength;
|
|
2128
|
+
|
|
2129
|
+
if (dataLength >= 65536) {
|
|
1882
2130
|
offset += 8;
|
|
1883
2131
|
payloadLength = 127;
|
|
1884
|
-
} else if (
|
|
2132
|
+
} else if (dataLength > 125) {
|
|
1885
2133
|
offset += 2;
|
|
1886
2134
|
payloadLength = 126;
|
|
1887
2135
|
}
|
|
1888
2136
|
|
|
1889
|
-
const target = Buffer.allocUnsafe(merge ?
|
|
2137
|
+
const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);
|
|
1890
2138
|
|
|
1891
2139
|
target[0] = options.fin ? options.opcode | 0x80 : options.opcode;
|
|
1892
2140
|
if (options.rsv1) target[0] |= 0x40;
|
|
@@ -1894,28 +2142,28 @@ let Sender$1 = class Sender {
|
|
|
1894
2142
|
target[1] = payloadLength;
|
|
1895
2143
|
|
|
1896
2144
|
if (payloadLength === 126) {
|
|
1897
|
-
target.writeUInt16BE(
|
|
2145
|
+
target.writeUInt16BE(dataLength, 2);
|
|
1898
2146
|
} else if (payloadLength === 127) {
|
|
1899
|
-
target
|
|
1900
|
-
target.
|
|
2147
|
+
target[2] = target[3] = 0;
|
|
2148
|
+
target.writeUIntBE(dataLength, 4, 6);
|
|
1901
2149
|
}
|
|
1902
2150
|
|
|
1903
2151
|
if (!options.mask) return [target, data];
|
|
1904
2152
|
|
|
1905
|
-
randomFillSync(mask, 0, 4);
|
|
1906
|
-
|
|
1907
2153
|
target[1] |= 0x80;
|
|
1908
2154
|
target[offset - 4] = mask[0];
|
|
1909
2155
|
target[offset - 3] = mask[1];
|
|
1910
2156
|
target[offset - 2] = mask[2];
|
|
1911
2157
|
target[offset - 1] = mask[3];
|
|
1912
2158
|
|
|
2159
|
+
if (skipMasking) return [target, data];
|
|
2160
|
+
|
|
1913
2161
|
if (merge) {
|
|
1914
|
-
applyMask(data, mask, target, offset,
|
|
2162
|
+
applyMask(data, mask, target, offset, dataLength);
|
|
1915
2163
|
return [target];
|
|
1916
2164
|
}
|
|
1917
2165
|
|
|
1918
|
-
applyMask(data, mask, data, 0,
|
|
2166
|
+
applyMask(data, mask, data, 0, dataLength);
|
|
1919
2167
|
return [target, data];
|
|
1920
2168
|
}
|
|
1921
2169
|
|
|
@@ -1923,7 +2171,7 @@ let Sender$1 = class Sender {
|
|
|
1923
2171
|
* Sends a close message to the other peer.
|
|
1924
2172
|
*
|
|
1925
2173
|
* @param {Number} [code] The status code component of the body
|
|
1926
|
-
* @param {String} [data] The message component of the body
|
|
2174
|
+
* @param {(String|Buffer)} [data] The message component of the body
|
|
1927
2175
|
* @param {Boolean} [mask=false] Specifies whether or not to mask the message
|
|
1928
2176
|
* @param {Function} [cb] Callback
|
|
1929
2177
|
* @public
|
|
@@ -1935,7 +2183,7 @@ let Sender$1 = class Sender {
|
|
|
1935
2183
|
buf = EMPTY_BUFFER$1;
|
|
1936
2184
|
} else if (typeof code !== 'number' || !isValidStatusCode(code)) {
|
|
1937
2185
|
throw new TypeError('First argument must be a valid error code number');
|
|
1938
|
-
} else if (data === undefined || data
|
|
2186
|
+
} else if (data === undefined || !data.length) {
|
|
1939
2187
|
buf = Buffer.allocUnsafe(2);
|
|
1940
2188
|
buf.writeUInt16BE(code, 0);
|
|
1941
2189
|
} else {
|
|
@@ -1947,37 +2195,32 @@ let Sender$1 = class Sender {
|
|
|
1947
2195
|
|
|
1948
2196
|
buf = Buffer.allocUnsafe(2 + length);
|
|
1949
2197
|
buf.writeUInt16BE(code, 0);
|
|
1950
|
-
|
|
2198
|
+
|
|
2199
|
+
if (typeof data === 'string') {
|
|
2200
|
+
buf.write(data, 2);
|
|
2201
|
+
} else {
|
|
2202
|
+
buf.set(data, 2);
|
|
2203
|
+
}
|
|
1951
2204
|
}
|
|
1952
2205
|
|
|
1953
|
-
|
|
1954
|
-
|
|
2206
|
+
const options = {
|
|
2207
|
+
[kByteLength]: buf.length,
|
|
2208
|
+
fin: true,
|
|
2209
|
+
generateMask: this._generateMask,
|
|
2210
|
+
mask,
|
|
2211
|
+
maskBuffer: this._maskBuffer,
|
|
2212
|
+
opcode: 0x08,
|
|
2213
|
+
readOnly: false,
|
|
2214
|
+
rsv1: false
|
|
2215
|
+
};
|
|
2216
|
+
|
|
2217
|
+
if (this._state !== DEFAULT) {
|
|
2218
|
+
this.enqueue([this.dispatch, buf, false, options, cb]);
|
|
1955
2219
|
} else {
|
|
1956
|
-
this.
|
|
2220
|
+
this.sendFrame(Sender.frame(buf, options), cb);
|
|
1957
2221
|
}
|
|
1958
2222
|
}
|
|
1959
2223
|
|
|
1960
|
-
/**
|
|
1961
|
-
* Frames and sends a close message.
|
|
1962
|
-
*
|
|
1963
|
-
* @param {Buffer} data The message to send
|
|
1964
|
-
* @param {Boolean} [mask=false] Specifies whether or not to mask `data`
|
|
1965
|
-
* @param {Function} [cb] Callback
|
|
1966
|
-
* @private
|
|
1967
|
-
*/
|
|
1968
|
-
doClose(data, mask, cb) {
|
|
1969
|
-
this.sendFrame(
|
|
1970
|
-
Sender.frame(data, {
|
|
1971
|
-
fin: true,
|
|
1972
|
-
rsv1: false,
|
|
1973
|
-
opcode: 0x08,
|
|
1974
|
-
mask,
|
|
1975
|
-
readOnly: false
|
|
1976
|
-
}),
|
|
1977
|
-
cb
|
|
1978
|
-
);
|
|
1979
|
-
}
|
|
1980
|
-
|
|
1981
2224
|
/**
|
|
1982
2225
|
* Sends a ping message to the other peer.
|
|
1983
2226
|
*
|
|
@@ -1987,41 +2230,49 @@ let Sender$1 = class Sender {
|
|
|
1987
2230
|
* @public
|
|
1988
2231
|
*/
|
|
1989
2232
|
ping(data, mask, cb) {
|
|
1990
|
-
|
|
2233
|
+
let byteLength;
|
|
2234
|
+
let readOnly;
|
|
2235
|
+
|
|
2236
|
+
if (typeof data === 'string') {
|
|
2237
|
+
byteLength = Buffer.byteLength(data);
|
|
2238
|
+
readOnly = false;
|
|
2239
|
+
} else if (isBlob$1(data)) {
|
|
2240
|
+
byteLength = data.size;
|
|
2241
|
+
readOnly = false;
|
|
2242
|
+
} else {
|
|
2243
|
+
data = toBuffer$1(data);
|
|
2244
|
+
byteLength = data.length;
|
|
2245
|
+
readOnly = toBuffer$1.readOnly;
|
|
2246
|
+
}
|
|
1991
2247
|
|
|
1992
|
-
if (
|
|
2248
|
+
if (byteLength > 125) {
|
|
1993
2249
|
throw new RangeError('The data size must not be greater than 125 bytes');
|
|
1994
2250
|
}
|
|
1995
2251
|
|
|
1996
|
-
|
|
1997
|
-
|
|
2252
|
+
const options = {
|
|
2253
|
+
[kByteLength]: byteLength,
|
|
2254
|
+
fin: true,
|
|
2255
|
+
generateMask: this._generateMask,
|
|
2256
|
+
mask,
|
|
2257
|
+
maskBuffer: this._maskBuffer,
|
|
2258
|
+
opcode: 0x09,
|
|
2259
|
+
readOnly,
|
|
2260
|
+
rsv1: false
|
|
2261
|
+
};
|
|
2262
|
+
|
|
2263
|
+
if (isBlob$1(data)) {
|
|
2264
|
+
if (this._state !== DEFAULT) {
|
|
2265
|
+
this.enqueue([this.getBlobData, data, false, options, cb]);
|
|
2266
|
+
} else {
|
|
2267
|
+
this.getBlobData(data, false, options, cb);
|
|
2268
|
+
}
|
|
2269
|
+
} else if (this._state !== DEFAULT) {
|
|
2270
|
+
this.enqueue([this.dispatch, data, false, options, cb]);
|
|
1998
2271
|
} else {
|
|
1999
|
-
this.
|
|
2272
|
+
this.sendFrame(Sender.frame(data, options), cb);
|
|
2000
2273
|
}
|
|
2001
2274
|
}
|
|
2002
2275
|
|
|
2003
|
-
/**
|
|
2004
|
-
* Frames and sends a ping message.
|
|
2005
|
-
*
|
|
2006
|
-
* @param {Buffer} data The message to send
|
|
2007
|
-
* @param {Boolean} [mask=false] Specifies whether or not to mask `data`
|
|
2008
|
-
* @param {Boolean} [readOnly=false] Specifies whether `data` can be modified
|
|
2009
|
-
* @param {Function} [cb] Callback
|
|
2010
|
-
* @private
|
|
2011
|
-
*/
|
|
2012
|
-
doPing(data, mask, readOnly, cb) {
|
|
2013
|
-
this.sendFrame(
|
|
2014
|
-
Sender.frame(data, {
|
|
2015
|
-
fin: true,
|
|
2016
|
-
rsv1: false,
|
|
2017
|
-
opcode: 0x09,
|
|
2018
|
-
mask,
|
|
2019
|
-
readOnly
|
|
2020
|
-
}),
|
|
2021
|
-
cb
|
|
2022
|
-
);
|
|
2023
|
-
}
|
|
2024
|
-
|
|
2025
2276
|
/**
|
|
2026
2277
|
* Sends a pong message to the other peer.
|
|
2027
2278
|
*
|
|
@@ -2031,50 +2282,58 @@ let Sender$1 = class Sender {
|
|
|
2031
2282
|
* @public
|
|
2032
2283
|
*/
|
|
2033
2284
|
pong(data, mask, cb) {
|
|
2034
|
-
|
|
2285
|
+
let byteLength;
|
|
2286
|
+
let readOnly;
|
|
2287
|
+
|
|
2288
|
+
if (typeof data === 'string') {
|
|
2289
|
+
byteLength = Buffer.byteLength(data);
|
|
2290
|
+
readOnly = false;
|
|
2291
|
+
} else if (isBlob$1(data)) {
|
|
2292
|
+
byteLength = data.size;
|
|
2293
|
+
readOnly = false;
|
|
2294
|
+
} else {
|
|
2295
|
+
data = toBuffer$1(data);
|
|
2296
|
+
byteLength = data.length;
|
|
2297
|
+
readOnly = toBuffer$1.readOnly;
|
|
2298
|
+
}
|
|
2035
2299
|
|
|
2036
|
-
if (
|
|
2300
|
+
if (byteLength > 125) {
|
|
2037
2301
|
throw new RangeError('The data size must not be greater than 125 bytes');
|
|
2038
2302
|
}
|
|
2039
2303
|
|
|
2040
|
-
|
|
2041
|
-
|
|
2304
|
+
const options = {
|
|
2305
|
+
[kByteLength]: byteLength,
|
|
2306
|
+
fin: true,
|
|
2307
|
+
generateMask: this._generateMask,
|
|
2308
|
+
mask,
|
|
2309
|
+
maskBuffer: this._maskBuffer,
|
|
2310
|
+
opcode: 0x0a,
|
|
2311
|
+
readOnly,
|
|
2312
|
+
rsv1: false
|
|
2313
|
+
};
|
|
2314
|
+
|
|
2315
|
+
if (isBlob$1(data)) {
|
|
2316
|
+
if (this._state !== DEFAULT) {
|
|
2317
|
+
this.enqueue([this.getBlobData, data, false, options, cb]);
|
|
2318
|
+
} else {
|
|
2319
|
+
this.getBlobData(data, false, options, cb);
|
|
2320
|
+
}
|
|
2321
|
+
} else if (this._state !== DEFAULT) {
|
|
2322
|
+
this.enqueue([this.dispatch, data, false, options, cb]);
|
|
2042
2323
|
} else {
|
|
2043
|
-
this.
|
|
2324
|
+
this.sendFrame(Sender.frame(data, options), cb);
|
|
2044
2325
|
}
|
|
2045
2326
|
}
|
|
2046
2327
|
|
|
2047
|
-
/**
|
|
2048
|
-
* Frames and sends a pong message.
|
|
2049
|
-
*
|
|
2050
|
-
* @param {Buffer} data The message to send
|
|
2051
|
-
* @param {Boolean} [mask=false] Specifies whether or not to mask `data`
|
|
2052
|
-
* @param {Boolean} [readOnly=false] Specifies whether `data` can be modified
|
|
2053
|
-
* @param {Function} [cb] Callback
|
|
2054
|
-
* @private
|
|
2055
|
-
*/
|
|
2056
|
-
doPong(data, mask, readOnly, cb) {
|
|
2057
|
-
this.sendFrame(
|
|
2058
|
-
Sender.frame(data, {
|
|
2059
|
-
fin: true,
|
|
2060
|
-
rsv1: false,
|
|
2061
|
-
opcode: 0x0a,
|
|
2062
|
-
mask,
|
|
2063
|
-
readOnly
|
|
2064
|
-
}),
|
|
2065
|
-
cb
|
|
2066
|
-
);
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2069
2328
|
/**
|
|
2070
2329
|
* Sends a data message to the other peer.
|
|
2071
2330
|
*
|
|
2072
2331
|
* @param {*} data The message to send
|
|
2073
2332
|
* @param {Object} options Options object
|
|
2074
|
-
* @param {Boolean} [options.compress=false] Specifies whether or not to
|
|
2075
|
-
* compress `data`
|
|
2076
2333
|
* @param {Boolean} [options.binary=false] Specifies whether `data` is binary
|
|
2077
2334
|
* or text
|
|
2335
|
+
* @param {Boolean} [options.compress=false] Specifies whether or not to
|
|
2336
|
+
* compress `data`
|
|
2078
2337
|
* @param {Boolean} [options.fin=false] Specifies whether the fragment is the
|
|
2079
2338
|
* last one
|
|
2080
2339
|
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
|
|
@@ -2083,15 +2342,37 @@ let Sender$1 = class Sender {
|
|
|
2083
2342
|
* @public
|
|
2084
2343
|
*/
|
|
2085
2344
|
send(data, options, cb) {
|
|
2086
|
-
const
|
|
2087
|
-
const perMessageDeflate = this._extensions[PerMessageDeflate$2.extensionName];
|
|
2345
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate$1.extensionName];
|
|
2088
2346
|
let opcode = options.binary ? 2 : 1;
|
|
2089
2347
|
let rsv1 = options.compress;
|
|
2090
2348
|
|
|
2349
|
+
let byteLength;
|
|
2350
|
+
let readOnly;
|
|
2351
|
+
|
|
2352
|
+
if (typeof data === 'string') {
|
|
2353
|
+
byteLength = Buffer.byteLength(data);
|
|
2354
|
+
readOnly = false;
|
|
2355
|
+
} else if (isBlob$1(data)) {
|
|
2356
|
+
byteLength = data.size;
|
|
2357
|
+
readOnly = false;
|
|
2358
|
+
} else {
|
|
2359
|
+
data = toBuffer$1(data);
|
|
2360
|
+
byteLength = data.length;
|
|
2361
|
+
readOnly = toBuffer$1.readOnly;
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2091
2364
|
if (this._firstFragment) {
|
|
2092
2365
|
this._firstFragment = false;
|
|
2093
|
-
if (
|
|
2094
|
-
rsv1
|
|
2366
|
+
if (
|
|
2367
|
+
rsv1 &&
|
|
2368
|
+
perMessageDeflate &&
|
|
2369
|
+
perMessageDeflate.params[
|
|
2370
|
+
perMessageDeflate._isServer
|
|
2371
|
+
? 'server_no_context_takeover'
|
|
2372
|
+
: 'client_no_context_takeover'
|
|
2373
|
+
]
|
|
2374
|
+
) {
|
|
2375
|
+
rsv1 = byteLength >= perMessageDeflate._threshold;
|
|
2095
2376
|
}
|
|
2096
2377
|
this._compress = rsv1;
|
|
2097
2378
|
} else {
|
|
@@ -2101,48 +2382,112 @@ let Sender$1 = class Sender {
|
|
|
2101
2382
|
|
|
2102
2383
|
if (options.fin) this._firstFragment = true;
|
|
2103
2384
|
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2385
|
+
const opts = {
|
|
2386
|
+
[kByteLength]: byteLength,
|
|
2387
|
+
fin: options.fin,
|
|
2388
|
+
generateMask: this._generateMask,
|
|
2389
|
+
mask: options.mask,
|
|
2390
|
+
maskBuffer: this._maskBuffer,
|
|
2391
|
+
opcode,
|
|
2392
|
+
readOnly,
|
|
2393
|
+
rsv1
|
|
2394
|
+
};
|
|
2112
2395
|
|
|
2113
|
-
|
|
2114
|
-
|
|
2396
|
+
if (isBlob$1(data)) {
|
|
2397
|
+
if (this._state !== DEFAULT) {
|
|
2398
|
+
this.enqueue([this.getBlobData, data, this._compress, opts, cb]);
|
|
2115
2399
|
} else {
|
|
2116
|
-
this.
|
|
2400
|
+
this.getBlobData(data, this._compress, opts, cb);
|
|
2117
2401
|
}
|
|
2402
|
+
} else if (this._state !== DEFAULT) {
|
|
2403
|
+
this.enqueue([this.dispatch, data, this._compress, opts, cb]);
|
|
2118
2404
|
} else {
|
|
2119
|
-
this.
|
|
2120
|
-
Sender.frame(buf, {
|
|
2121
|
-
fin: options.fin,
|
|
2122
|
-
rsv1: false,
|
|
2123
|
-
opcode,
|
|
2124
|
-
mask: options.mask,
|
|
2125
|
-
readOnly: toBuffer$1.readOnly
|
|
2126
|
-
}),
|
|
2127
|
-
cb
|
|
2128
|
-
);
|
|
2405
|
+
this.dispatch(data, this._compress, opts, cb);
|
|
2129
2406
|
}
|
|
2130
2407
|
}
|
|
2131
2408
|
|
|
2132
2409
|
/**
|
|
2133
|
-
*
|
|
2410
|
+
* Gets the contents of a blob as binary data.
|
|
2134
2411
|
*
|
|
2135
|
-
* @param {
|
|
2412
|
+
* @param {Blob} blob The blob
|
|
2136
2413
|
* @param {Boolean} [compress=false] Specifies whether or not to compress
|
|
2137
|
-
*
|
|
2414
|
+
* the data
|
|
2138
2415
|
* @param {Object} options Options object
|
|
2416
|
+
* @param {Boolean} [options.fin=false] Specifies whether or not to set the
|
|
2417
|
+
* FIN bit
|
|
2418
|
+
* @param {Function} [options.generateMask] The function used to generate the
|
|
2419
|
+
* masking key
|
|
2420
|
+
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
|
|
2421
|
+
* `data`
|
|
2422
|
+
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking
|
|
2423
|
+
* key
|
|
2139
2424
|
* @param {Number} options.opcode The opcode
|
|
2140
2425
|
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
|
|
2141
2426
|
* modified
|
|
2427
|
+
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
|
|
2428
|
+
* RSV1 bit
|
|
2429
|
+
* @param {Function} [cb] Callback
|
|
2430
|
+
* @private
|
|
2431
|
+
*/
|
|
2432
|
+
getBlobData(blob, compress, options, cb) {
|
|
2433
|
+
this._bufferedBytes += options[kByteLength];
|
|
2434
|
+
this._state = GET_BLOB_DATA;
|
|
2435
|
+
|
|
2436
|
+
blob
|
|
2437
|
+
.arrayBuffer()
|
|
2438
|
+
.then((arrayBuffer) => {
|
|
2439
|
+
if (this._socket.destroyed) {
|
|
2440
|
+
const err = new Error(
|
|
2441
|
+
'The socket was closed while the blob was being read'
|
|
2442
|
+
);
|
|
2443
|
+
|
|
2444
|
+
//
|
|
2445
|
+
// `callCallbacks` is called in the next tick to ensure that errors
|
|
2446
|
+
// that might be thrown in the callbacks behave like errors thrown
|
|
2447
|
+
// outside the promise chain.
|
|
2448
|
+
//
|
|
2449
|
+
process.nextTick(callCallbacks, this, err, cb);
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2453
|
+
this._bufferedBytes -= options[kByteLength];
|
|
2454
|
+
const data = toBuffer$1(arrayBuffer);
|
|
2455
|
+
|
|
2456
|
+
if (!compress) {
|
|
2457
|
+
this._state = DEFAULT;
|
|
2458
|
+
this.sendFrame(Sender.frame(data, options), cb);
|
|
2459
|
+
this.dequeue();
|
|
2460
|
+
} else {
|
|
2461
|
+
this.dispatch(data, compress, options, cb);
|
|
2462
|
+
}
|
|
2463
|
+
})
|
|
2464
|
+
.catch((err) => {
|
|
2465
|
+
//
|
|
2466
|
+
// `onError` is called in the next tick for the same reason that
|
|
2467
|
+
// `callCallbacks` above is.
|
|
2468
|
+
//
|
|
2469
|
+
process.nextTick(onError, this, err, cb);
|
|
2470
|
+
});
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
/**
|
|
2474
|
+
* Dispatches a message.
|
|
2475
|
+
*
|
|
2476
|
+
* @param {(Buffer|String)} data The message to send
|
|
2477
|
+
* @param {Boolean} [compress=false] Specifies whether or not to compress
|
|
2478
|
+
* `data`
|
|
2479
|
+
* @param {Object} options Options object
|
|
2142
2480
|
* @param {Boolean} [options.fin=false] Specifies whether or not to set the
|
|
2143
2481
|
* FIN bit
|
|
2482
|
+
* @param {Function} [options.generateMask] The function used to generate the
|
|
2483
|
+
* masking key
|
|
2144
2484
|
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
|
|
2145
2485
|
* `data`
|
|
2486
|
+
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking
|
|
2487
|
+
* key
|
|
2488
|
+
* @param {Number} options.opcode The opcode
|
|
2489
|
+
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
|
|
2490
|
+
* modified
|
|
2146
2491
|
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
|
|
2147
2492
|
* RSV1 bit
|
|
2148
2493
|
* @param {Function} [cb] Callback
|
|
@@ -2154,29 +2499,22 @@ let Sender$1 = class Sender {
|
|
|
2154
2499
|
return;
|
|
2155
2500
|
}
|
|
2156
2501
|
|
|
2157
|
-
const perMessageDeflate = this._extensions[PerMessageDeflate$
|
|
2502
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate$1.extensionName];
|
|
2158
2503
|
|
|
2159
|
-
this._bufferedBytes +=
|
|
2160
|
-
this.
|
|
2504
|
+
this._bufferedBytes += options[kByteLength];
|
|
2505
|
+
this._state = DEFLATING;
|
|
2161
2506
|
perMessageDeflate.compress(data, options.fin, (_, buf) => {
|
|
2162
2507
|
if (this._socket.destroyed) {
|
|
2163
2508
|
const err = new Error(
|
|
2164
2509
|
'The socket was closed while data was being compressed'
|
|
2165
2510
|
);
|
|
2166
2511
|
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
for (let i = 0; i < this._queue.length; i++) {
|
|
2170
|
-
const callback = this._queue[i][4];
|
|
2171
|
-
|
|
2172
|
-
if (typeof callback === 'function') callback(err);
|
|
2173
|
-
}
|
|
2174
|
-
|
|
2512
|
+
callCallbacks(this, err, cb);
|
|
2175
2513
|
return;
|
|
2176
2514
|
}
|
|
2177
2515
|
|
|
2178
|
-
this._bufferedBytes -=
|
|
2179
|
-
this.
|
|
2516
|
+
this._bufferedBytes -= options[kByteLength];
|
|
2517
|
+
this._state = DEFAULT;
|
|
2180
2518
|
options.readOnly = false;
|
|
2181
2519
|
this.sendFrame(Sender.frame(buf, options), cb);
|
|
2182
2520
|
this.dequeue();
|
|
@@ -2189,10 +2527,10 @@ let Sender$1 = class Sender {
|
|
|
2189
2527
|
* @private
|
|
2190
2528
|
*/
|
|
2191
2529
|
dequeue() {
|
|
2192
|
-
while (
|
|
2530
|
+
while (this._state === DEFAULT && this._queue.length) {
|
|
2193
2531
|
const params = this._queue.shift();
|
|
2194
2532
|
|
|
2195
|
-
this._bufferedBytes -= params[
|
|
2533
|
+
this._bufferedBytes -= params[3][kByteLength];
|
|
2196
2534
|
Reflect.apply(params[0], this, params.slice(1));
|
|
2197
2535
|
}
|
|
2198
2536
|
}
|
|
@@ -2204,14 +2542,14 @@ let Sender$1 = class Sender {
|
|
|
2204
2542
|
* @private
|
|
2205
2543
|
*/
|
|
2206
2544
|
enqueue(params) {
|
|
2207
|
-
this._bufferedBytes += params[
|
|
2545
|
+
this._bufferedBytes += params[3][kByteLength];
|
|
2208
2546
|
this._queue.push(params);
|
|
2209
2547
|
}
|
|
2210
2548
|
|
|
2211
2549
|
/**
|
|
2212
2550
|
* Sends a frame.
|
|
2213
2551
|
*
|
|
2214
|
-
* @param {Buffer[]} list The frame to send
|
|
2552
|
+
* @param {(Buffer | String)[]} list The frame to send
|
|
2215
2553
|
* @param {Function} [cb] Callback
|
|
2216
2554
|
* @private
|
|
2217
2555
|
*/
|
|
@@ -2230,111 +2568,204 @@ let Sender$1 = class Sender {
|
|
|
2230
2568
|
var sender = Sender$1;
|
|
2231
2569
|
|
|
2232
2570
|
/**
|
|
2233
|
-
*
|
|
2571
|
+
* Calls queued callbacks with an error.
|
|
2234
2572
|
*
|
|
2573
|
+
* @param {Sender} sender The `Sender` instance
|
|
2574
|
+
* @param {Error} err The error to call the callbacks with
|
|
2575
|
+
* @param {Function} [cb] The first callback
|
|
2235
2576
|
* @private
|
|
2236
2577
|
*/
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
constructor(type, target) {
|
|
2246
|
-
this.target = target;
|
|
2247
|
-
this.type = type;
|
|
2578
|
+
function callCallbacks(sender, err, cb) {
|
|
2579
|
+
if (typeof cb === 'function') cb(err);
|
|
2580
|
+
|
|
2581
|
+
for (let i = 0; i < sender._queue.length; i++) {
|
|
2582
|
+
const params = sender._queue[i];
|
|
2583
|
+
const callback = params[params.length - 1];
|
|
2584
|
+
|
|
2585
|
+
if (typeof callback === 'function') callback(err);
|
|
2248
2586
|
}
|
|
2249
2587
|
}
|
|
2250
2588
|
|
|
2251
2589
|
/**
|
|
2252
|
-
*
|
|
2590
|
+
* Handles a `Sender` error.
|
|
2253
2591
|
*
|
|
2254
|
-
* @
|
|
2592
|
+
* @param {Sender} sender The `Sender` instance
|
|
2593
|
+
* @param {Error} err The error
|
|
2594
|
+
* @param {Function} [cb] The first pending callback
|
|
2255
2595
|
* @private
|
|
2256
2596
|
*/
|
|
2257
|
-
|
|
2597
|
+
function onError(sender, err, cb) {
|
|
2598
|
+
callCallbacks(sender, err, cb);
|
|
2599
|
+
sender.onerror(err);
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
const { kForOnEventAttribute: kForOnEventAttribute$1, kListener: kListener$1 } = constants;
|
|
2603
|
+
|
|
2604
|
+
const kCode = Symbol('kCode');
|
|
2605
|
+
const kData = Symbol('kData');
|
|
2606
|
+
const kError = Symbol('kError');
|
|
2607
|
+
const kMessage = Symbol('kMessage');
|
|
2608
|
+
const kReason = Symbol('kReason');
|
|
2609
|
+
const kTarget = Symbol('kTarget');
|
|
2610
|
+
const kType = Symbol('kType');
|
|
2611
|
+
const kWasClean = Symbol('kWasClean');
|
|
2612
|
+
|
|
2613
|
+
/**
|
|
2614
|
+
* Class representing an event.
|
|
2615
|
+
*/
|
|
2616
|
+
class Event {
|
|
2258
2617
|
/**
|
|
2259
|
-
* Create a new `
|
|
2618
|
+
* Create a new `Event`.
|
|
2260
2619
|
*
|
|
2261
|
-
* @param {
|
|
2262
|
-
* @
|
|
2263
|
-
|
|
2620
|
+
* @param {String} type The name of the event
|
|
2621
|
+
* @throws {TypeError} If the `type` argument is not specified
|
|
2622
|
+
*/
|
|
2623
|
+
constructor(type) {
|
|
2624
|
+
this[kTarget] = null;
|
|
2625
|
+
this[kType] = type;
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2628
|
+
/**
|
|
2629
|
+
* @type {*}
|
|
2264
2630
|
*/
|
|
2265
|
-
|
|
2266
|
-
|
|
2631
|
+
get target() {
|
|
2632
|
+
return this[kTarget];
|
|
2633
|
+
}
|
|
2267
2634
|
|
|
2268
|
-
|
|
2635
|
+
/**
|
|
2636
|
+
* @type {String}
|
|
2637
|
+
*/
|
|
2638
|
+
get type() {
|
|
2639
|
+
return this[kType];
|
|
2269
2640
|
}
|
|
2270
2641
|
}
|
|
2271
2642
|
|
|
2643
|
+
Object.defineProperty(Event.prototype, 'target', { enumerable: true });
|
|
2644
|
+
Object.defineProperty(Event.prototype, 'type', { enumerable: true });
|
|
2645
|
+
|
|
2272
2646
|
/**
|
|
2273
2647
|
* Class representing a close event.
|
|
2274
2648
|
*
|
|
2275
2649
|
* @extends Event
|
|
2276
|
-
* @private
|
|
2277
2650
|
*/
|
|
2278
2651
|
class CloseEvent extends Event {
|
|
2279
2652
|
/**
|
|
2280
2653
|
* Create a new `CloseEvent`.
|
|
2281
2654
|
*
|
|
2282
|
-
* @param {
|
|
2283
|
-
*
|
|
2284
|
-
*
|
|
2285
|
-
*
|
|
2286
|
-
*
|
|
2287
|
-
*
|
|
2655
|
+
* @param {String} type The name of the event
|
|
2656
|
+
* @param {Object} [options] A dictionary object that allows for setting
|
|
2657
|
+
* attributes via object members of the same name
|
|
2658
|
+
* @param {Number} [options.code=0] The status code explaining why the
|
|
2659
|
+
* connection was closed
|
|
2660
|
+
* @param {String} [options.reason=''] A human-readable string explaining why
|
|
2661
|
+
* the connection was closed
|
|
2662
|
+
* @param {Boolean} [options.wasClean=false] Indicates whether or not the
|
|
2663
|
+
* connection was cleanly closed
|
|
2664
|
+
*/
|
|
2665
|
+
constructor(type, options = {}) {
|
|
2666
|
+
super(type);
|
|
2667
|
+
|
|
2668
|
+
this[kCode] = options.code === undefined ? 0 : options.code;
|
|
2669
|
+
this[kReason] = options.reason === undefined ? '' : options.reason;
|
|
2670
|
+
this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
/**
|
|
2674
|
+
* @type {Number}
|
|
2675
|
+
*/
|
|
2676
|
+
get code() {
|
|
2677
|
+
return this[kCode];
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
/**
|
|
2681
|
+
* @type {String}
|
|
2288
2682
|
*/
|
|
2289
|
-
|
|
2290
|
-
|
|
2683
|
+
get reason() {
|
|
2684
|
+
return this[kReason];
|
|
2685
|
+
}
|
|
2291
2686
|
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2687
|
+
/**
|
|
2688
|
+
* @type {Boolean}
|
|
2689
|
+
*/
|
|
2690
|
+
get wasClean() {
|
|
2691
|
+
return this[kWasClean];
|
|
2295
2692
|
}
|
|
2296
2693
|
}
|
|
2297
2694
|
|
|
2695
|
+
Object.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });
|
|
2696
|
+
Object.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });
|
|
2697
|
+
Object.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });
|
|
2698
|
+
|
|
2298
2699
|
/**
|
|
2299
|
-
* Class representing an
|
|
2700
|
+
* Class representing an error event.
|
|
2300
2701
|
*
|
|
2301
2702
|
* @extends Event
|
|
2302
|
-
* @private
|
|
2303
2703
|
*/
|
|
2304
|
-
class
|
|
2704
|
+
class ErrorEvent extends Event {
|
|
2305
2705
|
/**
|
|
2306
|
-
* Create a new `
|
|
2706
|
+
* Create a new `ErrorEvent`.
|
|
2307
2707
|
*
|
|
2308
|
-
* @param {
|
|
2309
|
-
*
|
|
2708
|
+
* @param {String} type The name of the event
|
|
2709
|
+
* @param {Object} [options] A dictionary object that allows for setting
|
|
2710
|
+
* attributes via object members of the same name
|
|
2711
|
+
* @param {*} [options.error=null] The error that generated this event
|
|
2712
|
+
* @param {String} [options.message=''] The error message
|
|
2713
|
+
*/
|
|
2714
|
+
constructor(type, options = {}) {
|
|
2715
|
+
super(type);
|
|
2716
|
+
|
|
2717
|
+
this[kError] = options.error === undefined ? null : options.error;
|
|
2718
|
+
this[kMessage] = options.message === undefined ? '' : options.message;
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
/**
|
|
2722
|
+
* @type {*}
|
|
2723
|
+
*/
|
|
2724
|
+
get error() {
|
|
2725
|
+
return this[kError];
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
/**
|
|
2729
|
+
* @type {String}
|
|
2310
2730
|
*/
|
|
2311
|
-
|
|
2312
|
-
|
|
2731
|
+
get message() {
|
|
2732
|
+
return this[kMessage];
|
|
2313
2733
|
}
|
|
2314
2734
|
}
|
|
2315
2735
|
|
|
2736
|
+
Object.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });
|
|
2737
|
+
Object.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });
|
|
2738
|
+
|
|
2316
2739
|
/**
|
|
2317
|
-
* Class representing
|
|
2740
|
+
* Class representing a message event.
|
|
2318
2741
|
*
|
|
2319
2742
|
* @extends Event
|
|
2320
|
-
* @private
|
|
2321
2743
|
*/
|
|
2322
|
-
class
|
|
2744
|
+
class MessageEvent extends Event {
|
|
2323
2745
|
/**
|
|
2324
|
-
* Create a new `
|
|
2746
|
+
* Create a new `MessageEvent`.
|
|
2325
2747
|
*
|
|
2326
|
-
* @param {
|
|
2327
|
-
* @param {
|
|
2328
|
-
*
|
|
2748
|
+
* @param {String} type The name of the event
|
|
2749
|
+
* @param {Object} [options] A dictionary object that allows for setting
|
|
2750
|
+
* attributes via object members of the same name
|
|
2751
|
+
* @param {*} [options.data=null] The message content
|
|
2329
2752
|
*/
|
|
2330
|
-
constructor(
|
|
2331
|
-
super(
|
|
2753
|
+
constructor(type, options = {}) {
|
|
2754
|
+
super(type);
|
|
2332
2755
|
|
|
2333
|
-
this
|
|
2334
|
-
|
|
2756
|
+
this[kData] = options.data === undefined ? null : options.data;
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2759
|
+
/**
|
|
2760
|
+
* @type {*}
|
|
2761
|
+
*/
|
|
2762
|
+
get data() {
|
|
2763
|
+
return this[kData];
|
|
2335
2764
|
}
|
|
2336
2765
|
}
|
|
2337
2766
|
|
|
2767
|
+
Object.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });
|
|
2768
|
+
|
|
2338
2769
|
/**
|
|
2339
2770
|
* This provides methods for emulating the `EventTarget` interface. It's not
|
|
2340
2771
|
* meant to be used directly.
|
|
@@ -2346,49 +2777,75 @@ const EventTarget = {
|
|
|
2346
2777
|
* Register an event listener.
|
|
2347
2778
|
*
|
|
2348
2779
|
* @param {String} type A string representing the event type to listen for
|
|
2349
|
-
* @param {Function}
|
|
2780
|
+
* @param {(Function|Object)} handler The listener to add
|
|
2350
2781
|
* @param {Object} [options] An options object specifies characteristics about
|
|
2351
2782
|
* the event listener
|
|
2352
|
-
* @param {Boolean} [options.once=false] A `Boolean
|
|
2783
|
+
* @param {Boolean} [options.once=false] A `Boolean` indicating that the
|
|
2353
2784
|
* listener should be invoked at most once after being added. If `true`,
|
|
2354
2785
|
* the listener would be automatically removed when invoked.
|
|
2355
2786
|
* @public
|
|
2356
2787
|
*/
|
|
2357
|
-
addEventListener(type,
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
}
|
|
2367
|
-
|
|
2368
|
-
function onError(error) {
|
|
2369
|
-
listener.call(this, new ErrorEvent(error, this));
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
function onOpen() {
|
|
2373
|
-
listener.call(this, new OpenEvent(this));
|
|
2788
|
+
addEventListener(type, handler, options = {}) {
|
|
2789
|
+
for (const listener of this.listeners(type)) {
|
|
2790
|
+
if (
|
|
2791
|
+
!options[kForOnEventAttribute$1] &&
|
|
2792
|
+
listener[kListener$1] === handler &&
|
|
2793
|
+
!listener[kForOnEventAttribute$1]
|
|
2794
|
+
) {
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2374
2797
|
}
|
|
2375
2798
|
|
|
2376
|
-
|
|
2799
|
+
let wrapper;
|
|
2377
2800
|
|
|
2378
2801
|
if (type === 'message') {
|
|
2379
|
-
|
|
2380
|
-
|
|
2802
|
+
wrapper = function onMessage(data, isBinary) {
|
|
2803
|
+
const event = new MessageEvent('message', {
|
|
2804
|
+
data: isBinary ? data : data.toString()
|
|
2805
|
+
});
|
|
2806
|
+
|
|
2807
|
+
event[kTarget] = this;
|
|
2808
|
+
callListener(handler, this, event);
|
|
2809
|
+
};
|
|
2381
2810
|
} else if (type === 'close') {
|
|
2382
|
-
|
|
2383
|
-
|
|
2811
|
+
wrapper = function onClose(code, message) {
|
|
2812
|
+
const event = new CloseEvent('close', {
|
|
2813
|
+
code,
|
|
2814
|
+
reason: message.toString(),
|
|
2815
|
+
wasClean: this._closeFrameReceived && this._closeFrameSent
|
|
2816
|
+
});
|
|
2817
|
+
|
|
2818
|
+
event[kTarget] = this;
|
|
2819
|
+
callListener(handler, this, event);
|
|
2820
|
+
};
|
|
2384
2821
|
} else if (type === 'error') {
|
|
2385
|
-
|
|
2386
|
-
|
|
2822
|
+
wrapper = function onError(error) {
|
|
2823
|
+
const event = new ErrorEvent('error', {
|
|
2824
|
+
error,
|
|
2825
|
+
message: error.message
|
|
2826
|
+
});
|
|
2827
|
+
|
|
2828
|
+
event[kTarget] = this;
|
|
2829
|
+
callListener(handler, this, event);
|
|
2830
|
+
};
|
|
2387
2831
|
} else if (type === 'open') {
|
|
2388
|
-
|
|
2389
|
-
|
|
2832
|
+
wrapper = function onOpen() {
|
|
2833
|
+
const event = new Event('open');
|
|
2834
|
+
|
|
2835
|
+
event[kTarget] = this;
|
|
2836
|
+
callListener(handler, this, event);
|
|
2837
|
+
};
|
|
2838
|
+
} else {
|
|
2839
|
+
return;
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
wrapper[kForOnEventAttribute$1] = !!options[kForOnEventAttribute$1];
|
|
2843
|
+
wrapper[kListener$1] = handler;
|
|
2844
|
+
|
|
2845
|
+
if (options.once) {
|
|
2846
|
+
this.once(type, wrapper);
|
|
2390
2847
|
} else {
|
|
2391
|
-
this
|
|
2848
|
+
this.on(type, wrapper);
|
|
2392
2849
|
}
|
|
2393
2850
|
},
|
|
2394
2851
|
|
|
@@ -2396,44 +2853,39 @@ const EventTarget = {
|
|
|
2396
2853
|
* Remove an event listener.
|
|
2397
2854
|
*
|
|
2398
2855
|
* @param {String} type A string representing the event type to remove
|
|
2399
|
-
* @param {Function}
|
|
2856
|
+
* @param {(Function|Object)} handler The listener to remove
|
|
2400
2857
|
* @public
|
|
2401
2858
|
*/
|
|
2402
|
-
removeEventListener(type,
|
|
2403
|
-
const
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
this.removeListener(type, listeners[i]);
|
|
2859
|
+
removeEventListener(type, handler) {
|
|
2860
|
+
for (const listener of this.listeners(type)) {
|
|
2861
|
+
if (listener[kListener$1] === handler && !listener[kForOnEventAttribute$1]) {
|
|
2862
|
+
this.removeListener(type, listener);
|
|
2863
|
+
break;
|
|
2408
2864
|
}
|
|
2409
2865
|
}
|
|
2410
2866
|
}
|
|
2411
2867
|
};
|
|
2412
2868
|
|
|
2413
|
-
var eventTarget =
|
|
2869
|
+
var eventTarget = {
|
|
2870
|
+
EventTarget};
|
|
2414
2871
|
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
|
|
2433
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95
|
|
2434
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
|
|
2435
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127
|
|
2436
|
-
];
|
|
2872
|
+
/**
|
|
2873
|
+
* Call an event listener
|
|
2874
|
+
*
|
|
2875
|
+
* @param {(Function|Object)} listener The listener to call
|
|
2876
|
+
* @param {*} thisArg The value to use as `this`` when calling the listener
|
|
2877
|
+
* @param {Event} event The event to pass to the listener
|
|
2878
|
+
* @private
|
|
2879
|
+
*/
|
|
2880
|
+
function callListener(listener, thisArg, event) {
|
|
2881
|
+
if (typeof listener === 'object' && listener.handleEvent) {
|
|
2882
|
+
listener.handleEvent.call(listener, event);
|
|
2883
|
+
} else {
|
|
2884
|
+
listener.call(thisArg, event);
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
const { tokenChars: tokenChars$1 } = validationExports;
|
|
2437
2889
|
|
|
2438
2890
|
/**
|
|
2439
2891
|
* Adds an offer to the map of extension offers or a parameter to the map of
|
|
@@ -2457,11 +2909,8 @@ function push(dest, name, elem) {
|
|
|
2457
2909
|
* @return {Object} The parsed object
|
|
2458
2910
|
* @public
|
|
2459
2911
|
*/
|
|
2460
|
-
function parse$
|
|
2912
|
+
function parse$1(header) {
|
|
2461
2913
|
const offers = Object.create(null);
|
|
2462
|
-
|
|
2463
|
-
if (header === undefined || header === '') return offers;
|
|
2464
|
-
|
|
2465
2914
|
let params = Object.create(null);
|
|
2466
2915
|
let mustUnescape = false;
|
|
2467
2916
|
let isEscaping = false;
|
|
@@ -2469,16 +2918,20 @@ function parse$2(header) {
|
|
|
2469
2918
|
let extensionName;
|
|
2470
2919
|
let paramName;
|
|
2471
2920
|
let start = -1;
|
|
2921
|
+
let code = -1;
|
|
2472
2922
|
let end = -1;
|
|
2473
2923
|
let i = 0;
|
|
2474
2924
|
|
|
2475
2925
|
for (; i < header.length; i++) {
|
|
2476
|
-
|
|
2926
|
+
code = header.charCodeAt(i);
|
|
2477
2927
|
|
|
2478
2928
|
if (extensionName === undefined) {
|
|
2479
|
-
if (end === -1 && tokenChars[code] === 1) {
|
|
2929
|
+
if (end === -1 && tokenChars$1[code] === 1) {
|
|
2480
2930
|
if (start === -1) start = i;
|
|
2481
|
-
} else if (
|
|
2931
|
+
} else if (
|
|
2932
|
+
i !== 0 &&
|
|
2933
|
+
(code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */
|
|
2934
|
+
) {
|
|
2482
2935
|
if (end === -1 && start !== -1) end = i;
|
|
2483
2936
|
} else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {
|
|
2484
2937
|
if (start === -1) {
|
|
@@ -2499,7 +2952,7 @@ function parse$2(header) {
|
|
|
2499
2952
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
2500
2953
|
}
|
|
2501
2954
|
} else if (paramName === undefined) {
|
|
2502
|
-
if (end === -1 && tokenChars[code] === 1) {
|
|
2955
|
+
if (end === -1 && tokenChars$1[code] === 1) {
|
|
2503
2956
|
if (start === -1) start = i;
|
|
2504
2957
|
} else if (code === 0x20 || code === 0x09) {
|
|
2505
2958
|
if (end === -1 && start !== -1) end = i;
|
|
@@ -2530,14 +2983,14 @@ function parse$2(header) {
|
|
|
2530
2983
|
// Ref: https://tools.ietf.org/html/rfc6455#section-9.1
|
|
2531
2984
|
//
|
|
2532
2985
|
if (isEscaping) {
|
|
2533
|
-
if (tokenChars[code] !== 1) {
|
|
2986
|
+
if (tokenChars$1[code] !== 1) {
|
|
2534
2987
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
2535
2988
|
}
|
|
2536
2989
|
if (start === -1) start = i;
|
|
2537
2990
|
else if (!mustUnescape) mustUnescape = true;
|
|
2538
2991
|
isEscaping = false;
|
|
2539
2992
|
} else if (inQuotes) {
|
|
2540
|
-
if (tokenChars[code] === 1) {
|
|
2993
|
+
if (tokenChars$1[code] === 1) {
|
|
2541
2994
|
if (start === -1) start = i;
|
|
2542
2995
|
} else if (code === 0x22 /* '"' */ && start !== -1) {
|
|
2543
2996
|
inQuotes = false;
|
|
@@ -2549,7 +3002,7 @@ function parse$2(header) {
|
|
|
2549
3002
|
}
|
|
2550
3003
|
} else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {
|
|
2551
3004
|
inQuotes = true;
|
|
2552
|
-
} else if (end === -1 && tokenChars[code] === 1) {
|
|
3005
|
+
} else if (end === -1 && tokenChars$1[code] === 1) {
|
|
2553
3006
|
if (start === -1) start = i;
|
|
2554
3007
|
} else if (start !== -1 && (code === 0x20 || code === 0x09)) {
|
|
2555
3008
|
if (end === -1) end = i;
|
|
@@ -2579,7 +3032,7 @@ function parse$2(header) {
|
|
|
2579
3032
|
}
|
|
2580
3033
|
}
|
|
2581
3034
|
|
|
2582
|
-
if (start === -1 || inQuotes) {
|
|
3035
|
+
if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {
|
|
2583
3036
|
throw new SyntaxError('Unexpected end of input');
|
|
2584
3037
|
}
|
|
2585
3038
|
|
|
@@ -2608,7 +3061,7 @@ function parse$2(header) {
|
|
|
2608
3061
|
* @return {String} A string representing the given object
|
|
2609
3062
|
* @public
|
|
2610
3063
|
*/
|
|
2611
|
-
function format$
|
|
3064
|
+
function format$1(extensions) {
|
|
2612
3065
|
return Object.keys(extensions)
|
|
2613
3066
|
.map((extension) => {
|
|
2614
3067
|
let configurations = extensions[extension];
|
|
@@ -2632,44 +3085,52 @@ function format$2(extensions) {
|
|
|
2632
3085
|
.join(', ');
|
|
2633
3086
|
}
|
|
2634
3087
|
|
|
2635
|
-
var extension = { format: format$
|
|
3088
|
+
var extension = { format: format$1, parse: parse$1 };
|
|
2636
3089
|
|
|
2637
|
-
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Readable$" }] */
|
|
3090
|
+
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$", "caughtErrors": "none" }] */
|
|
2638
3091
|
|
|
2639
|
-
const EventEmitter
|
|
2640
|
-
const https = require$$1$
|
|
2641
|
-
const http
|
|
3092
|
+
const EventEmitter = require$$0$4;
|
|
3093
|
+
const https = require$$1$2;
|
|
3094
|
+
const http = require$$2$1;
|
|
2642
3095
|
const net = require$$3;
|
|
2643
3096
|
const tls = require$$4;
|
|
2644
|
-
const { randomBytes, createHash: createHash$1 } = require$$
|
|
2645
|
-
const { Readable } = require$$0$
|
|
3097
|
+
const { randomBytes, createHash: createHash$1 } = require$$1$1;
|
|
3098
|
+
const { Duplex: Duplex$2, Readable } = require$$0$3;
|
|
2646
3099
|
const { URL } = require$$7;
|
|
2647
3100
|
|
|
2648
|
-
const PerMessageDeflate
|
|
3101
|
+
const PerMessageDeflate = permessageDeflate;
|
|
2649
3102
|
const Receiver = receiver;
|
|
2650
3103
|
const Sender = sender;
|
|
3104
|
+
const { isBlob } = validationExports;
|
|
3105
|
+
|
|
2651
3106
|
const {
|
|
2652
3107
|
BINARY_TYPES,
|
|
3108
|
+
CLOSE_TIMEOUT: CLOSE_TIMEOUT$1,
|
|
2653
3109
|
EMPTY_BUFFER,
|
|
2654
3110
|
GUID: GUID$1,
|
|
3111
|
+
kForOnEventAttribute,
|
|
3112
|
+
kListener,
|
|
2655
3113
|
kStatusCode,
|
|
2656
3114
|
kWebSocket: kWebSocket$1,
|
|
2657
3115
|
NOOP
|
|
2658
3116
|
} = constants;
|
|
2659
|
-
const {
|
|
2660
|
-
|
|
3117
|
+
const {
|
|
3118
|
+
EventTarget: { addEventListener, removeEventListener }
|
|
3119
|
+
} = eventTarget;
|
|
3120
|
+
const { format, parse } = extension;
|
|
2661
3121
|
const { toBuffer } = bufferUtilExports;
|
|
2662
3122
|
|
|
2663
|
-
const
|
|
3123
|
+
const kAborted = Symbol('kAborted');
|
|
2664
3124
|
const protocolVersions = [8, 13];
|
|
2665
|
-
const
|
|
3125
|
+
const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
|
|
3126
|
+
const subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
|
|
2666
3127
|
|
|
2667
3128
|
/**
|
|
2668
3129
|
* Class representing a WebSocket.
|
|
2669
3130
|
*
|
|
2670
3131
|
* @extends EventEmitter
|
|
2671
3132
|
*/
|
|
2672
|
-
let WebSocket$
|
|
3133
|
+
let WebSocket$1 = class WebSocket extends EventEmitter {
|
|
2673
3134
|
/**
|
|
2674
3135
|
* Create a new `WebSocket`.
|
|
2675
3136
|
*
|
|
@@ -2684,9 +3145,11 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
2684
3145
|
this._closeCode = 1006;
|
|
2685
3146
|
this._closeFrameReceived = false;
|
|
2686
3147
|
this._closeFrameSent = false;
|
|
2687
|
-
this._closeMessage =
|
|
3148
|
+
this._closeMessage = EMPTY_BUFFER;
|
|
2688
3149
|
this._closeTimer = null;
|
|
3150
|
+
this._errorEmitted = false;
|
|
2689
3151
|
this._extensions = {};
|
|
3152
|
+
this._paused = false;
|
|
2690
3153
|
this._protocol = '';
|
|
2691
3154
|
this._readyState = WebSocket.CONNECTING;
|
|
2692
3155
|
this._receiver = null;
|
|
@@ -2698,23 +3161,28 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
2698
3161
|
this._isServer = false;
|
|
2699
3162
|
this._redirects = 0;
|
|
2700
3163
|
|
|
2701
|
-
if (
|
|
2702
|
-
protocols =
|
|
2703
|
-
} else if (
|
|
2704
|
-
|
|
2705
|
-
|
|
3164
|
+
if (protocols === undefined) {
|
|
3165
|
+
protocols = [];
|
|
3166
|
+
} else if (!Array.isArray(protocols)) {
|
|
3167
|
+
if (typeof protocols === 'object' && protocols !== null) {
|
|
3168
|
+
options = protocols;
|
|
3169
|
+
protocols = [];
|
|
3170
|
+
} else {
|
|
3171
|
+
protocols = [protocols];
|
|
3172
|
+
}
|
|
2706
3173
|
}
|
|
2707
3174
|
|
|
2708
3175
|
initAsClient(this, address, protocols, options);
|
|
2709
3176
|
} else {
|
|
3177
|
+
this._autoPong = options.autoPong;
|
|
3178
|
+
this._closeTimeout = options.closeTimeout;
|
|
2710
3179
|
this._isServer = true;
|
|
2711
3180
|
}
|
|
2712
3181
|
}
|
|
2713
3182
|
|
|
2714
3183
|
/**
|
|
2715
|
-
*
|
|
2716
|
-
*
|
|
2717
|
-
* type).
|
|
3184
|
+
* For historical reasons, the custom "nodebuffer" type is used by the default
|
|
3185
|
+
* instead of "blob".
|
|
2718
3186
|
*
|
|
2719
3187
|
* @type {String}
|
|
2720
3188
|
*/
|
|
@@ -2750,49 +3218,44 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
2750
3218
|
}
|
|
2751
3219
|
|
|
2752
3220
|
/**
|
|
2753
|
-
* @type {
|
|
3221
|
+
* @type {Boolean}
|
|
2754
3222
|
*/
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
return undefined;
|
|
3223
|
+
get isPaused() {
|
|
3224
|
+
return this._paused;
|
|
2758
3225
|
}
|
|
2759
3226
|
|
|
2760
|
-
/* istanbul ignore next */
|
|
2761
|
-
set onclose(listener) {}
|
|
2762
|
-
|
|
2763
3227
|
/**
|
|
2764
3228
|
* @type {Function}
|
|
2765
3229
|
*/
|
|
2766
3230
|
/* istanbul ignore next */
|
|
2767
|
-
get
|
|
2768
|
-
return
|
|
3231
|
+
get onclose() {
|
|
3232
|
+
return null;
|
|
2769
3233
|
}
|
|
2770
3234
|
|
|
3235
|
+
/**
|
|
3236
|
+
* @type {Function}
|
|
3237
|
+
*/
|
|
2771
3238
|
/* istanbul ignore next */
|
|
2772
|
-
|
|
3239
|
+
get onerror() {
|
|
3240
|
+
return null;
|
|
3241
|
+
}
|
|
2773
3242
|
|
|
2774
3243
|
/**
|
|
2775
3244
|
* @type {Function}
|
|
2776
3245
|
*/
|
|
2777
3246
|
/* istanbul ignore next */
|
|
2778
3247
|
get onopen() {
|
|
2779
|
-
return
|
|
3248
|
+
return null;
|
|
2780
3249
|
}
|
|
2781
3250
|
|
|
2782
|
-
/* istanbul ignore next */
|
|
2783
|
-
set onopen(listener) {}
|
|
2784
|
-
|
|
2785
3251
|
/**
|
|
2786
3252
|
* @type {Function}
|
|
2787
3253
|
*/
|
|
2788
3254
|
/* istanbul ignore next */
|
|
2789
3255
|
get onmessage() {
|
|
2790
|
-
return
|
|
3256
|
+
return null;
|
|
2791
3257
|
}
|
|
2792
3258
|
|
|
2793
|
-
/* istanbul ignore next */
|
|
2794
|
-
set onmessage(listener) {}
|
|
2795
|
-
|
|
2796
3259
|
/**
|
|
2797
3260
|
* @type {String}
|
|
2798
3261
|
*/
|
|
@@ -2817,25 +3280,37 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
2817
3280
|
/**
|
|
2818
3281
|
* Set up the socket and the internal resources.
|
|
2819
3282
|
*
|
|
2820
|
-
* @param {
|
|
2821
|
-
* server and client
|
|
3283
|
+
* @param {Duplex} socket The network socket between the server and client
|
|
2822
3284
|
* @param {Buffer} head The first packet of the upgraded stream
|
|
2823
|
-
* @param {
|
|
3285
|
+
* @param {Object} options Options object
|
|
3286
|
+
* @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether
|
|
3287
|
+
* any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
|
|
3288
|
+
* multiple times in the same tick
|
|
3289
|
+
* @param {Function} [options.generateMask] The function used to generate the
|
|
3290
|
+
* masking key
|
|
3291
|
+
* @param {Number} [options.maxPayload=0] The maximum allowed message size
|
|
3292
|
+
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
|
|
3293
|
+
* not to skip UTF-8 validation for text and close messages
|
|
2824
3294
|
* @private
|
|
2825
3295
|
*/
|
|
2826
|
-
setSocket(socket, head,
|
|
2827
|
-
const receiver = new Receiver(
|
|
2828
|
-
|
|
2829
|
-
this.
|
|
2830
|
-
this.
|
|
2831
|
-
|
|
2832
|
-
|
|
3296
|
+
setSocket(socket, head, options) {
|
|
3297
|
+
const receiver = new Receiver({
|
|
3298
|
+
allowSynchronousEvents: options.allowSynchronousEvents,
|
|
3299
|
+
binaryType: this.binaryType,
|
|
3300
|
+
extensions: this._extensions,
|
|
3301
|
+
isServer: this._isServer,
|
|
3302
|
+
maxPayload: options.maxPayload,
|
|
3303
|
+
skipUTF8Validation: options.skipUTF8Validation
|
|
3304
|
+
});
|
|
3305
|
+
|
|
3306
|
+
const sender = new Sender(socket, this._extensions, options.generateMask);
|
|
2833
3307
|
|
|
2834
|
-
this._sender = new Sender(socket, this._extensions);
|
|
2835
3308
|
this._receiver = receiver;
|
|
3309
|
+
this._sender = sender;
|
|
2836
3310
|
this._socket = socket;
|
|
2837
3311
|
|
|
2838
3312
|
receiver[kWebSocket$1] = this;
|
|
3313
|
+
sender[kWebSocket$1] = this;
|
|
2839
3314
|
socket[kWebSocket$1] = this;
|
|
2840
3315
|
|
|
2841
3316
|
receiver.on('conclude', receiverOnConclude);
|
|
@@ -2845,15 +3320,20 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
2845
3320
|
receiver.on('ping', receiverOnPing);
|
|
2846
3321
|
receiver.on('pong', receiverOnPong);
|
|
2847
3322
|
|
|
2848
|
-
|
|
2849
|
-
|
|
3323
|
+
sender.onerror = senderOnError;
|
|
3324
|
+
|
|
3325
|
+
//
|
|
3326
|
+
// These methods may not be available if `socket` is just a `Duplex`.
|
|
3327
|
+
//
|
|
3328
|
+
if (socket.setTimeout) socket.setTimeout(0);
|
|
3329
|
+
if (socket.setNoDelay) socket.setNoDelay();
|
|
2850
3330
|
|
|
2851
3331
|
if (head.length > 0) socket.unshift(head);
|
|
2852
3332
|
|
|
2853
3333
|
socket.on('close', socketOnClose);
|
|
2854
3334
|
socket.on('data', socketOnData);
|
|
2855
3335
|
socket.on('end', socketOnEnd);
|
|
2856
|
-
socket.on('error', socketOnError
|
|
3336
|
+
socket.on('error', socketOnError);
|
|
2857
3337
|
|
|
2858
3338
|
this._readyState = WebSocket.OPEN;
|
|
2859
3339
|
this.emit('open');
|
|
@@ -2871,8 +3351,8 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
2871
3351
|
return;
|
|
2872
3352
|
}
|
|
2873
3353
|
|
|
2874
|
-
if (this._extensions[PerMessageDeflate
|
|
2875
|
-
this._extensions[PerMessageDeflate
|
|
3354
|
+
if (this._extensions[PerMessageDeflate.extensionName]) {
|
|
3355
|
+
this._extensions[PerMessageDeflate.extensionName].cleanup();
|
|
2876
3356
|
}
|
|
2877
3357
|
|
|
2878
3358
|
this._receiver.removeAllListeners();
|
|
@@ -2896,14 +3376,16 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
2896
3376
|
* +---+
|
|
2897
3377
|
*
|
|
2898
3378
|
* @param {Number} [code] Status code explaining why the connection is closing
|
|
2899
|
-
* @param {String} [data]
|
|
3379
|
+
* @param {(String|Buffer)} [data] The reason why the connection is
|
|
3380
|
+
* closing
|
|
2900
3381
|
* @public
|
|
2901
3382
|
*/
|
|
2902
3383
|
close(code, data) {
|
|
2903
3384
|
if (this.readyState === WebSocket.CLOSED) return;
|
|
2904
3385
|
if (this.readyState === WebSocket.CONNECTING) {
|
|
2905
3386
|
const msg = 'WebSocket was closed before the connection was established';
|
|
2906
|
-
|
|
3387
|
+
abortHandshake(this, this._req, msg);
|
|
3388
|
+
return;
|
|
2907
3389
|
}
|
|
2908
3390
|
|
|
2909
3391
|
if (this.readyState === WebSocket.CLOSING) {
|
|
@@ -2935,13 +3417,24 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
2935
3417
|
}
|
|
2936
3418
|
});
|
|
2937
3419
|
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
3420
|
+
setCloseTimer(this);
|
|
3421
|
+
}
|
|
3422
|
+
|
|
3423
|
+
/**
|
|
3424
|
+
* Pause the socket.
|
|
3425
|
+
*
|
|
3426
|
+
* @public
|
|
3427
|
+
*/
|
|
3428
|
+
pause() {
|
|
3429
|
+
if (
|
|
3430
|
+
this.readyState === WebSocket.CONNECTING ||
|
|
3431
|
+
this.readyState === WebSocket.CLOSED
|
|
3432
|
+
) {
|
|
3433
|
+
return;
|
|
3434
|
+
}
|
|
3435
|
+
|
|
3436
|
+
this._paused = true;
|
|
3437
|
+
this._socket.pause();
|
|
2945
3438
|
}
|
|
2946
3439
|
|
|
2947
3440
|
/**
|
|
@@ -3008,15 +3501,32 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
3008
3501
|
this._sender.pong(data || EMPTY_BUFFER, mask, cb);
|
|
3009
3502
|
}
|
|
3010
3503
|
|
|
3504
|
+
/**
|
|
3505
|
+
* Resume the socket.
|
|
3506
|
+
*
|
|
3507
|
+
* @public
|
|
3508
|
+
*/
|
|
3509
|
+
resume() {
|
|
3510
|
+
if (
|
|
3511
|
+
this.readyState === WebSocket.CONNECTING ||
|
|
3512
|
+
this.readyState === WebSocket.CLOSED
|
|
3513
|
+
) {
|
|
3514
|
+
return;
|
|
3515
|
+
}
|
|
3516
|
+
|
|
3517
|
+
this._paused = false;
|
|
3518
|
+
if (!this._receiver._writableState.needDrain) this._socket.resume();
|
|
3519
|
+
}
|
|
3520
|
+
|
|
3011
3521
|
/**
|
|
3012
3522
|
* Send a data message.
|
|
3013
3523
|
*
|
|
3014
3524
|
* @param {*} data The message to send
|
|
3015
3525
|
* @param {Object} [options] Options object
|
|
3016
|
-
* @param {Boolean} [options.compress] Specifies whether or not to compress
|
|
3017
|
-
* `data`
|
|
3018
3526
|
* @param {Boolean} [options.binary] Specifies whether `data` is binary or
|
|
3019
3527
|
* text
|
|
3528
|
+
* @param {Boolean} [options.compress] Specifies whether or not to compress
|
|
3529
|
+
* `data`
|
|
3020
3530
|
* @param {Boolean} [options.fin=true] Specifies whether the fragment is the
|
|
3021
3531
|
* last one
|
|
3022
3532
|
* @param {Boolean} [options.mask] Specifies whether or not to mask `data`
|
|
@@ -3048,7 +3558,7 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
3048
3558
|
...options
|
|
3049
3559
|
};
|
|
3050
3560
|
|
|
3051
|
-
if (!this._extensions[PerMessageDeflate
|
|
3561
|
+
if (!this._extensions[PerMessageDeflate.extensionName]) {
|
|
3052
3562
|
opts.compress = false;
|
|
3053
3563
|
}
|
|
3054
3564
|
|
|
@@ -3064,7 +3574,8 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
3064
3574
|
if (this.readyState === WebSocket.CLOSED) return;
|
|
3065
3575
|
if (this.readyState === WebSocket.CONNECTING) {
|
|
3066
3576
|
const msg = 'WebSocket was closed before the connection was established';
|
|
3067
|
-
|
|
3577
|
+
abortHandshake(this, this._req, msg);
|
|
3578
|
+
return;
|
|
3068
3579
|
}
|
|
3069
3580
|
|
|
3070
3581
|
if (this._socket) {
|
|
@@ -3078,7 +3589,7 @@ let WebSocket$3 = class WebSocket extends EventEmitter$1 {
|
|
|
3078
3589
|
* @constant {Number} CONNECTING
|
|
3079
3590
|
* @memberof WebSocket
|
|
3080
3591
|
*/
|
|
3081
|
-
Object.defineProperty(WebSocket$
|
|
3592
|
+
Object.defineProperty(WebSocket$1, 'CONNECTING', {
|
|
3082
3593
|
enumerable: true,
|
|
3083
3594
|
value: readyStates.indexOf('CONNECTING')
|
|
3084
3595
|
});
|
|
@@ -3087,7 +3598,7 @@ Object.defineProperty(WebSocket$3, 'CONNECTING', {
|
|
|
3087
3598
|
* @constant {Number} CONNECTING
|
|
3088
3599
|
* @memberof WebSocket.prototype
|
|
3089
3600
|
*/
|
|
3090
|
-
Object.defineProperty(WebSocket$
|
|
3601
|
+
Object.defineProperty(WebSocket$1.prototype, 'CONNECTING', {
|
|
3091
3602
|
enumerable: true,
|
|
3092
3603
|
value: readyStates.indexOf('CONNECTING')
|
|
3093
3604
|
});
|
|
@@ -3096,7 +3607,7 @@ Object.defineProperty(WebSocket$3.prototype, 'CONNECTING', {
|
|
|
3096
3607
|
* @constant {Number} OPEN
|
|
3097
3608
|
* @memberof WebSocket
|
|
3098
3609
|
*/
|
|
3099
|
-
Object.defineProperty(WebSocket$
|
|
3610
|
+
Object.defineProperty(WebSocket$1, 'OPEN', {
|
|
3100
3611
|
enumerable: true,
|
|
3101
3612
|
value: readyStates.indexOf('OPEN')
|
|
3102
3613
|
});
|
|
@@ -3105,7 +3616,7 @@ Object.defineProperty(WebSocket$3, 'OPEN', {
|
|
|
3105
3616
|
* @constant {Number} OPEN
|
|
3106
3617
|
* @memberof WebSocket.prototype
|
|
3107
3618
|
*/
|
|
3108
|
-
Object.defineProperty(WebSocket$
|
|
3619
|
+
Object.defineProperty(WebSocket$1.prototype, 'OPEN', {
|
|
3109
3620
|
enumerable: true,
|
|
3110
3621
|
value: readyStates.indexOf('OPEN')
|
|
3111
3622
|
});
|
|
@@ -3114,7 +3625,7 @@ Object.defineProperty(WebSocket$3.prototype, 'OPEN', {
|
|
|
3114
3625
|
* @constant {Number} CLOSING
|
|
3115
3626
|
* @memberof WebSocket
|
|
3116
3627
|
*/
|
|
3117
|
-
Object.defineProperty(WebSocket$
|
|
3628
|
+
Object.defineProperty(WebSocket$1, 'CLOSING', {
|
|
3118
3629
|
enumerable: true,
|
|
3119
3630
|
value: readyStates.indexOf('CLOSING')
|
|
3120
3631
|
});
|
|
@@ -3123,7 +3634,7 @@ Object.defineProperty(WebSocket$3, 'CLOSING', {
|
|
|
3123
3634
|
* @constant {Number} CLOSING
|
|
3124
3635
|
* @memberof WebSocket.prototype
|
|
3125
3636
|
*/
|
|
3126
|
-
Object.defineProperty(WebSocket$
|
|
3637
|
+
Object.defineProperty(WebSocket$1.prototype, 'CLOSING', {
|
|
3127
3638
|
enumerable: true,
|
|
3128
3639
|
value: readyStates.indexOf('CLOSING')
|
|
3129
3640
|
});
|
|
@@ -3132,7 +3643,7 @@ Object.defineProperty(WebSocket$3.prototype, 'CLOSING', {
|
|
|
3132
3643
|
* @constant {Number} CLOSED
|
|
3133
3644
|
* @memberof WebSocket
|
|
3134
3645
|
*/
|
|
3135
|
-
Object.defineProperty(WebSocket$
|
|
3646
|
+
Object.defineProperty(WebSocket$1, 'CLOSED', {
|
|
3136
3647
|
enumerable: true,
|
|
3137
3648
|
value: readyStates.indexOf('CLOSED')
|
|
3138
3649
|
});
|
|
@@ -3141,7 +3652,7 @@ Object.defineProperty(WebSocket$3, 'CLOSED', {
|
|
|
3141
3652
|
* @constant {Number} CLOSED
|
|
3142
3653
|
* @memberof WebSocket.prototype
|
|
3143
3654
|
*/
|
|
3144
|
-
Object.defineProperty(WebSocket$
|
|
3655
|
+
Object.defineProperty(WebSocket$1.prototype, 'CLOSED', {
|
|
3145
3656
|
enumerable: true,
|
|
3146
3657
|
value: readyStates.indexOf('CLOSED')
|
|
3147
3658
|
});
|
|
@@ -3150,11 +3661,12 @@ Object.defineProperty(WebSocket$3.prototype, 'CLOSED', {
|
|
|
3150
3661
|
'binaryType',
|
|
3151
3662
|
'bufferedAmount',
|
|
3152
3663
|
'extensions',
|
|
3664
|
+
'isPaused',
|
|
3153
3665
|
'protocol',
|
|
3154
3666
|
'readyState',
|
|
3155
3667
|
'url'
|
|
3156
3668
|
].forEach((property) => {
|
|
3157
|
-
Object.defineProperty(WebSocket$
|
|
3669
|
+
Object.defineProperty(WebSocket$1.prototype, property, { enumerable: true });
|
|
3158
3670
|
});
|
|
3159
3671
|
|
|
3160
3672
|
//
|
|
@@ -3162,76 +3674,98 @@ Object.defineProperty(WebSocket$3.prototype, 'CLOSED', {
|
|
|
3162
3674
|
// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface
|
|
3163
3675
|
//
|
|
3164
3676
|
['open', 'error', 'close', 'message'].forEach((method) => {
|
|
3165
|
-
Object.defineProperty(WebSocket$
|
|
3677
|
+
Object.defineProperty(WebSocket$1.prototype, `on${method}`, {
|
|
3166
3678
|
enumerable: true,
|
|
3167
3679
|
get() {
|
|
3168
|
-
const
|
|
3169
|
-
|
|
3170
|
-
if (listeners[i]._listener) return listeners[i]._listener;
|
|
3680
|
+
for (const listener of this.listeners(method)) {
|
|
3681
|
+
if (listener[kForOnEventAttribute]) return listener[kListener];
|
|
3171
3682
|
}
|
|
3172
3683
|
|
|
3173
|
-
return
|
|
3684
|
+
return null;
|
|
3174
3685
|
},
|
|
3175
|
-
set(
|
|
3176
|
-
const
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
if (listeners[i]._listener) this.removeListener(method, listeners[i]);
|
|
3686
|
+
set(handler) {
|
|
3687
|
+
for (const listener of this.listeners(method)) {
|
|
3688
|
+
if (listener[kForOnEventAttribute]) {
|
|
3689
|
+
this.removeListener(method, listener);
|
|
3690
|
+
break;
|
|
3691
|
+
}
|
|
3182
3692
|
}
|
|
3183
|
-
|
|
3693
|
+
|
|
3694
|
+
if (typeof handler !== 'function') return;
|
|
3695
|
+
|
|
3696
|
+
this.addEventListener(method, handler, {
|
|
3697
|
+
[kForOnEventAttribute]: true
|
|
3698
|
+
});
|
|
3184
3699
|
}
|
|
3185
3700
|
});
|
|
3186
3701
|
});
|
|
3187
3702
|
|
|
3188
|
-
WebSocket$
|
|
3189
|
-
WebSocket$
|
|
3703
|
+
WebSocket$1.prototype.addEventListener = addEventListener;
|
|
3704
|
+
WebSocket$1.prototype.removeEventListener = removeEventListener;
|
|
3190
3705
|
|
|
3191
|
-
var websocket = WebSocket$
|
|
3706
|
+
var websocket = WebSocket$1;
|
|
3192
3707
|
|
|
3193
3708
|
/**
|
|
3194
3709
|
* Initialize a WebSocket client.
|
|
3195
3710
|
*
|
|
3196
3711
|
* @param {WebSocket} websocket The client to initialize
|
|
3197
3712
|
* @param {(String|URL)} address The URL to which to connect
|
|
3198
|
-
* @param {
|
|
3713
|
+
* @param {Array} protocols The subprotocols
|
|
3199
3714
|
* @param {Object} [options] Connection options
|
|
3200
|
-
* @param {
|
|
3201
|
-
*
|
|
3715
|
+
* @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any
|
|
3716
|
+
* of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple
|
|
3717
|
+
* times in the same tick
|
|
3718
|
+
* @param {Boolean} [options.autoPong=true] Specifies whether or not to
|
|
3719
|
+
* automatically send a pong in response to a ping
|
|
3720
|
+
* @param {Number} [options.closeTimeout=30000] Duration in milliseconds to wait
|
|
3721
|
+
* for the closing handshake to finish after `websocket.close()` is called
|
|
3722
|
+
* @param {Function} [options.finishRequest] A function which can be used to
|
|
3723
|
+
* customize the headers of each http request before it is sent
|
|
3724
|
+
* @param {Boolean} [options.followRedirects=false] Whether or not to follow
|
|
3725
|
+
* redirects
|
|
3726
|
+
* @param {Function} [options.generateMask] The function used to generate the
|
|
3727
|
+
* masking key
|
|
3202
3728
|
* @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the
|
|
3203
3729
|
* handshake request
|
|
3204
|
-
* @param {Number} [options.protocolVersion=13] Value of the
|
|
3205
|
-
* `Sec-WebSocket-Version` header
|
|
3206
|
-
* @param {String} [options.origin] Value of the `Origin` or
|
|
3207
|
-
* `Sec-WebSocket-Origin` header
|
|
3208
3730
|
* @param {Number} [options.maxPayload=104857600] The maximum allowed message
|
|
3209
3731
|
* size
|
|
3210
|
-
* @param {Boolean} [options.followRedirects=false] Whether or not to follow
|
|
3211
|
-
* redirects
|
|
3212
3732
|
* @param {Number} [options.maxRedirects=10] The maximum number of redirects
|
|
3213
3733
|
* allowed
|
|
3734
|
+
* @param {String} [options.origin] Value of the `Origin` or
|
|
3735
|
+
* `Sec-WebSocket-Origin` header
|
|
3736
|
+
* @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable
|
|
3737
|
+
* permessage-deflate
|
|
3738
|
+
* @param {Number} [options.protocolVersion=13] Value of the
|
|
3739
|
+
* `Sec-WebSocket-Version` header
|
|
3740
|
+
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
|
|
3741
|
+
* not to skip UTF-8 validation for text and close messages
|
|
3214
3742
|
* @private
|
|
3215
3743
|
*/
|
|
3216
3744
|
function initAsClient(websocket, address, protocols, options) {
|
|
3217
3745
|
const opts = {
|
|
3746
|
+
allowSynchronousEvents: true,
|
|
3747
|
+
autoPong: true,
|
|
3748
|
+
closeTimeout: CLOSE_TIMEOUT$1,
|
|
3218
3749
|
protocolVersion: protocolVersions[1],
|
|
3219
3750
|
maxPayload: 100 * 1024 * 1024,
|
|
3751
|
+
skipUTF8Validation: false,
|
|
3220
3752
|
perMessageDeflate: true,
|
|
3221
3753
|
followRedirects: false,
|
|
3222
3754
|
maxRedirects: 10,
|
|
3223
3755
|
...options,
|
|
3224
|
-
createConnection: undefined,
|
|
3225
3756
|
socketPath: undefined,
|
|
3226
3757
|
hostname: undefined,
|
|
3227
3758
|
protocol: undefined,
|
|
3228
3759
|
timeout: undefined,
|
|
3229
|
-
method:
|
|
3760
|
+
method: 'GET',
|
|
3230
3761
|
host: undefined,
|
|
3231
3762
|
path: undefined,
|
|
3232
3763
|
port: undefined
|
|
3233
3764
|
};
|
|
3234
3765
|
|
|
3766
|
+
websocket._autoPong = opts.autoPong;
|
|
3767
|
+
websocket._closeTimeout = opts.closeTimeout;
|
|
3768
|
+
|
|
3235
3769
|
if (!protocolVersions.includes(opts.protocolVersion)) {
|
|
3236
3770
|
throw new RangeError(
|
|
3237
3771
|
`Unsupported protocol version: ${opts.protocolVersion} ` +
|
|
@@ -3243,16 +3777,38 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3243
3777
|
|
|
3244
3778
|
if (address instanceof URL) {
|
|
3245
3779
|
parsedUrl = address;
|
|
3246
|
-
websocket._url = address.href;
|
|
3247
3780
|
} else {
|
|
3248
|
-
|
|
3249
|
-
|
|
3781
|
+
try {
|
|
3782
|
+
parsedUrl = new URL(address);
|
|
3783
|
+
} catch {
|
|
3784
|
+
throw new SyntaxError(`Invalid URL: ${address}`);
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3787
|
+
|
|
3788
|
+
if (parsedUrl.protocol === 'http:') {
|
|
3789
|
+
parsedUrl.protocol = 'ws:';
|
|
3790
|
+
} else if (parsedUrl.protocol === 'https:') {
|
|
3791
|
+
parsedUrl.protocol = 'wss:';
|
|
3250
3792
|
}
|
|
3251
3793
|
|
|
3252
|
-
|
|
3794
|
+
websocket._url = parsedUrl.href;
|
|
3795
|
+
|
|
3796
|
+
const isSecure = parsedUrl.protocol === 'wss:';
|
|
3797
|
+
const isIpcUrl = parsedUrl.protocol === 'ws+unix:';
|
|
3798
|
+
let invalidUrlMessage;
|
|
3799
|
+
|
|
3800
|
+
if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {
|
|
3801
|
+
invalidUrlMessage =
|
|
3802
|
+
'The URL\'s protocol must be one of "ws:", "wss:", ' +
|
|
3803
|
+
'"http:", "https:", or "ws+unix:"';
|
|
3804
|
+
} else if (isIpcUrl && !parsedUrl.pathname) {
|
|
3805
|
+
invalidUrlMessage = "The URL's pathname is empty";
|
|
3806
|
+
} else if (parsedUrl.hash) {
|
|
3807
|
+
invalidUrlMessage = 'The URL contains a fragment identifier';
|
|
3808
|
+
}
|
|
3253
3809
|
|
|
3254
|
-
if (
|
|
3255
|
-
const err = new
|
|
3810
|
+
if (invalidUrlMessage) {
|
|
3811
|
+
const err = new SyntaxError(invalidUrlMessage);
|
|
3256
3812
|
|
|
3257
3813
|
if (websocket._redirects === 0) {
|
|
3258
3814
|
throw err;
|
|
@@ -3262,41 +3818,55 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3262
3818
|
}
|
|
3263
3819
|
}
|
|
3264
3820
|
|
|
3265
|
-
const isSecure =
|
|
3266
|
-
parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
|
|
3267
3821
|
const defaultPort = isSecure ? 443 : 80;
|
|
3268
3822
|
const key = randomBytes(16).toString('base64');
|
|
3269
|
-
const
|
|
3823
|
+
const request = isSecure ? https.request : http.request;
|
|
3824
|
+
const protocolSet = new Set();
|
|
3270
3825
|
let perMessageDeflate;
|
|
3271
3826
|
|
|
3272
|
-
opts.createConnection =
|
|
3827
|
+
opts.createConnection =
|
|
3828
|
+
opts.createConnection || (isSecure ? tlsConnect : netConnect);
|
|
3273
3829
|
opts.defaultPort = opts.defaultPort || defaultPort;
|
|
3274
3830
|
opts.port = parsedUrl.port || defaultPort;
|
|
3275
3831
|
opts.host = parsedUrl.hostname.startsWith('[')
|
|
3276
3832
|
? parsedUrl.hostname.slice(1, -1)
|
|
3277
3833
|
: parsedUrl.hostname;
|
|
3278
3834
|
opts.headers = {
|
|
3835
|
+
...opts.headers,
|
|
3279
3836
|
'Sec-WebSocket-Version': opts.protocolVersion,
|
|
3280
3837
|
'Sec-WebSocket-Key': key,
|
|
3281
3838
|
Connection: 'Upgrade',
|
|
3282
|
-
Upgrade: 'websocket'
|
|
3283
|
-
...opts.headers
|
|
3839
|
+
Upgrade: 'websocket'
|
|
3284
3840
|
};
|
|
3285
3841
|
opts.path = parsedUrl.pathname + parsedUrl.search;
|
|
3286
3842
|
opts.timeout = opts.handshakeTimeout;
|
|
3287
3843
|
|
|
3288
3844
|
if (opts.perMessageDeflate) {
|
|
3289
|
-
perMessageDeflate = new PerMessageDeflate
|
|
3290
|
-
opts.perMessageDeflate
|
|
3291
|
-
false,
|
|
3292
|
-
opts.maxPayload
|
|
3293
|
-
);
|
|
3294
|
-
opts.headers['Sec-WebSocket-Extensions'] = format
|
|
3295
|
-
[PerMessageDeflate
|
|
3845
|
+
perMessageDeflate = new PerMessageDeflate({
|
|
3846
|
+
...opts.perMessageDeflate,
|
|
3847
|
+
isServer: false,
|
|
3848
|
+
maxPayload: opts.maxPayload
|
|
3849
|
+
});
|
|
3850
|
+
opts.headers['Sec-WebSocket-Extensions'] = format({
|
|
3851
|
+
[PerMessageDeflate.extensionName]: perMessageDeflate.offer()
|
|
3296
3852
|
});
|
|
3297
3853
|
}
|
|
3298
|
-
if (protocols) {
|
|
3299
|
-
|
|
3854
|
+
if (protocols.length) {
|
|
3855
|
+
for (const protocol of protocols) {
|
|
3856
|
+
if (
|
|
3857
|
+
typeof protocol !== 'string' ||
|
|
3858
|
+
!subprotocolRegex.test(protocol) ||
|
|
3859
|
+
protocolSet.has(protocol)
|
|
3860
|
+
) {
|
|
3861
|
+
throw new SyntaxError(
|
|
3862
|
+
'An invalid or duplicated subprotocol was specified'
|
|
3863
|
+
);
|
|
3864
|
+
}
|
|
3865
|
+
|
|
3866
|
+
protocolSet.add(protocol);
|
|
3867
|
+
}
|
|
3868
|
+
|
|
3869
|
+
opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');
|
|
3300
3870
|
}
|
|
3301
3871
|
if (opts.origin) {
|
|
3302
3872
|
if (opts.protocolVersion < 13) {
|
|
@@ -3309,18 +3879,20 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3309
3879
|
opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
|
|
3310
3880
|
}
|
|
3311
3881
|
|
|
3312
|
-
if (
|
|
3882
|
+
if (isIpcUrl) {
|
|
3313
3883
|
const parts = opts.path.split(':');
|
|
3314
3884
|
|
|
3315
3885
|
opts.socketPath = parts[0];
|
|
3316
3886
|
opts.path = parts[1];
|
|
3317
3887
|
}
|
|
3318
3888
|
|
|
3889
|
+
let req;
|
|
3890
|
+
|
|
3319
3891
|
if (opts.followRedirects) {
|
|
3320
3892
|
if (websocket._redirects === 0) {
|
|
3321
|
-
websocket.
|
|
3893
|
+
websocket._originalIpc = isIpcUrl;
|
|
3322
3894
|
websocket._originalSecure = isSecure;
|
|
3323
|
-
websocket._originalHostOrSocketPath =
|
|
3895
|
+
websocket._originalHostOrSocketPath = isIpcUrl
|
|
3324
3896
|
? opts.socketPath
|
|
3325
3897
|
: parsedUrl.host;
|
|
3326
3898
|
|
|
@@ -3337,14 +3909,14 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3337
3909
|
options.headers[key.toLowerCase()] = value;
|
|
3338
3910
|
}
|
|
3339
3911
|
}
|
|
3340
|
-
} else {
|
|
3341
|
-
const isSameHost =
|
|
3342
|
-
? websocket.
|
|
3912
|
+
} else if (websocket.listenerCount('redirect') === 0) {
|
|
3913
|
+
const isSameHost = isIpcUrl
|
|
3914
|
+
? websocket._originalIpc
|
|
3343
3915
|
? opts.socketPath === websocket._originalHostOrSocketPath
|
|
3344
3916
|
: false
|
|
3345
|
-
: websocket.
|
|
3346
|
-
|
|
3347
|
-
|
|
3917
|
+
: websocket._originalIpc
|
|
3918
|
+
? false
|
|
3919
|
+
: parsedUrl.host === websocket._originalHostOrSocketPath;
|
|
3348
3920
|
|
|
3349
3921
|
if (!isSameHost || (websocket._originalSecure && !isSecure)) {
|
|
3350
3922
|
//
|
|
@@ -3369,18 +3941,33 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3369
3941
|
options.headers.authorization =
|
|
3370
3942
|
'Basic ' + Buffer.from(opts.auth).toString('base64');
|
|
3371
3943
|
}
|
|
3372
|
-
}
|
|
3373
3944
|
|
|
3374
|
-
|
|
3945
|
+
req = websocket._req = request(opts);
|
|
3946
|
+
|
|
3947
|
+
if (websocket._redirects) {
|
|
3948
|
+
//
|
|
3949
|
+
// Unlike what is done for the `'upgrade'` event, no early exit is
|
|
3950
|
+
// triggered here if the user calls `websocket.close()` or
|
|
3951
|
+
// `websocket.terminate()` from a listener of the `'redirect'` event. This
|
|
3952
|
+
// is because the user can also call `request.destroy()` with an error
|
|
3953
|
+
// before calling `websocket.close()` or `websocket.terminate()` and this
|
|
3954
|
+
// would result in an error being emitted on the `request` object with no
|
|
3955
|
+
// `'error'` event listeners attached.
|
|
3956
|
+
//
|
|
3957
|
+
websocket.emit('redirect', websocket.url, req);
|
|
3958
|
+
}
|
|
3959
|
+
} else {
|
|
3960
|
+
req = websocket._req = request(opts);
|
|
3961
|
+
}
|
|
3375
3962
|
|
|
3376
3963
|
if (opts.timeout) {
|
|
3377
3964
|
req.on('timeout', () => {
|
|
3378
|
-
abortHandshake
|
|
3965
|
+
abortHandshake(websocket, req, 'Opening handshake has timed out');
|
|
3379
3966
|
});
|
|
3380
3967
|
}
|
|
3381
3968
|
|
|
3382
3969
|
req.on('error', (err) => {
|
|
3383
|
-
if (req === null || req
|
|
3970
|
+
if (req === null || req[kAborted]) return;
|
|
3384
3971
|
|
|
3385
3972
|
req = websocket._req = null;
|
|
3386
3973
|
emitErrorAndClose(websocket, err);
|
|
@@ -3397,7 +3984,7 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3397
3984
|
statusCode < 400
|
|
3398
3985
|
) {
|
|
3399
3986
|
if (++websocket._redirects > opts.maxRedirects) {
|
|
3400
|
-
abortHandshake
|
|
3987
|
+
abortHandshake(websocket, req, 'Maximum redirects exceeded');
|
|
3401
3988
|
return;
|
|
3402
3989
|
}
|
|
3403
3990
|
|
|
@@ -3407,14 +3994,15 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3407
3994
|
|
|
3408
3995
|
try {
|
|
3409
3996
|
addr = new URL(location, address);
|
|
3410
|
-
} catch (
|
|
3997
|
+
} catch (e) {
|
|
3998
|
+
const err = new SyntaxError(`Invalid URL: ${location}`);
|
|
3411
3999
|
emitErrorAndClose(websocket, err);
|
|
3412
4000
|
return;
|
|
3413
4001
|
}
|
|
3414
4002
|
|
|
3415
4003
|
initAsClient(websocket, addr, protocols, options);
|
|
3416
4004
|
} else if (!websocket.emit('unexpected-response', req, res)) {
|
|
3417
|
-
abortHandshake
|
|
4005
|
+
abortHandshake(
|
|
3418
4006
|
websocket,
|
|
3419
4007
|
req,
|
|
3420
4008
|
`Unexpected server response: ${res.statusCode}`
|
|
@@ -3426,17 +4014,17 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3426
4014
|
websocket.emit('upgrade', res);
|
|
3427
4015
|
|
|
3428
4016
|
//
|
|
3429
|
-
// The user may have closed the connection from a listener of the
|
|
3430
|
-
// event.
|
|
4017
|
+
// The user may have closed the connection from a listener of the
|
|
4018
|
+
// `'upgrade'` event.
|
|
3431
4019
|
//
|
|
3432
|
-
if (websocket.readyState !== WebSocket$
|
|
4020
|
+
if (websocket.readyState !== WebSocket$1.CONNECTING) return;
|
|
3433
4021
|
|
|
3434
4022
|
req = websocket._req = null;
|
|
3435
4023
|
|
|
3436
4024
|
const upgrade = res.headers.upgrade;
|
|
3437
4025
|
|
|
3438
4026
|
if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {
|
|
3439
|
-
abortHandshake
|
|
4027
|
+
abortHandshake(websocket, socket, 'Invalid Upgrade header');
|
|
3440
4028
|
return;
|
|
3441
4029
|
}
|
|
3442
4030
|
|
|
@@ -3445,24 +4033,25 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3445
4033
|
.digest('base64');
|
|
3446
4034
|
|
|
3447
4035
|
if (res.headers['sec-websocket-accept'] !== digest) {
|
|
3448
|
-
abortHandshake
|
|
4036
|
+
abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');
|
|
3449
4037
|
return;
|
|
3450
4038
|
}
|
|
3451
4039
|
|
|
3452
4040
|
const serverProt = res.headers['sec-websocket-protocol'];
|
|
3453
|
-
const protList = (protocols || '').split(/, */);
|
|
3454
4041
|
let protError;
|
|
3455
4042
|
|
|
3456
|
-
if (
|
|
3457
|
-
|
|
3458
|
-
|
|
4043
|
+
if (serverProt !== undefined) {
|
|
4044
|
+
if (!protocolSet.size) {
|
|
4045
|
+
protError = 'Server sent a subprotocol but none was requested';
|
|
4046
|
+
} else if (!protocolSet.has(serverProt)) {
|
|
4047
|
+
protError = 'Server sent an invalid subprotocol';
|
|
4048
|
+
}
|
|
4049
|
+
} else if (protocolSet.size) {
|
|
3459
4050
|
protError = 'Server sent no subprotocol';
|
|
3460
|
-
} else if (serverProt && !protList.includes(serverProt)) {
|
|
3461
|
-
protError = 'Server sent an invalid subprotocol';
|
|
3462
4051
|
}
|
|
3463
4052
|
|
|
3464
4053
|
if (protError) {
|
|
3465
|
-
abortHandshake
|
|
4054
|
+
abortHandshake(websocket, socket, protError);
|
|
3466
4055
|
return;
|
|
3467
4056
|
}
|
|
3468
4057
|
|
|
@@ -3475,59 +4064,72 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3475
4064
|
const message =
|
|
3476
4065
|
'Server sent a Sec-WebSocket-Extensions header but no extension ' +
|
|
3477
4066
|
'was requested';
|
|
3478
|
-
abortHandshake
|
|
4067
|
+
abortHandshake(websocket, socket, message);
|
|
3479
4068
|
return;
|
|
3480
4069
|
}
|
|
3481
4070
|
|
|
3482
4071
|
let extensions;
|
|
3483
4072
|
|
|
3484
4073
|
try {
|
|
3485
|
-
extensions = parse
|
|
4074
|
+
extensions = parse(secWebSocketExtensions);
|
|
3486
4075
|
} catch (err) {
|
|
3487
4076
|
const message = 'Invalid Sec-WebSocket-Extensions header';
|
|
3488
|
-
abortHandshake
|
|
4077
|
+
abortHandshake(websocket, socket, message);
|
|
3489
4078
|
return;
|
|
3490
4079
|
}
|
|
3491
4080
|
|
|
3492
4081
|
const extensionNames = Object.keys(extensions);
|
|
3493
4082
|
|
|
3494
|
-
if (
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
return;
|
|
3503
|
-
}
|
|
3504
|
-
|
|
3505
|
-
try {
|
|
3506
|
-
perMessageDeflate.accept(extensions[PerMessageDeflate$1.extensionName]);
|
|
3507
|
-
} catch (err) {
|
|
3508
|
-
const message = 'Invalid Sec-WebSocket-Extensions header';
|
|
3509
|
-
abortHandshake$1(websocket, socket, message);
|
|
3510
|
-
return;
|
|
3511
|
-
}
|
|
4083
|
+
if (
|
|
4084
|
+
extensionNames.length !== 1 ||
|
|
4085
|
+
extensionNames[0] !== PerMessageDeflate.extensionName
|
|
4086
|
+
) {
|
|
4087
|
+
const message = 'Server indicated an extension that was not requested';
|
|
4088
|
+
abortHandshake(websocket, socket, message);
|
|
4089
|
+
return;
|
|
4090
|
+
}
|
|
3512
4091
|
|
|
3513
|
-
|
|
3514
|
-
|
|
4092
|
+
try {
|
|
4093
|
+
perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
|
|
4094
|
+
} catch (err) {
|
|
4095
|
+
const message = 'Invalid Sec-WebSocket-Extensions header';
|
|
4096
|
+
abortHandshake(websocket, socket, message);
|
|
4097
|
+
return;
|
|
3515
4098
|
}
|
|
4099
|
+
|
|
4100
|
+
websocket._extensions[PerMessageDeflate.extensionName] =
|
|
4101
|
+
perMessageDeflate;
|
|
3516
4102
|
}
|
|
3517
4103
|
|
|
3518
|
-
websocket.setSocket(socket, head,
|
|
4104
|
+
websocket.setSocket(socket, head, {
|
|
4105
|
+
allowSynchronousEvents: opts.allowSynchronousEvents,
|
|
4106
|
+
generateMask: opts.generateMask,
|
|
4107
|
+
maxPayload: opts.maxPayload,
|
|
4108
|
+
skipUTF8Validation: opts.skipUTF8Validation
|
|
4109
|
+
});
|
|
3519
4110
|
});
|
|
4111
|
+
|
|
4112
|
+
if (opts.finishRequest) {
|
|
4113
|
+
opts.finishRequest(req, websocket);
|
|
4114
|
+
} else {
|
|
4115
|
+
req.end();
|
|
4116
|
+
}
|
|
3520
4117
|
}
|
|
3521
4118
|
|
|
3522
4119
|
/**
|
|
3523
|
-
* Emit the `'error'` and `'close'`
|
|
4120
|
+
* Emit the `'error'` and `'close'` events.
|
|
3524
4121
|
*
|
|
3525
4122
|
* @param {WebSocket} websocket The WebSocket instance
|
|
3526
4123
|
* @param {Error} The error to emit
|
|
3527
4124
|
* @private
|
|
3528
4125
|
*/
|
|
3529
4126
|
function emitErrorAndClose(websocket, err) {
|
|
3530
|
-
websocket._readyState = WebSocket$
|
|
4127
|
+
websocket._readyState = WebSocket$1.CLOSING;
|
|
4128
|
+
//
|
|
4129
|
+
// The following assignment is practically useless and is done only for
|
|
4130
|
+
// consistency.
|
|
4131
|
+
//
|
|
4132
|
+
websocket._errorEmitted = true;
|
|
3531
4133
|
websocket.emit('error', err);
|
|
3532
4134
|
websocket.emitClose();
|
|
3533
4135
|
}
|
|
@@ -3570,13 +4172,14 @@ function tlsConnect(options) {
|
|
|
3570
4172
|
* @param {String} message The error message
|
|
3571
4173
|
* @private
|
|
3572
4174
|
*/
|
|
3573
|
-
function abortHandshake
|
|
3574
|
-
websocket._readyState = WebSocket$
|
|
4175
|
+
function abortHandshake(websocket, stream, message) {
|
|
4176
|
+
websocket._readyState = WebSocket$1.CLOSING;
|
|
3575
4177
|
|
|
3576
4178
|
const err = new Error(message);
|
|
3577
|
-
Error.captureStackTrace(err, abortHandshake
|
|
4179
|
+
Error.captureStackTrace(err, abortHandshake);
|
|
3578
4180
|
|
|
3579
4181
|
if (stream.setHeader) {
|
|
4182
|
+
stream[kAborted] = true;
|
|
3580
4183
|
stream.abort();
|
|
3581
4184
|
|
|
3582
4185
|
if (stream.socket && !stream.socket.destroyed) {
|
|
@@ -3588,8 +4191,7 @@ function abortHandshake$1(websocket, stream, message) {
|
|
|
3588
4191
|
stream.socket.destroy();
|
|
3589
4192
|
}
|
|
3590
4193
|
|
|
3591
|
-
|
|
3592
|
-
websocket.emit('error', err);
|
|
4194
|
+
process.nextTick(emitErrorAndClose, websocket, err);
|
|
3593
4195
|
} else {
|
|
3594
4196
|
stream.destroy(err);
|
|
3595
4197
|
stream.once('error', websocket.emit.bind(websocket, 'error'));
|
|
@@ -3608,7 +4210,7 @@ function abortHandshake$1(websocket, stream, message) {
|
|
|
3608
4210
|
*/
|
|
3609
4211
|
function sendAfterClose(websocket, data, cb) {
|
|
3610
4212
|
if (data) {
|
|
3611
|
-
const length = toBuffer(data).length;
|
|
4213
|
+
const length = isBlob(data) ? data.size : toBuffer(data).length;
|
|
3612
4214
|
|
|
3613
4215
|
//
|
|
3614
4216
|
// The `_bufferedAmount` property is used only when the peer is a client and
|
|
@@ -3625,7 +4227,7 @@ function sendAfterClose(websocket, data, cb) {
|
|
|
3625
4227
|
`WebSocket is not open: readyState ${websocket.readyState} ` +
|
|
3626
4228
|
`(${readyStates[websocket.readyState]})`
|
|
3627
4229
|
);
|
|
3628
|
-
cb
|
|
4230
|
+
process.nextTick(cb, err);
|
|
3629
4231
|
}
|
|
3630
4232
|
}
|
|
3631
4233
|
|
|
@@ -3633,7 +4235,7 @@ function sendAfterClose(websocket, data, cb) {
|
|
|
3633
4235
|
* The listener of the `Receiver` `'conclude'` event.
|
|
3634
4236
|
*
|
|
3635
4237
|
* @param {Number} code The status code
|
|
3636
|
-
* @param {
|
|
4238
|
+
* @param {Buffer} reason The reason for closing
|
|
3637
4239
|
* @private
|
|
3638
4240
|
*/
|
|
3639
4241
|
function receiverOnConclude(code, reason) {
|
|
@@ -3658,7 +4260,9 @@ function receiverOnConclude(code, reason) {
|
|
|
3658
4260
|
* @private
|
|
3659
4261
|
*/
|
|
3660
4262
|
function receiverOnDrain() {
|
|
3661
|
-
this[kWebSocket$1]
|
|
4263
|
+
const websocket = this[kWebSocket$1];
|
|
4264
|
+
|
|
4265
|
+
if (!websocket.isPaused) websocket._socket.resume();
|
|
3662
4266
|
}
|
|
3663
4267
|
|
|
3664
4268
|
/**
|
|
@@ -3682,7 +4286,10 @@ function receiverOnError(err) {
|
|
|
3682
4286
|
websocket.close(err[kStatusCode]);
|
|
3683
4287
|
}
|
|
3684
4288
|
|
|
3685
|
-
websocket.
|
|
4289
|
+
if (!websocket._errorEmitted) {
|
|
4290
|
+
websocket._errorEmitted = true;
|
|
4291
|
+
websocket.emit('error', err);
|
|
4292
|
+
}
|
|
3686
4293
|
}
|
|
3687
4294
|
|
|
3688
4295
|
/**
|
|
@@ -3697,11 +4304,12 @@ function receiverOnFinish() {
|
|
|
3697
4304
|
/**
|
|
3698
4305
|
* The listener of the `Receiver` `'message'` event.
|
|
3699
4306
|
*
|
|
3700
|
-
* @param {
|
|
4307
|
+
* @param {Buffer|ArrayBuffer|Buffer[])} data The message
|
|
4308
|
+
* @param {Boolean} isBinary Specifies whether the message is binary or not
|
|
3701
4309
|
* @private
|
|
3702
4310
|
*/
|
|
3703
|
-
function receiverOnMessage(data) {
|
|
3704
|
-
this[kWebSocket$1].emit('message', data);
|
|
4311
|
+
function receiverOnMessage(data, isBinary) {
|
|
4312
|
+
this[kWebSocket$1].emit('message', data, isBinary);
|
|
3705
4313
|
}
|
|
3706
4314
|
|
|
3707
4315
|
/**
|
|
@@ -3713,7 +4321,7 @@ function receiverOnMessage(data) {
|
|
|
3713
4321
|
function receiverOnPing(data) {
|
|
3714
4322
|
const websocket = this[kWebSocket$1];
|
|
3715
4323
|
|
|
3716
|
-
websocket.pong(data, !
|
|
4324
|
+
if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);
|
|
3717
4325
|
websocket.emit('ping', data);
|
|
3718
4326
|
}
|
|
3719
4327
|
|
|
@@ -3738,7 +4346,48 @@ function resume(stream) {
|
|
|
3738
4346
|
}
|
|
3739
4347
|
|
|
3740
4348
|
/**
|
|
3741
|
-
* The
|
|
4349
|
+
* The `Sender` error event handler.
|
|
4350
|
+
*
|
|
4351
|
+
* @param {Error} The error
|
|
4352
|
+
* @private
|
|
4353
|
+
*/
|
|
4354
|
+
function senderOnError(err) {
|
|
4355
|
+
const websocket = this[kWebSocket$1];
|
|
4356
|
+
|
|
4357
|
+
if (websocket.readyState === WebSocket$1.CLOSED) return;
|
|
4358
|
+
if (websocket.readyState === WebSocket$1.OPEN) {
|
|
4359
|
+
websocket._readyState = WebSocket$1.CLOSING;
|
|
4360
|
+
setCloseTimer(websocket);
|
|
4361
|
+
}
|
|
4362
|
+
|
|
4363
|
+
//
|
|
4364
|
+
// `socket.end()` is used instead of `socket.destroy()` to allow the other
|
|
4365
|
+
// peer to finish sending queued data. There is no need to set a timer here
|
|
4366
|
+
// because `CLOSING` means that it is already set or not needed.
|
|
4367
|
+
//
|
|
4368
|
+
this._socket.end();
|
|
4369
|
+
|
|
4370
|
+
if (!websocket._errorEmitted) {
|
|
4371
|
+
websocket._errorEmitted = true;
|
|
4372
|
+
websocket.emit('error', err);
|
|
4373
|
+
}
|
|
4374
|
+
}
|
|
4375
|
+
|
|
4376
|
+
/**
|
|
4377
|
+
* Set a timer to destroy the underlying raw socket of a WebSocket.
|
|
4378
|
+
*
|
|
4379
|
+
* @param {WebSocket} websocket The WebSocket instance
|
|
4380
|
+
* @private
|
|
4381
|
+
*/
|
|
4382
|
+
function setCloseTimer(websocket) {
|
|
4383
|
+
websocket._closeTimer = setTimeout(
|
|
4384
|
+
websocket._socket.destroy.bind(websocket._socket),
|
|
4385
|
+
websocket._closeTimeout
|
|
4386
|
+
);
|
|
4387
|
+
}
|
|
4388
|
+
|
|
4389
|
+
/**
|
|
4390
|
+
* The listener of the socket `'close'` event.
|
|
3742
4391
|
*
|
|
3743
4392
|
* @private
|
|
3744
4393
|
*/
|
|
@@ -3749,25 +4398,25 @@ function socketOnClose() {
|
|
|
3749
4398
|
this.removeListener('data', socketOnData);
|
|
3750
4399
|
this.removeListener('end', socketOnEnd);
|
|
3751
4400
|
|
|
3752
|
-
websocket._readyState = WebSocket$
|
|
3753
|
-
|
|
3754
|
-
let chunk;
|
|
4401
|
+
websocket._readyState = WebSocket$1.CLOSING;
|
|
3755
4402
|
|
|
3756
4403
|
//
|
|
3757
4404
|
// The close frame might not have been received or the `'end'` event emitted,
|
|
3758
4405
|
// for example, if the socket was destroyed due to an error. Ensure that the
|
|
3759
4406
|
// `receiver` stream is closed after writing any remaining buffered data to
|
|
3760
4407
|
// it. If the readable side of the socket is in flowing mode then there is no
|
|
3761
|
-
// buffered data as everything has been already written
|
|
3762
|
-
//
|
|
3763
|
-
//
|
|
4408
|
+
// buffered data as everything has been already written. If instead, the
|
|
4409
|
+
// socket is paused, any possible buffered data will be read as a single
|
|
4410
|
+
// chunk.
|
|
3764
4411
|
//
|
|
3765
4412
|
if (
|
|
3766
4413
|
!this._readableState.endEmitted &&
|
|
3767
4414
|
!websocket._closeFrameReceived &&
|
|
3768
4415
|
!websocket._receiver._writableState.errorEmitted &&
|
|
3769
|
-
|
|
4416
|
+
this._readableState.length !== 0
|
|
3770
4417
|
) {
|
|
4418
|
+
const chunk = this.read(this._readableState.length);
|
|
4419
|
+
|
|
3771
4420
|
websocket._receiver.write(chunk);
|
|
3772
4421
|
}
|
|
3773
4422
|
|
|
@@ -3789,7 +4438,7 @@ function socketOnClose() {
|
|
|
3789
4438
|
}
|
|
3790
4439
|
|
|
3791
4440
|
/**
|
|
3792
|
-
* The listener of the
|
|
4441
|
+
* The listener of the socket `'data'` event.
|
|
3793
4442
|
*
|
|
3794
4443
|
* @param {Buffer} chunk A chunk of data
|
|
3795
4444
|
* @private
|
|
@@ -3801,680 +4450,54 @@ function socketOnData(chunk) {
|
|
|
3801
4450
|
}
|
|
3802
4451
|
|
|
3803
4452
|
/**
|
|
3804
|
-
* The listener of the
|
|
4453
|
+
* The listener of the socket `'end'` event.
|
|
3805
4454
|
*
|
|
3806
4455
|
* @private
|
|
3807
4456
|
*/
|
|
3808
4457
|
function socketOnEnd() {
|
|
3809
4458
|
const websocket = this[kWebSocket$1];
|
|
3810
4459
|
|
|
3811
|
-
websocket._readyState = WebSocket$
|
|
4460
|
+
websocket._readyState = WebSocket$1.CLOSING;
|
|
3812
4461
|
websocket._receiver.end();
|
|
3813
4462
|
this.end();
|
|
3814
4463
|
}
|
|
3815
4464
|
|
|
3816
4465
|
/**
|
|
3817
|
-
* The listener of the
|
|
4466
|
+
* The listener of the socket `'error'` event.
|
|
3818
4467
|
*
|
|
3819
4468
|
* @private
|
|
3820
4469
|
*/
|
|
3821
|
-
function socketOnError
|
|
4470
|
+
function socketOnError() {
|
|
3822
4471
|
const websocket = this[kWebSocket$1];
|
|
3823
4472
|
|
|
3824
|
-
this.removeListener('error', socketOnError
|
|
4473
|
+
this.removeListener('error', socketOnError);
|
|
3825
4474
|
this.on('error', NOOP);
|
|
3826
4475
|
|
|
3827
4476
|
if (websocket) {
|
|
3828
|
-
websocket._readyState = WebSocket$
|
|
3829
|
-
this.destroy();
|
|
3830
|
-
}
|
|
3831
|
-
}
|
|
3832
|
-
|
|
3833
|
-
const { Duplex } = require$$0$2;
|
|
3834
|
-
|
|
3835
|
-
/**
|
|
3836
|
-
* Emits the `'close'` event on a stream.
|
|
3837
|
-
*
|
|
3838
|
-
* @param {Duplex} stream The stream.
|
|
3839
|
-
* @private
|
|
3840
|
-
*/
|
|
3841
|
-
function emitClose$1(stream) {
|
|
3842
|
-
stream.emit('close');
|
|
3843
|
-
}
|
|
3844
|
-
|
|
3845
|
-
/**
|
|
3846
|
-
* The listener of the `'end'` event.
|
|
3847
|
-
*
|
|
3848
|
-
* @private
|
|
3849
|
-
*/
|
|
3850
|
-
function duplexOnEnd() {
|
|
3851
|
-
if (!this.destroyed && this._writableState.finished) {
|
|
4477
|
+
websocket._readyState = WebSocket$1.CLOSING;
|
|
3852
4478
|
this.destroy();
|
|
3853
4479
|
}
|
|
3854
4480
|
}
|
|
3855
4481
|
|
|
3856
|
-
|
|
3857
|
-
* The listener of the `'error'` event.
|
|
3858
|
-
*
|
|
3859
|
-
* @param {Error} err The error
|
|
3860
|
-
* @private
|
|
3861
|
-
*/
|
|
3862
|
-
function duplexOnError(err) {
|
|
3863
|
-
this.removeListener('error', duplexOnError);
|
|
3864
|
-
this.destroy();
|
|
3865
|
-
if (this.listenerCount('error') === 0) {
|
|
3866
|
-
// Do not suppress the throwing behavior.
|
|
3867
|
-
this.emit('error', err);
|
|
3868
|
-
}
|
|
3869
|
-
}
|
|
3870
|
-
|
|
3871
|
-
/**
|
|
3872
|
-
* Wraps a `WebSocket` in a duplex stream.
|
|
3873
|
-
*
|
|
3874
|
-
* @param {WebSocket} ws The `WebSocket` to wrap
|
|
3875
|
-
* @param {Object} [options] The options for the `Duplex` constructor
|
|
3876
|
-
* @return {Duplex} The duplex stream
|
|
3877
|
-
* @public
|
|
3878
|
-
*/
|
|
3879
|
-
function createWebSocketStream(ws, options) {
|
|
3880
|
-
let resumeOnReceiverDrain = true;
|
|
3881
|
-
let terminateOnDestroy = true;
|
|
3882
|
-
|
|
3883
|
-
function receiverOnDrain() {
|
|
3884
|
-
if (resumeOnReceiverDrain) ws._socket.resume();
|
|
3885
|
-
}
|
|
3886
|
-
|
|
3887
|
-
if (ws.readyState === ws.CONNECTING) {
|
|
3888
|
-
ws.once('open', function open() {
|
|
3889
|
-
ws._receiver.removeAllListeners('drain');
|
|
3890
|
-
ws._receiver.on('drain', receiverOnDrain);
|
|
3891
|
-
});
|
|
3892
|
-
} else {
|
|
3893
|
-
ws._receiver.removeAllListeners('drain');
|
|
3894
|
-
ws._receiver.on('drain', receiverOnDrain);
|
|
3895
|
-
}
|
|
3896
|
-
|
|
3897
|
-
const duplex = new Duplex({
|
|
3898
|
-
...options,
|
|
3899
|
-
autoDestroy: false,
|
|
3900
|
-
emitClose: false,
|
|
3901
|
-
objectMode: false,
|
|
3902
|
-
writableObjectMode: false
|
|
3903
|
-
});
|
|
3904
|
-
|
|
3905
|
-
ws.on('message', function message(msg) {
|
|
3906
|
-
if (!duplex.push(msg)) {
|
|
3907
|
-
resumeOnReceiverDrain = false;
|
|
3908
|
-
ws._socket.pause();
|
|
3909
|
-
}
|
|
3910
|
-
});
|
|
3911
|
-
|
|
3912
|
-
ws.once('error', function error(err) {
|
|
3913
|
-
if (duplex.destroyed) return;
|
|
3914
|
-
|
|
3915
|
-
// Prevent `ws.terminate()` from being called by `duplex._destroy()`.
|
|
3916
|
-
//
|
|
3917
|
-
// - If the `'error'` event is emitted before the `'open'` event, then
|
|
3918
|
-
// `ws.terminate()` is a noop as no socket is assigned.
|
|
3919
|
-
// - Otherwise, the error is re-emitted by the listener of the `'error'`
|
|
3920
|
-
// event of the `Receiver` object. The listener already closes the
|
|
3921
|
-
// connection by calling `ws.close()`. This allows a close frame to be
|
|
3922
|
-
// sent to the other peer. If `ws.terminate()` is called right after this,
|
|
3923
|
-
// then the close frame might not be sent.
|
|
3924
|
-
terminateOnDestroy = false;
|
|
3925
|
-
duplex.destroy(err);
|
|
3926
|
-
});
|
|
3927
|
-
|
|
3928
|
-
ws.once('close', function close() {
|
|
3929
|
-
if (duplex.destroyed) return;
|
|
3930
|
-
|
|
3931
|
-
duplex.push(null);
|
|
3932
|
-
});
|
|
3933
|
-
|
|
3934
|
-
duplex._destroy = function (err, callback) {
|
|
3935
|
-
if (ws.readyState === ws.CLOSED) {
|
|
3936
|
-
callback(err);
|
|
3937
|
-
process.nextTick(emitClose$1, duplex);
|
|
3938
|
-
return;
|
|
3939
|
-
}
|
|
3940
|
-
|
|
3941
|
-
let called = false;
|
|
3942
|
-
|
|
3943
|
-
ws.once('error', function error(err) {
|
|
3944
|
-
called = true;
|
|
3945
|
-
callback(err);
|
|
3946
|
-
});
|
|
3947
|
-
|
|
3948
|
-
ws.once('close', function close() {
|
|
3949
|
-
if (!called) callback(err);
|
|
3950
|
-
process.nextTick(emitClose$1, duplex);
|
|
3951
|
-
});
|
|
3952
|
-
|
|
3953
|
-
if (terminateOnDestroy) ws.terminate();
|
|
3954
|
-
};
|
|
3955
|
-
|
|
3956
|
-
duplex._final = function (callback) {
|
|
3957
|
-
if (ws.readyState === ws.CONNECTING) {
|
|
3958
|
-
ws.once('open', function open() {
|
|
3959
|
-
duplex._final(callback);
|
|
3960
|
-
});
|
|
3961
|
-
return;
|
|
3962
|
-
}
|
|
3963
|
-
|
|
3964
|
-
// If the value of the `_socket` property is `null` it means that `ws` is a
|
|
3965
|
-
// client websocket and the handshake failed. In fact, when this happens, a
|
|
3966
|
-
// socket is never assigned to the websocket. Wait for the `'error'` event
|
|
3967
|
-
// that will be emitted by the websocket.
|
|
3968
|
-
if (ws._socket === null) return;
|
|
3969
|
-
|
|
3970
|
-
if (ws._socket._writableState.finished) {
|
|
3971
|
-
callback();
|
|
3972
|
-
if (duplex._readableState.endEmitted) duplex.destroy();
|
|
3973
|
-
} else {
|
|
3974
|
-
ws._socket.once('finish', function finish() {
|
|
3975
|
-
// `duplex` is not destroyed here because the `'end'` event will be
|
|
3976
|
-
// emitted on `duplex` after this `'finish'` event. The EOF signaling
|
|
3977
|
-
// `null` chunk is, in fact, pushed when the websocket emits `'close'`.
|
|
3978
|
-
callback();
|
|
3979
|
-
});
|
|
3980
|
-
ws.close();
|
|
3981
|
-
}
|
|
3982
|
-
};
|
|
3983
|
-
|
|
3984
|
-
duplex._read = function () {
|
|
3985
|
-
if (
|
|
3986
|
-
(ws.readyState === ws.OPEN || ws.readyState === ws.CLOSING) &&
|
|
3987
|
-
!resumeOnReceiverDrain
|
|
3988
|
-
) {
|
|
3989
|
-
resumeOnReceiverDrain = true;
|
|
3990
|
-
if (!ws._receiver._writableState.needDrain) ws._socket.resume();
|
|
3991
|
-
}
|
|
3992
|
-
};
|
|
3993
|
-
|
|
3994
|
-
duplex._write = function (chunk, encoding, callback) {
|
|
3995
|
-
if (ws.readyState === ws.CONNECTING) {
|
|
3996
|
-
ws.once('open', function open() {
|
|
3997
|
-
duplex._write(chunk, encoding, callback);
|
|
3998
|
-
});
|
|
3999
|
-
return;
|
|
4000
|
-
}
|
|
4001
|
-
|
|
4002
|
-
ws.send(chunk, callback);
|
|
4003
|
-
};
|
|
4004
|
-
|
|
4005
|
-
duplex.on('end', duplexOnEnd);
|
|
4006
|
-
duplex.on('error', duplexOnError);
|
|
4007
|
-
return duplex;
|
|
4008
|
-
}
|
|
4009
|
-
|
|
4010
|
-
var stream = createWebSocketStream;
|
|
4011
|
-
|
|
4012
|
-
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls|https$" }] */
|
|
4013
|
-
|
|
4014
|
-
const EventEmitter = require$$0$3;
|
|
4015
|
-
const http = require$$2$1;
|
|
4016
|
-
const { createHash } = require$$5;
|
|
4017
|
-
|
|
4018
|
-
const PerMessageDeflate = permessageDeflate;
|
|
4019
|
-
const WebSocket$2 = websocket;
|
|
4020
|
-
const { format, parse } = extension;
|
|
4021
|
-
const { GUID, kWebSocket } = constants;
|
|
4022
|
-
|
|
4023
|
-
const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
|
|
4024
|
-
|
|
4025
|
-
const RUNNING = 0;
|
|
4026
|
-
const CLOSING = 1;
|
|
4027
|
-
const CLOSED = 2;
|
|
4028
|
-
|
|
4029
|
-
/**
|
|
4030
|
-
* Class representing a WebSocket server.
|
|
4031
|
-
*
|
|
4032
|
-
* @extends EventEmitter
|
|
4033
|
-
*/
|
|
4034
|
-
class WebSocketServer extends EventEmitter {
|
|
4035
|
-
/**
|
|
4036
|
-
* Create a `WebSocketServer` instance.
|
|
4037
|
-
*
|
|
4038
|
-
* @param {Object} options Configuration options
|
|
4039
|
-
* @param {Number} [options.backlog=511] The maximum length of the queue of
|
|
4040
|
-
* pending connections
|
|
4041
|
-
* @param {Boolean} [options.clientTracking=true] Specifies whether or not to
|
|
4042
|
-
* track clients
|
|
4043
|
-
* @param {Function} [options.handleProtocols] A hook to handle protocols
|
|
4044
|
-
* @param {String} [options.host] The hostname where to bind the server
|
|
4045
|
-
* @param {Number} [options.maxPayload=104857600] The maximum allowed message
|
|
4046
|
-
* size
|
|
4047
|
-
* @param {Boolean} [options.noServer=false] Enable no server mode
|
|
4048
|
-
* @param {String} [options.path] Accept only connections matching this path
|
|
4049
|
-
* @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable
|
|
4050
|
-
* permessage-deflate
|
|
4051
|
-
* @param {Number} [options.port] The port where to bind the server
|
|
4052
|
-
* @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S
|
|
4053
|
-
* server to use
|
|
4054
|
-
* @param {Function} [options.verifyClient] A hook to reject connections
|
|
4055
|
-
* @param {Function} [callback] A listener for the `listening` event
|
|
4056
|
-
*/
|
|
4057
|
-
constructor(options, callback) {
|
|
4058
|
-
super();
|
|
4059
|
-
|
|
4060
|
-
options = {
|
|
4061
|
-
maxPayload: 100 * 1024 * 1024,
|
|
4062
|
-
perMessageDeflate: false,
|
|
4063
|
-
handleProtocols: null,
|
|
4064
|
-
clientTracking: true,
|
|
4065
|
-
verifyClient: null,
|
|
4066
|
-
noServer: false,
|
|
4067
|
-
backlog: null, // use default (511 as implemented in net.js)
|
|
4068
|
-
server: null,
|
|
4069
|
-
host: null,
|
|
4070
|
-
path: null,
|
|
4071
|
-
port: null,
|
|
4072
|
-
...options
|
|
4073
|
-
};
|
|
4074
|
-
|
|
4075
|
-
if (
|
|
4076
|
-
(options.port == null && !options.server && !options.noServer) ||
|
|
4077
|
-
(options.port != null && (options.server || options.noServer)) ||
|
|
4078
|
-
(options.server && options.noServer)
|
|
4079
|
-
) {
|
|
4080
|
-
throw new TypeError(
|
|
4081
|
-
'One and only one of the "port", "server", or "noServer" options ' +
|
|
4082
|
-
'must be specified'
|
|
4083
|
-
);
|
|
4084
|
-
}
|
|
4085
|
-
|
|
4086
|
-
if (options.port != null) {
|
|
4087
|
-
this._server = http.createServer((req, res) => {
|
|
4088
|
-
const body = http.STATUS_CODES[426];
|
|
4089
|
-
|
|
4090
|
-
res.writeHead(426, {
|
|
4091
|
-
'Content-Length': body.length,
|
|
4092
|
-
'Content-Type': 'text/plain'
|
|
4093
|
-
});
|
|
4094
|
-
res.end(body);
|
|
4095
|
-
});
|
|
4096
|
-
this._server.listen(
|
|
4097
|
-
options.port,
|
|
4098
|
-
options.host,
|
|
4099
|
-
options.backlog,
|
|
4100
|
-
callback
|
|
4101
|
-
);
|
|
4102
|
-
} else if (options.server) {
|
|
4103
|
-
this._server = options.server;
|
|
4104
|
-
}
|
|
4105
|
-
|
|
4106
|
-
if (this._server) {
|
|
4107
|
-
const emitConnection = this.emit.bind(this, 'connection');
|
|
4108
|
-
|
|
4109
|
-
this._removeListeners = addListeners(this._server, {
|
|
4110
|
-
listening: this.emit.bind(this, 'listening'),
|
|
4111
|
-
error: this.emit.bind(this, 'error'),
|
|
4112
|
-
upgrade: (req, socket, head) => {
|
|
4113
|
-
this.handleUpgrade(req, socket, head, emitConnection);
|
|
4114
|
-
}
|
|
4115
|
-
});
|
|
4116
|
-
}
|
|
4117
|
-
|
|
4118
|
-
if (options.perMessageDeflate === true) options.perMessageDeflate = {};
|
|
4119
|
-
if (options.clientTracking) this.clients = new Set();
|
|
4120
|
-
this.options = options;
|
|
4121
|
-
this._state = RUNNING;
|
|
4122
|
-
}
|
|
4123
|
-
|
|
4124
|
-
/**
|
|
4125
|
-
* Returns the bound address, the address family name, and port of the server
|
|
4126
|
-
* as reported by the operating system if listening on an IP socket.
|
|
4127
|
-
* If the server is listening on a pipe or UNIX domain socket, the name is
|
|
4128
|
-
* returned as a string.
|
|
4129
|
-
*
|
|
4130
|
-
* @return {(Object|String|null)} The address of the server
|
|
4131
|
-
* @public
|
|
4132
|
-
*/
|
|
4133
|
-
address() {
|
|
4134
|
-
if (this.options.noServer) {
|
|
4135
|
-
throw new Error('The server is operating in "noServer" mode');
|
|
4136
|
-
}
|
|
4137
|
-
|
|
4138
|
-
if (!this._server) return null;
|
|
4139
|
-
return this._server.address();
|
|
4140
|
-
}
|
|
4141
|
-
|
|
4142
|
-
/**
|
|
4143
|
-
* Close the server.
|
|
4144
|
-
*
|
|
4145
|
-
* @param {Function} [cb] Callback
|
|
4146
|
-
* @public
|
|
4147
|
-
*/
|
|
4148
|
-
close(cb) {
|
|
4149
|
-
if (cb) this.once('close', cb);
|
|
4150
|
-
|
|
4151
|
-
if (this._state === CLOSED) {
|
|
4152
|
-
process.nextTick(emitClose, this);
|
|
4153
|
-
return;
|
|
4154
|
-
}
|
|
4155
|
-
|
|
4156
|
-
if (this._state === CLOSING) return;
|
|
4157
|
-
this._state = CLOSING;
|
|
4158
|
-
|
|
4159
|
-
//
|
|
4160
|
-
// Terminate all associated clients.
|
|
4161
|
-
//
|
|
4162
|
-
if (this.clients) {
|
|
4163
|
-
for (const client of this.clients) client.terminate();
|
|
4164
|
-
}
|
|
4165
|
-
|
|
4166
|
-
const server = this._server;
|
|
4167
|
-
|
|
4168
|
-
if (server) {
|
|
4169
|
-
this._removeListeners();
|
|
4170
|
-
this._removeListeners = this._server = null;
|
|
4171
|
-
|
|
4172
|
-
//
|
|
4173
|
-
// Close the http server if it was internally created.
|
|
4174
|
-
//
|
|
4175
|
-
if (this.options.port != null) {
|
|
4176
|
-
server.close(emitClose.bind(undefined, this));
|
|
4177
|
-
return;
|
|
4178
|
-
}
|
|
4179
|
-
}
|
|
4180
|
-
|
|
4181
|
-
process.nextTick(emitClose, this);
|
|
4182
|
-
}
|
|
4183
|
-
|
|
4184
|
-
/**
|
|
4185
|
-
* See if a given request should be handled by this server instance.
|
|
4186
|
-
*
|
|
4187
|
-
* @param {http.IncomingMessage} req Request object to inspect
|
|
4188
|
-
* @return {Boolean} `true` if the request is valid, else `false`
|
|
4189
|
-
* @public
|
|
4190
|
-
*/
|
|
4191
|
-
shouldHandle(req) {
|
|
4192
|
-
if (this.options.path) {
|
|
4193
|
-
const index = req.url.indexOf('?');
|
|
4194
|
-
const pathname = index !== -1 ? req.url.slice(0, index) : req.url;
|
|
4195
|
-
|
|
4196
|
-
if (pathname !== this.options.path) return false;
|
|
4197
|
-
}
|
|
4198
|
-
|
|
4199
|
-
return true;
|
|
4200
|
-
}
|
|
4201
|
-
|
|
4202
|
-
/**
|
|
4203
|
-
* Handle a HTTP Upgrade request.
|
|
4204
|
-
*
|
|
4205
|
-
* @param {http.IncomingMessage} req The request object
|
|
4206
|
-
* @param {(net.Socket|tls.Socket)} socket The network socket between the
|
|
4207
|
-
* server and client
|
|
4208
|
-
* @param {Buffer} head The first packet of the upgraded stream
|
|
4209
|
-
* @param {Function} cb Callback
|
|
4210
|
-
* @public
|
|
4211
|
-
*/
|
|
4212
|
-
handleUpgrade(req, socket, head, cb) {
|
|
4213
|
-
socket.on('error', socketOnError);
|
|
4214
|
-
|
|
4215
|
-
const key =
|
|
4216
|
-
req.headers['sec-websocket-key'] !== undefined
|
|
4217
|
-
? req.headers['sec-websocket-key'].trim()
|
|
4218
|
-
: false;
|
|
4219
|
-
const upgrade = req.headers.upgrade;
|
|
4220
|
-
const version = +req.headers['sec-websocket-version'];
|
|
4221
|
-
const extensions = {};
|
|
4222
|
-
|
|
4223
|
-
if (
|
|
4224
|
-
req.method !== 'GET' ||
|
|
4225
|
-
upgrade === undefined ||
|
|
4226
|
-
upgrade.toLowerCase() !== 'websocket' ||
|
|
4227
|
-
!key ||
|
|
4228
|
-
!keyRegex.test(key) ||
|
|
4229
|
-
(version !== 8 && version !== 13) ||
|
|
4230
|
-
!this.shouldHandle(req)
|
|
4231
|
-
) {
|
|
4232
|
-
return abortHandshake(socket, 400);
|
|
4233
|
-
}
|
|
4234
|
-
|
|
4235
|
-
if (this.options.perMessageDeflate) {
|
|
4236
|
-
const perMessageDeflate = new PerMessageDeflate(
|
|
4237
|
-
this.options.perMessageDeflate,
|
|
4238
|
-
true,
|
|
4239
|
-
this.options.maxPayload
|
|
4240
|
-
);
|
|
4241
|
-
|
|
4242
|
-
try {
|
|
4243
|
-
const offers = parse(req.headers['sec-websocket-extensions']);
|
|
4244
|
-
|
|
4245
|
-
if (offers[PerMessageDeflate.extensionName]) {
|
|
4246
|
-
perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
|
|
4247
|
-
extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
|
|
4248
|
-
}
|
|
4249
|
-
} catch (err) {
|
|
4250
|
-
return abortHandshake(socket, 400);
|
|
4251
|
-
}
|
|
4252
|
-
}
|
|
4253
|
-
|
|
4254
|
-
//
|
|
4255
|
-
// Optionally call external client verification handler.
|
|
4256
|
-
//
|
|
4257
|
-
if (this.options.verifyClient) {
|
|
4258
|
-
const info = {
|
|
4259
|
-
origin:
|
|
4260
|
-
req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
|
|
4261
|
-
secure: !!(req.socket.authorized || req.socket.encrypted),
|
|
4262
|
-
req
|
|
4263
|
-
};
|
|
4264
|
-
|
|
4265
|
-
if (this.options.verifyClient.length === 2) {
|
|
4266
|
-
this.options.verifyClient(info, (verified, code, message, headers) => {
|
|
4267
|
-
if (!verified) {
|
|
4268
|
-
return abortHandshake(socket, code || 401, message, headers);
|
|
4269
|
-
}
|
|
4270
|
-
|
|
4271
|
-
this.completeUpgrade(key, extensions, req, socket, head, cb);
|
|
4272
|
-
});
|
|
4273
|
-
return;
|
|
4274
|
-
}
|
|
4275
|
-
|
|
4276
|
-
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
|
|
4277
|
-
}
|
|
4278
|
-
|
|
4279
|
-
this.completeUpgrade(key, extensions, req, socket, head, cb);
|
|
4280
|
-
}
|
|
4281
|
-
|
|
4282
|
-
/**
|
|
4283
|
-
* Upgrade the connection to WebSocket.
|
|
4284
|
-
*
|
|
4285
|
-
* @param {String} key The value of the `Sec-WebSocket-Key` header
|
|
4286
|
-
* @param {Object} extensions The accepted extensions
|
|
4287
|
-
* @param {http.IncomingMessage} req The request object
|
|
4288
|
-
* @param {(net.Socket|tls.Socket)} socket The network socket between the
|
|
4289
|
-
* server and client
|
|
4290
|
-
* @param {Buffer} head The first packet of the upgraded stream
|
|
4291
|
-
* @param {Function} cb Callback
|
|
4292
|
-
* @throws {Error} If called more than once with the same socket
|
|
4293
|
-
* @private
|
|
4294
|
-
*/
|
|
4295
|
-
completeUpgrade(key, extensions, req, socket, head, cb) {
|
|
4296
|
-
//
|
|
4297
|
-
// Destroy the socket if the client has already sent a FIN packet.
|
|
4298
|
-
//
|
|
4299
|
-
if (!socket.readable || !socket.writable) return socket.destroy();
|
|
4300
|
-
|
|
4301
|
-
if (socket[kWebSocket]) {
|
|
4302
|
-
throw new Error(
|
|
4303
|
-
'server.handleUpgrade() was called more than once with the same ' +
|
|
4304
|
-
'socket, possibly due to a misconfiguration'
|
|
4305
|
-
);
|
|
4306
|
-
}
|
|
4307
|
-
|
|
4308
|
-
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
4309
|
-
|
|
4310
|
-
const digest = createHash('sha1')
|
|
4311
|
-
.update(key + GUID)
|
|
4312
|
-
.digest('base64');
|
|
4313
|
-
|
|
4314
|
-
const headers = [
|
|
4315
|
-
'HTTP/1.1 101 Switching Protocols',
|
|
4316
|
-
'Upgrade: websocket',
|
|
4317
|
-
'Connection: Upgrade',
|
|
4318
|
-
`Sec-WebSocket-Accept: ${digest}`
|
|
4319
|
-
];
|
|
4320
|
-
|
|
4321
|
-
const ws = new WebSocket$2(null);
|
|
4322
|
-
let protocol = req.headers['sec-websocket-protocol'];
|
|
4323
|
-
|
|
4324
|
-
if (protocol) {
|
|
4325
|
-
protocol = protocol.split(',').map(trim);
|
|
4326
|
-
|
|
4327
|
-
//
|
|
4328
|
-
// Optionally call external protocol selection handler.
|
|
4329
|
-
//
|
|
4330
|
-
if (this.options.handleProtocols) {
|
|
4331
|
-
protocol = this.options.handleProtocols(protocol, req);
|
|
4332
|
-
} else {
|
|
4333
|
-
protocol = protocol[0];
|
|
4334
|
-
}
|
|
4335
|
-
|
|
4336
|
-
if (protocol) {
|
|
4337
|
-
headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
|
|
4338
|
-
ws._protocol = protocol;
|
|
4339
|
-
}
|
|
4340
|
-
}
|
|
4341
|
-
|
|
4342
|
-
if (extensions[PerMessageDeflate.extensionName]) {
|
|
4343
|
-
const params = extensions[PerMessageDeflate.extensionName].params;
|
|
4344
|
-
const value = format({
|
|
4345
|
-
[PerMessageDeflate.extensionName]: [params]
|
|
4346
|
-
});
|
|
4347
|
-
headers.push(`Sec-WebSocket-Extensions: ${value}`);
|
|
4348
|
-
ws._extensions = extensions;
|
|
4349
|
-
}
|
|
4350
|
-
|
|
4351
|
-
//
|
|
4352
|
-
// Allow external modification/inspection of handshake headers.
|
|
4353
|
-
//
|
|
4354
|
-
this.emit('headers', headers, req);
|
|
4355
|
-
|
|
4356
|
-
socket.write(headers.concat('\r\n').join('\r\n'));
|
|
4357
|
-
socket.removeListener('error', socketOnError);
|
|
4358
|
-
|
|
4359
|
-
ws.setSocket(socket, head, this.options.maxPayload);
|
|
4360
|
-
|
|
4361
|
-
if (this.clients) {
|
|
4362
|
-
this.clients.add(ws);
|
|
4363
|
-
ws.on('close', () => this.clients.delete(ws));
|
|
4364
|
-
}
|
|
4365
|
-
|
|
4366
|
-
cb(ws, req);
|
|
4367
|
-
}
|
|
4368
|
-
}
|
|
4369
|
-
|
|
4370
|
-
var websocketServer = WebSocketServer;
|
|
4371
|
-
|
|
4372
|
-
/**
|
|
4373
|
-
* Add event listeners on an `EventEmitter` using a map of <event, listener>
|
|
4374
|
-
* pairs.
|
|
4375
|
-
*
|
|
4376
|
-
* @param {EventEmitter} server The event emitter
|
|
4377
|
-
* @param {Object.<String, Function>} map The listeners to add
|
|
4378
|
-
* @return {Function} A function that will remove the added listeners when
|
|
4379
|
-
* called
|
|
4380
|
-
* @private
|
|
4381
|
-
*/
|
|
4382
|
-
function addListeners(server, map) {
|
|
4383
|
-
for (const event of Object.keys(map)) server.on(event, map[event]);
|
|
4384
|
-
|
|
4385
|
-
return function removeListeners() {
|
|
4386
|
-
for (const event of Object.keys(map)) {
|
|
4387
|
-
server.removeListener(event, map[event]);
|
|
4388
|
-
}
|
|
4389
|
-
};
|
|
4390
|
-
}
|
|
4391
|
-
|
|
4392
|
-
/**
|
|
4393
|
-
* Emit a `'close'` event on an `EventEmitter`.
|
|
4394
|
-
*
|
|
4395
|
-
* @param {EventEmitter} server The event emitter
|
|
4396
|
-
* @private
|
|
4397
|
-
*/
|
|
4398
|
-
function emitClose(server) {
|
|
4399
|
-
server._state = CLOSED;
|
|
4400
|
-
server.emit('close');
|
|
4401
|
-
}
|
|
4402
|
-
|
|
4403
|
-
/**
|
|
4404
|
-
* Handle premature socket errors.
|
|
4405
|
-
*
|
|
4406
|
-
* @private
|
|
4407
|
-
*/
|
|
4408
|
-
function socketOnError() {
|
|
4409
|
-
this.destroy();
|
|
4410
|
-
}
|
|
4411
|
-
|
|
4412
|
-
/**
|
|
4413
|
-
* Close the connection when preconditions are not fulfilled.
|
|
4414
|
-
*
|
|
4415
|
-
* @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request
|
|
4416
|
-
* @param {Number} code The HTTP response status code
|
|
4417
|
-
* @param {String} [message] The HTTP response body
|
|
4418
|
-
* @param {Object} [headers] Additional HTTP response headers
|
|
4419
|
-
* @private
|
|
4420
|
-
*/
|
|
4421
|
-
function abortHandshake(socket, code, message, headers) {
|
|
4422
|
-
if (socket.writable) {
|
|
4423
|
-
message = message || http.STATUS_CODES[code];
|
|
4424
|
-
headers = {
|
|
4425
|
-
Connection: 'close',
|
|
4426
|
-
'Content-Type': 'text/html',
|
|
4427
|
-
'Content-Length': Buffer.byteLength(message),
|
|
4428
|
-
...headers
|
|
4429
|
-
};
|
|
4430
|
-
|
|
4431
|
-
socket.write(
|
|
4432
|
-
`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
|
|
4433
|
-
Object.keys(headers)
|
|
4434
|
-
.map((h) => `${h}: ${headers[h]}`)
|
|
4435
|
-
.join('\r\n') +
|
|
4436
|
-
'\r\n\r\n' +
|
|
4437
|
-
message
|
|
4438
|
-
);
|
|
4439
|
-
}
|
|
4440
|
-
|
|
4441
|
-
socket.removeListener('error', socketOnError);
|
|
4442
|
-
socket.destroy();
|
|
4443
|
-
}
|
|
4444
|
-
|
|
4445
|
-
/**
|
|
4446
|
-
* Remove whitespace characters from both ends of a string.
|
|
4447
|
-
*
|
|
4448
|
-
* @param {String} str The string
|
|
4449
|
-
* @return {String} A new string representing `str` stripped of whitespace
|
|
4450
|
-
* characters from both its beginning and end
|
|
4451
|
-
* @private
|
|
4452
|
-
*/
|
|
4453
|
-
function trim(str) {
|
|
4454
|
-
return str.trim();
|
|
4455
|
-
}
|
|
4456
|
-
|
|
4457
|
-
const WebSocket$1 = websocket;
|
|
4482
|
+
var WebSocket$2 = /*@__PURE__*/getDefaultExportFromCjs(websocket);
|
|
4458
4483
|
|
|
4459
|
-
WebSocket$
|
|
4460
|
-
|
|
4461
|
-
WebSocket$1.Receiver = receiver;
|
|
4462
|
-
WebSocket$1.Sender = sender;
|
|
4484
|
+
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^WebSocket$" }] */
|
|
4485
|
+
const { Duplex: Duplex$1 } = require$$0$3;
|
|
4463
4486
|
|
|
4464
|
-
|
|
4487
|
+
const { tokenChars } = validationExports;
|
|
4465
4488
|
|
|
4466
|
-
|
|
4489
|
+
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex$", "caughtErrors": "none" }] */
|
|
4490
|
+
const { Duplex } = require$$0$3;
|
|
4491
|
+
const { createHash } = require$$1$1;
|
|
4492
|
+
const { CLOSE_TIMEOUT, GUID, kWebSocket } = constants;
|
|
4467
4493
|
|
|
4468
4494
|
/**
|
|
4469
4495
|
* Re-exports WebSocket and WebSocketServer from the ws package.
|
|
4470
4496
|
*
|
|
4471
|
-
* ws is a CJS module
|
|
4472
|
-
*
|
|
4473
|
-
* around that by extracting them from the default export and re-exporting
|
|
4474
|
-
* them as merged type+value pairs.
|
|
4497
|
+
* ws is a CJS module with different shapes for default and namespace imports.
|
|
4498
|
+
* This module normalizes those imports and re-exports them as merged type+value pairs.
|
|
4475
4499
|
*/
|
|
4476
|
-
const WebSocket =
|
|
4477
|
-
ws$1.Server;
|
|
4500
|
+
const WebSocket = WebSocket$2;
|
|
4478
4501
|
|
|
4479
4502
|
const CONFIG_FILENAME = ".babyloninspector";
|
|
4480
4503
|
const DefaultBrowserPort = 4400;
|