crossws 0.2.4 → 0.3.1
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/README.md +8 -9
- package/adapters/cloudflare-durable.d.ts +2 -0
- package/adapters/sse.d.ts +2 -0
- package/dist/adapters/bun.d.mts +25 -6
- package/dist/adapters/bun.d.ts +25 -6
- package/dist/adapters/bun.mjs +54 -62
- package/dist/adapters/cloudflare-durable.d.mts +20 -0
- package/dist/adapters/cloudflare-durable.d.ts +20 -0
- package/dist/adapters/cloudflare-durable.mjs +132 -0
- package/dist/adapters/cloudflare.d.mts +5 -5
- package/dist/adapters/cloudflare.d.ts +5 -5
- package/dist/adapters/cloudflare.mjs +56 -49
- package/dist/adapters/deno.d.mts +10 -3
- package/dist/adapters/deno.d.ts +10 -3
- package/dist/adapters/deno.mjs +54 -45
- package/dist/adapters/node.d.mts +4 -2
- package/dist/adapters/node.d.ts +4 -2
- package/dist/adapters/node.mjs +106 -82
- package/dist/adapters/sse.d.mts +12 -0
- package/dist/adapters/sse.d.ts +12 -0
- package/dist/adapters/sse.mjs +120 -0
- package/dist/adapters/uws.d.mts +45 -9
- package/dist/adapters/uws.d.ts +45 -9
- package/dist/adapters/uws.mjs +148 -124
- package/dist/index.d.mts +136 -4
- package/dist/index.d.ts +136 -4
- package/dist/index.mjs +1 -10
- package/dist/shared/crossws.B4sHId41.mjs +42 -0
- package/dist/shared/crossws.By9qWDAI.mjs +8 -0
- package/dist/shared/crossws.ChIJSJVK.d.mts +297 -0
- package/dist/shared/crossws.ChIJSJVK.d.ts +297 -0
- package/dist/shared/crossws.DTY7a69w.mjs +315 -0
- package/dist/shared/{crossws.a5db571c.mjs → crossws.YgHWLi0G.mjs} +284 -115
- package/dist/websocket/{index.d.mts → native.d.mts} +1 -1
- package/dist/websocket/{node.d.cts → native.d.ts} +1 -1
- package/dist/websocket/native.mjs +3 -0
- package/dist/websocket/node.d.mts +1 -1
- package/dist/websocket/node.d.ts +1 -1
- package/dist/websocket/node.mjs +1 -1
- package/dist/websocket/sse.d.mts +41 -0
- package/dist/websocket/sse.d.ts +41 -0
- package/dist/websocket/sse.mjs +127 -0
- package/package.json +78 -75
- package/dist/adapters/bun.cjs +0 -95
- package/dist/adapters/bun.d.cts +0 -17
- package/dist/adapters/cloudflare.cjs +0 -65
- package/dist/adapters/cloudflare.d.cts +0 -12
- package/dist/adapters/deno.cjs +0 -63
- package/dist/adapters/deno.d.cts +0 -15
- package/dist/adapters/node.cjs +0 -739
- package/dist/adapters/node.d.cts +0 -298
- package/dist/adapters/uws.cjs +0 -153
- package/dist/adapters/uws.d.cts +0 -19
- package/dist/index.cjs +0 -17
- package/dist/index.d.cts +0 -6
- package/dist/shared/crossws.2ed26345.cjs +0 -3931
- package/dist/shared/crossws.36b9e66f.cjs +0 -156
- package/dist/shared/crossws.381454fe.d.cts +0 -115
- package/dist/shared/crossws.381454fe.d.mts +0 -115
- package/dist/shared/crossws.381454fe.d.ts +0 -115
- package/dist/shared/crossws.77e89680.mjs +0 -149
- package/dist/websocket/index.cjs +0 -5
- package/dist/websocket/index.d.cts +0 -10
- package/dist/websocket/index.d.ts +0 -10
- package/dist/websocket/index.mjs +0 -3
- package/dist/websocket/node.cjs +0 -17
|
@@ -15,10 +15,16 @@ function getDefaultExportFromCjs (x) {
|
|
|
15
15
|
|
|
16
16
|
var bufferUtil$1 = {exports: {}};
|
|
17
17
|
|
|
18
|
+
const BINARY_TYPES$2 = ['nodebuffer', 'arraybuffer', 'fragments'];
|
|
19
|
+
const hasBlob$1 = typeof Blob !== 'undefined';
|
|
20
|
+
|
|
21
|
+
if (hasBlob$1) BINARY_TYPES$2.push('blob');
|
|
22
|
+
|
|
18
23
|
var constants = {
|
|
19
|
-
BINARY_TYPES:
|
|
24
|
+
BINARY_TYPES: BINARY_TYPES$2,
|
|
20
25
|
EMPTY_BUFFER: Buffer.alloc(0),
|
|
21
26
|
GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
|
|
27
|
+
hasBlob: hasBlob$1,
|
|
22
28
|
kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),
|
|
23
29
|
kListener: Symbol('kListener'),
|
|
24
30
|
kStatusCode: Symbol('status-code'),
|
|
@@ -734,6 +740,8 @@ var isValidUTF8_1;
|
|
|
734
740
|
|
|
735
741
|
const { isUtf8 } = require$$0$1;
|
|
736
742
|
|
|
743
|
+
const { hasBlob } = constants;
|
|
744
|
+
|
|
737
745
|
//
|
|
738
746
|
// Allowed token characters:
|
|
739
747
|
//
|
|
@@ -839,7 +847,27 @@ function _isValidUTF8(buf) {
|
|
|
839
847
|
return true;
|
|
840
848
|
}
|
|
841
849
|
|
|
850
|
+
/**
|
|
851
|
+
* Determines whether a value is a `Blob`.
|
|
852
|
+
*
|
|
853
|
+
* @param {*} value The value to be tested
|
|
854
|
+
* @return {Boolean} `true` if `value` is a `Blob`, else `false`
|
|
855
|
+
* @private
|
|
856
|
+
*/
|
|
857
|
+
function isBlob$2(value) {
|
|
858
|
+
return (
|
|
859
|
+
hasBlob &&
|
|
860
|
+
typeof value === 'object' &&
|
|
861
|
+
typeof value.arrayBuffer === 'function' &&
|
|
862
|
+
typeof value.type === 'string' &&
|
|
863
|
+
typeof value.stream === 'function' &&
|
|
864
|
+
(value[Symbol.toStringTag] === 'Blob' ||
|
|
865
|
+
value[Symbol.toStringTag] === 'File')
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
|
|
842
869
|
validation.exports = {
|
|
870
|
+
isBlob: isBlob$2,
|
|
843
871
|
isValidStatusCode: isValidStatusCode$2,
|
|
844
872
|
isValidUTF8: _isValidUTF8,
|
|
845
873
|
tokenChars: tokenChars$1
|
|
@@ -870,19 +898,12 @@ const {
|
|
|
870
898
|
BINARY_TYPES: BINARY_TYPES$1,
|
|
871
899
|
EMPTY_BUFFER: EMPTY_BUFFER$2,
|
|
872
900
|
kStatusCode: kStatusCode$1,
|
|
873
|
-
kWebSocket: kWebSocket$
|
|
901
|
+
kWebSocket: kWebSocket$2
|
|
874
902
|
} = constants;
|
|
875
903
|
const { concat, toArrayBuffer, unmask } = bufferUtilExports;
|
|
876
904
|
const { isValidStatusCode: isValidStatusCode$1, isValidUTF8 } = validationExports;
|
|
877
905
|
|
|
878
906
|
const FastBuffer = Buffer[Symbol.species];
|
|
879
|
-
const promise = Promise.resolve();
|
|
880
|
-
|
|
881
|
-
//
|
|
882
|
-
// `queueMicrotask()` is not available in Node.js < 11.
|
|
883
|
-
//
|
|
884
|
-
const queueTask =
|
|
885
|
-
typeof queueMicrotask === 'function' ? queueMicrotask : queueMicrotaskShim;
|
|
886
907
|
|
|
887
908
|
const GET_INFO = 0;
|
|
888
909
|
const GET_PAYLOAD_LENGTH_16 = 1;
|
|
@@ -902,7 +923,7 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
902
923
|
* Creates a Receiver instance.
|
|
903
924
|
*
|
|
904
925
|
* @param {Object} [options] Options object
|
|
905
|
-
* @param {Boolean} [options.allowSynchronousEvents=
|
|
926
|
+
* @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
|
|
906
927
|
* any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
|
|
907
928
|
* multiple times in the same tick
|
|
908
929
|
* @param {String} [options.binaryType=nodebuffer] The type for binary data
|
|
@@ -917,13 +938,16 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
917
938
|
constructor(options = {}) {
|
|
918
939
|
super();
|
|
919
940
|
|
|
920
|
-
this._allowSynchronousEvents =
|
|
941
|
+
this._allowSynchronousEvents =
|
|
942
|
+
options.allowSynchronousEvents !== undefined
|
|
943
|
+
? options.allowSynchronousEvents
|
|
944
|
+
: true;
|
|
921
945
|
this._binaryType = options.binaryType || BINARY_TYPES$1[0];
|
|
922
946
|
this._extensions = options.extensions || {};
|
|
923
947
|
this._isServer = !!options.isServer;
|
|
924
948
|
this._maxPayload = options.maxPayload | 0;
|
|
925
949
|
this._skipUTF8Validation = !!options.skipUTF8Validation;
|
|
926
|
-
this[kWebSocket$
|
|
950
|
+
this[kWebSocket$2] = undefined;
|
|
927
951
|
|
|
928
952
|
this._bufferedBytes = 0;
|
|
929
953
|
this._buffers = [];
|
|
@@ -1426,21 +1450,18 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1426
1450
|
data = concat(fragments, messageLength);
|
|
1427
1451
|
} else if (this._binaryType === 'arraybuffer') {
|
|
1428
1452
|
data = toArrayBuffer(concat(fragments, messageLength));
|
|
1453
|
+
} else if (this._binaryType === 'blob') {
|
|
1454
|
+
data = new Blob(fragments);
|
|
1429
1455
|
} else {
|
|
1430
1456
|
data = fragments;
|
|
1431
1457
|
}
|
|
1432
1458
|
|
|
1433
|
-
|
|
1434
|
-
// If the state is `INFLATING`, it means that the frame data was
|
|
1435
|
-
// decompressed asynchronously, so there is no need to defer the event
|
|
1436
|
-
// as it will be emitted asynchronously anyway.
|
|
1437
|
-
//
|
|
1438
|
-
if (this._state === INFLATING || this._allowSynchronousEvents) {
|
|
1459
|
+
if (this._allowSynchronousEvents) {
|
|
1439
1460
|
this.emit('message', data, true);
|
|
1440
1461
|
this._state = GET_INFO;
|
|
1441
1462
|
} else {
|
|
1442
1463
|
this._state = DEFER_EVENT;
|
|
1443
|
-
|
|
1464
|
+
setImmediate(() => {
|
|
1444
1465
|
this.emit('message', data, true);
|
|
1445
1466
|
this._state = GET_INFO;
|
|
1446
1467
|
this.startLoop(cb);
|
|
@@ -1467,7 +1488,7 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1467
1488
|
this._state = GET_INFO;
|
|
1468
1489
|
} else {
|
|
1469
1490
|
this._state = DEFER_EVENT;
|
|
1470
|
-
|
|
1491
|
+
setImmediate(() => {
|
|
1471
1492
|
this.emit('message', buf, false);
|
|
1472
1493
|
this._state = GET_INFO;
|
|
1473
1494
|
this.startLoop(cb);
|
|
@@ -1538,7 +1559,7 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1538
1559
|
this._state = GET_INFO;
|
|
1539
1560
|
} else {
|
|
1540
1561
|
this._state = DEFER_EVENT;
|
|
1541
|
-
|
|
1562
|
+
setImmediate(() => {
|
|
1542
1563
|
this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);
|
|
1543
1564
|
this._state = GET_INFO;
|
|
1544
1565
|
this.startLoop(cb);
|
|
@@ -1575,45 +1596,23 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
1575
1596
|
|
|
1576
1597
|
var receiver = Receiver$1;
|
|
1577
1598
|
|
|
1578
|
-
/**
|
|
1579
|
-
* A shim for `queueMicrotask()`.
|
|
1580
|
-
*
|
|
1581
|
-
* @param {Function} cb Callback
|
|
1582
|
-
*/
|
|
1583
|
-
function queueMicrotaskShim(cb) {
|
|
1584
|
-
promise.then(cb).catch(throwErrorNextTick);
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
/**
|
|
1588
|
-
* Throws an error.
|
|
1589
|
-
*
|
|
1590
|
-
* @param {Error} err The error to throw
|
|
1591
|
-
* @private
|
|
1592
|
-
*/
|
|
1593
|
-
function throwError(err) {
|
|
1594
|
-
throw err;
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
/**
|
|
1598
|
-
* Throws an error in the next tick.
|
|
1599
|
-
*
|
|
1600
|
-
* @param {Error} err The error to throw
|
|
1601
|
-
* @private
|
|
1602
|
-
*/
|
|
1603
|
-
function throwErrorNextTick(err) {
|
|
1604
|
-
process.nextTick(throwError, err);
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
1599
|
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex" }] */
|
|
1608
1600
|
const { randomFillSync } = require$$1;
|
|
1609
1601
|
|
|
1610
1602
|
const PerMessageDeflate$1 = permessageDeflate;
|
|
1611
|
-
const { EMPTY_BUFFER: EMPTY_BUFFER$1 } = constants;
|
|
1612
|
-
const { isValidStatusCode } = validationExports;
|
|
1603
|
+
const { EMPTY_BUFFER: EMPTY_BUFFER$1, kWebSocket: kWebSocket$1, NOOP: NOOP$1 } = constants;
|
|
1604
|
+
const { isBlob: isBlob$1, isValidStatusCode } = validationExports;
|
|
1613
1605
|
const { mask: applyMask, toBuffer: toBuffer$1 } = bufferUtilExports;
|
|
1614
1606
|
|
|
1615
1607
|
const kByteLength = Symbol('kByteLength');
|
|
1616
1608
|
const maskBuffer = Buffer.alloc(4);
|
|
1609
|
+
const RANDOM_POOL_SIZE = 8 * 1024;
|
|
1610
|
+
let randomPool;
|
|
1611
|
+
let randomPoolPointer = RANDOM_POOL_SIZE;
|
|
1612
|
+
|
|
1613
|
+
const DEFAULT = 0;
|
|
1614
|
+
const DEFLATING = 1;
|
|
1615
|
+
const GET_BLOB_DATA = 2;
|
|
1617
1616
|
|
|
1618
1617
|
/**
|
|
1619
1618
|
* HyBi Sender implementation.
|
|
@@ -1641,8 +1640,10 @@ let Sender$1 = class Sender {
|
|
|
1641
1640
|
this._compress = false;
|
|
1642
1641
|
|
|
1643
1642
|
this._bufferedBytes = 0;
|
|
1644
|
-
this._deflating = false;
|
|
1645
1643
|
this._queue = [];
|
|
1644
|
+
this._state = DEFAULT;
|
|
1645
|
+
this.onerror = NOOP$1;
|
|
1646
|
+
this[kWebSocket$1] = undefined;
|
|
1646
1647
|
}
|
|
1647
1648
|
|
|
1648
1649
|
/**
|
|
@@ -1678,7 +1679,24 @@ let Sender$1 = class Sender {
|
|
|
1678
1679
|
if (options.generateMask) {
|
|
1679
1680
|
options.generateMask(mask);
|
|
1680
1681
|
} else {
|
|
1681
|
-
|
|
1682
|
+
if (randomPoolPointer === RANDOM_POOL_SIZE) {
|
|
1683
|
+
/* istanbul ignore else */
|
|
1684
|
+
if (randomPool === undefined) {
|
|
1685
|
+
//
|
|
1686
|
+
// This is lazily initialized because server-sent frames must not
|
|
1687
|
+
// be masked so it may never be used.
|
|
1688
|
+
//
|
|
1689
|
+
randomPool = Buffer.alloc(RANDOM_POOL_SIZE);
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);
|
|
1693
|
+
randomPoolPointer = 0;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
mask[0] = randomPool[randomPoolPointer++];
|
|
1697
|
+
mask[1] = randomPool[randomPoolPointer++];
|
|
1698
|
+
mask[2] = randomPool[randomPoolPointer++];
|
|
1699
|
+
mask[3] = randomPool[randomPoolPointer++];
|
|
1682
1700
|
}
|
|
1683
1701
|
|
|
1684
1702
|
skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
|
|
@@ -1792,7 +1810,7 @@ let Sender$1 = class Sender {
|
|
|
1792
1810
|
rsv1: false
|
|
1793
1811
|
};
|
|
1794
1812
|
|
|
1795
|
-
if (this.
|
|
1813
|
+
if (this._state !== DEFAULT) {
|
|
1796
1814
|
this.enqueue([this.dispatch, buf, false, options, cb]);
|
|
1797
1815
|
} else {
|
|
1798
1816
|
this.sendFrame(Sender.frame(buf, options), cb);
|
|
@@ -1814,6 +1832,9 @@ let Sender$1 = class Sender {
|
|
|
1814
1832
|
if (typeof data === 'string') {
|
|
1815
1833
|
byteLength = Buffer.byteLength(data);
|
|
1816
1834
|
readOnly = false;
|
|
1835
|
+
} else if (isBlob$1(data)) {
|
|
1836
|
+
byteLength = data.size;
|
|
1837
|
+
readOnly = false;
|
|
1817
1838
|
} else {
|
|
1818
1839
|
data = toBuffer$1(data);
|
|
1819
1840
|
byteLength = data.length;
|
|
@@ -1835,7 +1856,13 @@ let Sender$1 = class Sender {
|
|
|
1835
1856
|
rsv1: false
|
|
1836
1857
|
};
|
|
1837
1858
|
|
|
1838
|
-
if (
|
|
1859
|
+
if (isBlob$1(data)) {
|
|
1860
|
+
if (this._state !== DEFAULT) {
|
|
1861
|
+
this.enqueue([this.getBlobData, data, false, options, cb]);
|
|
1862
|
+
} else {
|
|
1863
|
+
this.getBlobData(data, false, options, cb);
|
|
1864
|
+
}
|
|
1865
|
+
} else if (this._state !== DEFAULT) {
|
|
1839
1866
|
this.enqueue([this.dispatch, data, false, options, cb]);
|
|
1840
1867
|
} else {
|
|
1841
1868
|
this.sendFrame(Sender.frame(data, options), cb);
|
|
@@ -1857,6 +1884,9 @@ let Sender$1 = class Sender {
|
|
|
1857
1884
|
if (typeof data === 'string') {
|
|
1858
1885
|
byteLength = Buffer.byteLength(data);
|
|
1859
1886
|
readOnly = false;
|
|
1887
|
+
} else if (isBlob$1(data)) {
|
|
1888
|
+
byteLength = data.size;
|
|
1889
|
+
readOnly = false;
|
|
1860
1890
|
} else {
|
|
1861
1891
|
data = toBuffer$1(data);
|
|
1862
1892
|
byteLength = data.length;
|
|
@@ -1878,7 +1908,13 @@ let Sender$1 = class Sender {
|
|
|
1878
1908
|
rsv1: false
|
|
1879
1909
|
};
|
|
1880
1910
|
|
|
1881
|
-
if (
|
|
1911
|
+
if (isBlob$1(data)) {
|
|
1912
|
+
if (this._state !== DEFAULT) {
|
|
1913
|
+
this.enqueue([this.getBlobData, data, false, options, cb]);
|
|
1914
|
+
} else {
|
|
1915
|
+
this.getBlobData(data, false, options, cb);
|
|
1916
|
+
}
|
|
1917
|
+
} else if (this._state !== DEFAULT) {
|
|
1882
1918
|
this.enqueue([this.dispatch, data, false, options, cb]);
|
|
1883
1919
|
} else {
|
|
1884
1920
|
this.sendFrame(Sender.frame(data, options), cb);
|
|
@@ -1912,6 +1948,9 @@ let Sender$1 = class Sender {
|
|
|
1912
1948
|
if (typeof data === 'string') {
|
|
1913
1949
|
byteLength = Buffer.byteLength(data);
|
|
1914
1950
|
readOnly = false;
|
|
1951
|
+
} else if (isBlob$1(data)) {
|
|
1952
|
+
byteLength = data.size;
|
|
1953
|
+
readOnly = false;
|
|
1915
1954
|
} else {
|
|
1916
1955
|
data = toBuffer$1(data);
|
|
1917
1956
|
byteLength = data.length;
|
|
@@ -1939,40 +1978,94 @@ let Sender$1 = class Sender {
|
|
|
1939
1978
|
|
|
1940
1979
|
if (options.fin) this._firstFragment = true;
|
|
1941
1980
|
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
};
|
|
1981
|
+
const opts = {
|
|
1982
|
+
[kByteLength]: byteLength,
|
|
1983
|
+
fin: options.fin,
|
|
1984
|
+
generateMask: this._generateMask,
|
|
1985
|
+
mask: options.mask,
|
|
1986
|
+
maskBuffer: this._maskBuffer,
|
|
1987
|
+
opcode,
|
|
1988
|
+
readOnly,
|
|
1989
|
+
rsv1
|
|
1990
|
+
};
|
|
1953
1991
|
|
|
1954
|
-
|
|
1955
|
-
|
|
1992
|
+
if (isBlob$1(data)) {
|
|
1993
|
+
if (this._state !== DEFAULT) {
|
|
1994
|
+
this.enqueue([this.getBlobData, data, this._compress, opts, cb]);
|
|
1956
1995
|
} else {
|
|
1957
|
-
this.
|
|
1996
|
+
this.getBlobData(data, this._compress, opts, cb);
|
|
1958
1997
|
}
|
|
1998
|
+
} else if (this._state !== DEFAULT) {
|
|
1999
|
+
this.enqueue([this.dispatch, data, this._compress, opts, cb]);
|
|
1959
2000
|
} else {
|
|
1960
|
-
this.
|
|
1961
|
-
Sender.frame(data, {
|
|
1962
|
-
[kByteLength]: byteLength,
|
|
1963
|
-
fin: options.fin,
|
|
1964
|
-
generateMask: this._generateMask,
|
|
1965
|
-
mask: options.mask,
|
|
1966
|
-
maskBuffer: this._maskBuffer,
|
|
1967
|
-
opcode,
|
|
1968
|
-
readOnly,
|
|
1969
|
-
rsv1: false
|
|
1970
|
-
}),
|
|
1971
|
-
cb
|
|
1972
|
-
);
|
|
2001
|
+
this.dispatch(data, this._compress, opts, cb);
|
|
1973
2002
|
}
|
|
1974
2003
|
}
|
|
1975
2004
|
|
|
2005
|
+
/**
|
|
2006
|
+
* Gets the contents of a blob as binary data.
|
|
2007
|
+
*
|
|
2008
|
+
* @param {Blob} blob The blob
|
|
2009
|
+
* @param {Boolean} [compress=false] Specifies whether or not to compress
|
|
2010
|
+
* the data
|
|
2011
|
+
* @param {Object} options Options object
|
|
2012
|
+
* @param {Boolean} [options.fin=false] Specifies whether or not to set the
|
|
2013
|
+
* FIN bit
|
|
2014
|
+
* @param {Function} [options.generateMask] The function used to generate the
|
|
2015
|
+
* masking key
|
|
2016
|
+
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
|
|
2017
|
+
* `data`
|
|
2018
|
+
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking
|
|
2019
|
+
* key
|
|
2020
|
+
* @param {Number} options.opcode The opcode
|
|
2021
|
+
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
|
|
2022
|
+
* modified
|
|
2023
|
+
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
|
|
2024
|
+
* RSV1 bit
|
|
2025
|
+
* @param {Function} [cb] Callback
|
|
2026
|
+
* @private
|
|
2027
|
+
*/
|
|
2028
|
+
getBlobData(blob, compress, options, cb) {
|
|
2029
|
+
this._bufferedBytes += options[kByteLength];
|
|
2030
|
+
this._state = GET_BLOB_DATA;
|
|
2031
|
+
|
|
2032
|
+
blob
|
|
2033
|
+
.arrayBuffer()
|
|
2034
|
+
.then((arrayBuffer) => {
|
|
2035
|
+
if (this._socket.destroyed) {
|
|
2036
|
+
const err = new Error(
|
|
2037
|
+
'The socket was closed while the blob was being read'
|
|
2038
|
+
);
|
|
2039
|
+
|
|
2040
|
+
//
|
|
2041
|
+
// `callCallbacks` is called in the next tick to ensure that errors
|
|
2042
|
+
// that might be thrown in the callbacks behave like errors thrown
|
|
2043
|
+
// outside the promise chain.
|
|
2044
|
+
//
|
|
2045
|
+
process.nextTick(callCallbacks, this, err, cb);
|
|
2046
|
+
return;
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
this._bufferedBytes -= options[kByteLength];
|
|
2050
|
+
const data = toBuffer$1(arrayBuffer);
|
|
2051
|
+
|
|
2052
|
+
if (!compress) {
|
|
2053
|
+
this._state = DEFAULT;
|
|
2054
|
+
this.sendFrame(Sender.frame(data, options), cb);
|
|
2055
|
+
this.dequeue();
|
|
2056
|
+
} else {
|
|
2057
|
+
this.dispatch(data, compress, options, cb);
|
|
2058
|
+
}
|
|
2059
|
+
})
|
|
2060
|
+
.catch((err) => {
|
|
2061
|
+
//
|
|
2062
|
+
// `onError` is called in the next tick for the same reason that
|
|
2063
|
+
// `callCallbacks` above is.
|
|
2064
|
+
//
|
|
2065
|
+
process.nextTick(onError, this, err, cb);
|
|
2066
|
+
});
|
|
2067
|
+
}
|
|
2068
|
+
|
|
1976
2069
|
/**
|
|
1977
2070
|
* Dispatches a message.
|
|
1978
2071
|
*
|
|
@@ -2005,27 +2098,19 @@ let Sender$1 = class Sender {
|
|
|
2005
2098
|
const perMessageDeflate = this._extensions[PerMessageDeflate$1.extensionName];
|
|
2006
2099
|
|
|
2007
2100
|
this._bufferedBytes += options[kByteLength];
|
|
2008
|
-
this.
|
|
2101
|
+
this._state = DEFLATING;
|
|
2009
2102
|
perMessageDeflate.compress(data, options.fin, (_, buf) => {
|
|
2010
2103
|
if (this._socket.destroyed) {
|
|
2011
2104
|
const err = new Error(
|
|
2012
2105
|
'The socket was closed while data was being compressed'
|
|
2013
2106
|
);
|
|
2014
2107
|
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
for (let i = 0; i < this._queue.length; i++) {
|
|
2018
|
-
const params = this._queue[i];
|
|
2019
|
-
const callback = params[params.length - 1];
|
|
2020
|
-
|
|
2021
|
-
if (typeof callback === 'function') callback(err);
|
|
2022
|
-
}
|
|
2023
|
-
|
|
2108
|
+
callCallbacks(this, err, cb);
|
|
2024
2109
|
return;
|
|
2025
2110
|
}
|
|
2026
2111
|
|
|
2027
2112
|
this._bufferedBytes -= options[kByteLength];
|
|
2028
|
-
this.
|
|
2113
|
+
this._state = DEFAULT;
|
|
2029
2114
|
options.readOnly = false;
|
|
2030
2115
|
this.sendFrame(Sender.frame(buf, options), cb);
|
|
2031
2116
|
this.dequeue();
|
|
@@ -2038,7 +2123,7 @@ let Sender$1 = class Sender {
|
|
|
2038
2123
|
* @private
|
|
2039
2124
|
*/
|
|
2040
2125
|
dequeue() {
|
|
2041
|
-
while (
|
|
2126
|
+
while (this._state === DEFAULT && this._queue.length) {
|
|
2042
2127
|
const params = this._queue.shift();
|
|
2043
2128
|
|
|
2044
2129
|
this._bufferedBytes -= params[3][kByteLength];
|
|
@@ -2078,6 +2163,38 @@ let Sender$1 = class Sender {
|
|
|
2078
2163
|
|
|
2079
2164
|
var sender = Sender$1;
|
|
2080
2165
|
|
|
2166
|
+
/**
|
|
2167
|
+
* Calls queued callbacks with an error.
|
|
2168
|
+
*
|
|
2169
|
+
* @param {Sender} sender The `Sender` instance
|
|
2170
|
+
* @param {Error} err The error to call the callbacks with
|
|
2171
|
+
* @param {Function} [cb] The first callback
|
|
2172
|
+
* @private
|
|
2173
|
+
*/
|
|
2174
|
+
function callCallbacks(sender, err, cb) {
|
|
2175
|
+
if (typeof cb === 'function') cb(err);
|
|
2176
|
+
|
|
2177
|
+
for (let i = 0; i < sender._queue.length; i++) {
|
|
2178
|
+
const params = sender._queue[i];
|
|
2179
|
+
const callback = params[params.length - 1];
|
|
2180
|
+
|
|
2181
|
+
if (typeof callback === 'function') callback(err);
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
/**
|
|
2186
|
+
* Handles a `Sender` error.
|
|
2187
|
+
*
|
|
2188
|
+
* @param {Sender} sender The `Sender` instance
|
|
2189
|
+
* @param {Error} err The error
|
|
2190
|
+
* @param {Function} [cb] The first pending callback
|
|
2191
|
+
* @private
|
|
2192
|
+
*/
|
|
2193
|
+
function onError(sender, err, cb) {
|
|
2194
|
+
callCallbacks(sender, err, cb);
|
|
2195
|
+
sender.onerror(err);
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2081
2198
|
const { kForOnEventAttribute: kForOnEventAttribute$1, kListener: kListener$1 } = constants;
|
|
2082
2199
|
|
|
2083
2200
|
const kCode = Symbol('kCode');
|
|
@@ -2571,7 +2688,7 @@ function format$1(extensions) {
|
|
|
2571
2688
|
|
|
2572
2689
|
var extension = { format: format$1, parse: parse$1 };
|
|
2573
2690
|
|
|
2574
|
-
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$" }] */
|
|
2691
|
+
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$", "caughtErrors": "none" }] */
|
|
2575
2692
|
|
|
2576
2693
|
const EventEmitter = require$$0$3;
|
|
2577
2694
|
const https = require$$1$1;
|
|
@@ -2584,6 +2701,8 @@ const { URL } = require$$7;
|
|
|
2584
2701
|
const PerMessageDeflate = permessageDeflate;
|
|
2585
2702
|
const Receiver = receiver;
|
|
2586
2703
|
const Sender = sender;
|
|
2704
|
+
const { isBlob } = validationExports;
|
|
2705
|
+
|
|
2587
2706
|
const {
|
|
2588
2707
|
BINARY_TYPES,
|
|
2589
2708
|
EMPTY_BUFFER,
|
|
@@ -2628,6 +2747,7 @@ class WebSocket extends EventEmitter {
|
|
|
2628
2747
|
this._closeFrameSent = false;
|
|
2629
2748
|
this._closeMessage = EMPTY_BUFFER;
|
|
2630
2749
|
this._closeTimer = null;
|
|
2750
|
+
this._errorEmitted = false;
|
|
2631
2751
|
this._extensions = {};
|
|
2632
2752
|
this._paused = false;
|
|
2633
2753
|
this._protocol = '';
|
|
@@ -2660,9 +2780,8 @@ class WebSocket extends EventEmitter {
|
|
|
2660
2780
|
}
|
|
2661
2781
|
|
|
2662
2782
|
/**
|
|
2663
|
-
*
|
|
2664
|
-
*
|
|
2665
|
-
* type).
|
|
2783
|
+
* For historical reasons, the custom "nodebuffer" type is used by the default
|
|
2784
|
+
* instead of "blob".
|
|
2666
2785
|
*
|
|
2667
2786
|
* @type {String}
|
|
2668
2787
|
*/
|
|
@@ -2783,11 +2902,14 @@ class WebSocket extends EventEmitter {
|
|
|
2783
2902
|
skipUTF8Validation: options.skipUTF8Validation
|
|
2784
2903
|
});
|
|
2785
2904
|
|
|
2786
|
-
|
|
2905
|
+
const sender = new Sender(socket, this._extensions, options.generateMask);
|
|
2906
|
+
|
|
2787
2907
|
this._receiver = receiver;
|
|
2908
|
+
this._sender = sender;
|
|
2788
2909
|
this._socket = socket;
|
|
2789
2910
|
|
|
2790
2911
|
receiver[kWebSocket] = this;
|
|
2912
|
+
sender[kWebSocket] = this;
|
|
2791
2913
|
socket[kWebSocket] = this;
|
|
2792
2914
|
|
|
2793
2915
|
receiver.on('conclude', receiverOnConclude);
|
|
@@ -2797,6 +2919,8 @@ class WebSocket extends EventEmitter {
|
|
|
2797
2919
|
receiver.on('ping', receiverOnPing);
|
|
2798
2920
|
receiver.on('pong', receiverOnPong);
|
|
2799
2921
|
|
|
2922
|
+
sender.onerror = senderOnError;
|
|
2923
|
+
|
|
2800
2924
|
//
|
|
2801
2925
|
// These methods may not be available if `socket` is just a `Duplex`.
|
|
2802
2926
|
//
|
|
@@ -2892,13 +3016,7 @@ class WebSocket extends EventEmitter {
|
|
|
2892
3016
|
}
|
|
2893
3017
|
});
|
|
2894
3018
|
|
|
2895
|
-
|
|
2896
|
-
// Specify a timeout for the closing handshake to complete.
|
|
2897
|
-
//
|
|
2898
|
-
this._closeTimer = setTimeout(
|
|
2899
|
-
this._socket.destroy.bind(this._socket),
|
|
2900
|
-
closeTimeout
|
|
2901
|
-
);
|
|
3019
|
+
setCloseTimer(this);
|
|
2902
3020
|
}
|
|
2903
3021
|
|
|
2904
3022
|
/**
|
|
@@ -3193,7 +3311,7 @@ var websocket = WebSocket;
|
|
|
3193
3311
|
* @param {(String|URL)} address The URL to which to connect
|
|
3194
3312
|
* @param {Array} protocols The subprotocols
|
|
3195
3313
|
* @param {Object} [options] Connection options
|
|
3196
|
-
* @param {Boolean} [options.allowSynchronousEvents=
|
|
3314
|
+
* @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any
|
|
3197
3315
|
* of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple
|
|
3198
3316
|
* times in the same tick
|
|
3199
3317
|
* @param {Boolean} [options.autoPong=true] Specifies whether or not to
|
|
@@ -3222,7 +3340,7 @@ var websocket = WebSocket;
|
|
|
3222
3340
|
*/
|
|
3223
3341
|
function initAsClient(websocket, address, protocols, options) {
|
|
3224
3342
|
const opts = {
|
|
3225
|
-
allowSynchronousEvents:
|
|
3343
|
+
allowSynchronousEvents: true,
|
|
3226
3344
|
autoPong: true,
|
|
3227
3345
|
protocolVersion: protocolVersions[1],
|
|
3228
3346
|
maxPayload: 100 * 1024 * 1024,
|
|
@@ -3231,7 +3349,6 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3231
3349
|
followRedirects: false,
|
|
3232
3350
|
maxRedirects: 10,
|
|
3233
3351
|
...options,
|
|
3234
|
-
createConnection: undefined,
|
|
3235
3352
|
socketPath: undefined,
|
|
3236
3353
|
hostname: undefined,
|
|
3237
3354
|
protocol: undefined,
|
|
@@ -3302,7 +3419,8 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3302
3419
|
const protocolSet = new Set();
|
|
3303
3420
|
let perMessageDeflate;
|
|
3304
3421
|
|
|
3305
|
-
opts.createConnection =
|
|
3422
|
+
opts.createConnection =
|
|
3423
|
+
opts.createConnection || (isSecure ? tlsConnect : netConnect);
|
|
3306
3424
|
opts.defaultPort = opts.defaultPort || defaultPort;
|
|
3307
3425
|
opts.port = parsedUrl.port || defaultPort;
|
|
3308
3426
|
opts.host = parsedUrl.hostname.startsWith('[')
|
|
@@ -3498,7 +3616,9 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3498
3616
|
|
|
3499
3617
|
req = websocket._req = null;
|
|
3500
3618
|
|
|
3501
|
-
|
|
3619
|
+
const upgrade = res.headers.upgrade;
|
|
3620
|
+
|
|
3621
|
+
if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {
|
|
3502
3622
|
abortHandshake(websocket, socket, 'Invalid Upgrade header');
|
|
3503
3623
|
return;
|
|
3504
3624
|
}
|
|
@@ -3600,6 +3720,11 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3600
3720
|
*/
|
|
3601
3721
|
function emitErrorAndClose(websocket, err) {
|
|
3602
3722
|
websocket._readyState = WebSocket.CLOSING;
|
|
3723
|
+
//
|
|
3724
|
+
// The following assignment is practically useless and is done only for
|
|
3725
|
+
// consistency.
|
|
3726
|
+
//
|
|
3727
|
+
websocket._errorEmitted = true;
|
|
3603
3728
|
websocket.emit('error', err);
|
|
3604
3729
|
websocket.emitClose();
|
|
3605
3730
|
}
|
|
@@ -3680,7 +3805,7 @@ function abortHandshake(websocket, stream, message) {
|
|
|
3680
3805
|
*/
|
|
3681
3806
|
function sendAfterClose(websocket, data, cb) {
|
|
3682
3807
|
if (data) {
|
|
3683
|
-
const length = toBuffer(data).length;
|
|
3808
|
+
const length = isBlob(data) ? data.size : toBuffer(data).length;
|
|
3684
3809
|
|
|
3685
3810
|
//
|
|
3686
3811
|
// The `_bufferedAmount` property is used only when the peer is a client and
|
|
@@ -3756,7 +3881,10 @@ function receiverOnError(err) {
|
|
|
3756
3881
|
websocket.close(err[kStatusCode]);
|
|
3757
3882
|
}
|
|
3758
3883
|
|
|
3759
|
-
websocket.
|
|
3884
|
+
if (!websocket._errorEmitted) {
|
|
3885
|
+
websocket._errorEmitted = true;
|
|
3886
|
+
websocket.emit('error', err);
|
|
3887
|
+
}
|
|
3760
3888
|
}
|
|
3761
3889
|
|
|
3762
3890
|
/**
|
|
@@ -3812,6 +3940,47 @@ function resume(stream) {
|
|
|
3812
3940
|
stream.resume();
|
|
3813
3941
|
}
|
|
3814
3942
|
|
|
3943
|
+
/**
|
|
3944
|
+
* The `Sender` error event handler.
|
|
3945
|
+
*
|
|
3946
|
+
* @param {Error} The error
|
|
3947
|
+
* @private
|
|
3948
|
+
*/
|
|
3949
|
+
function senderOnError(err) {
|
|
3950
|
+
const websocket = this[kWebSocket];
|
|
3951
|
+
|
|
3952
|
+
if (websocket.readyState === WebSocket.CLOSED) return;
|
|
3953
|
+
if (websocket.readyState === WebSocket.OPEN) {
|
|
3954
|
+
websocket._readyState = WebSocket.CLOSING;
|
|
3955
|
+
setCloseTimer(websocket);
|
|
3956
|
+
}
|
|
3957
|
+
|
|
3958
|
+
//
|
|
3959
|
+
// `socket.end()` is used instead of `socket.destroy()` to allow the other
|
|
3960
|
+
// peer to finish sending queued data. There is no need to set a timer here
|
|
3961
|
+
// because `CLOSING` means that it is already set or not needed.
|
|
3962
|
+
//
|
|
3963
|
+
this._socket.end();
|
|
3964
|
+
|
|
3965
|
+
if (!websocket._errorEmitted) {
|
|
3966
|
+
websocket._errorEmitted = true;
|
|
3967
|
+
websocket.emit('error', err);
|
|
3968
|
+
}
|
|
3969
|
+
}
|
|
3970
|
+
|
|
3971
|
+
/**
|
|
3972
|
+
* Set a timer to destroy the underlying raw socket of a WebSocket.
|
|
3973
|
+
*
|
|
3974
|
+
* @param {WebSocket} websocket The WebSocket instance
|
|
3975
|
+
* @private
|
|
3976
|
+
*/
|
|
3977
|
+
function setCloseTimer(websocket) {
|
|
3978
|
+
websocket._closeTimer = setTimeout(
|
|
3979
|
+
websocket._socket.destroy.bind(websocket._socket),
|
|
3980
|
+
closeTimeout
|
|
3981
|
+
);
|
|
3982
|
+
}
|
|
3983
|
+
|
|
3815
3984
|
/**
|
|
3816
3985
|
* The listener of the socket `'close'` event.
|
|
3817
3986
|
*
|