@jsenv/core 29.1.18 → 29.2.0
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/dist/babel_helpers/AsyncGenerator/AsyncGenerator.js +3 -16
- package/dist/babel_helpers/applyDecoratorDescriptor/applyDecoratorDescriptor.js +0 -5
- package/dist/babel_helpers/applyDecs/applyDecs.js +54 -241
- package/dist/babel_helpers/applyDecs2023/applyDecs2023.js +47 -195
- package/dist/babel_helpers/arrayLikeToArray/arrayLikeToArray.js +0 -2
- package/dist/babel_helpers/arrayWithoutHoles/arrayWithoutHoles.js +2 -1
- package/dist/babel_helpers/assertThisInitialized/assertThisInitialized.js +0 -1
- package/dist/babel_helpers/asyncGeneratorDelegate/asyncGeneratorDelegate.js +4 -14
- package/dist/babel_helpers/asyncIterator/asyncIterator.js +5 -20
- package/dist/babel_helpers/asyncToGenerator/asyncToGenerator.js +2 -8
- package/dist/babel_helpers/awaitAsyncGenerator/awaitAsyncGenerator.js +1 -3
- package/dist/babel_helpers/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +0 -4
- package/dist/babel_helpers/classApplyDescriptorGet/classApplyDescriptorGet.js +0 -1
- package/dist/babel_helpers/classApplyDescriptorSet/classApplyDescriptorSet.js +0 -1
- package/dist/babel_helpers/classExtractFieldDescriptor/classExtractFieldDescriptor.js +0 -1
- package/dist/babel_helpers/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +0 -1
- package/dist/babel_helpers/classPrivateMethodGet/classPrivateMethodGet.js +0 -1
- package/dist/babel_helpers/construct/construct.js +5 -5
- package/dist/babel_helpers/createClass/createClass.js +0 -1
- package/dist/babel_helpers/createForOfIteratorHelper/createForOfIteratorHelper.js +5 -9
- package/dist/babel_helpers/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +2 -3
- package/dist/babel_helpers/createRawReactElement/createRawReactElement.js +2 -8
- package/dist/babel_helpers/createSuper/createSuper.js +2 -4
- package/dist/babel_helpers/decorate/decorate.js +60 -311
- package/dist/babel_helpers/defaults/defaults.js +0 -3
- package/dist/babel_helpers/defineEnumerableProperties/defineEnumerableProperties.js +2 -5
- package/dist/babel_helpers/defineProperty/defineProperty.js +0 -1
- package/dist/babel_helpers/extends/extends.js +0 -3
- package/dist/babel_helpers/get/get.js +0 -3
- package/dist/babel_helpers/getPrototypeOf/getPrototypeOf.js +2 -1
- package/dist/babel_helpers/inherits/inherits.js +2 -3
- package/dist/babel_helpers/instanceof/instanceof.js +0 -1
- package/dist/babel_helpers/interopRequireWildcard/interopRequireWildcard.js +0 -10
- package/dist/babel_helpers/isNativeReflectConstruct/isNativeReflectConstruct.js +6 -6
- package/dist/babel_helpers/iterableToArrayLimit/iterableToArrayLimit.js +0 -5
- package/dist/babel_helpers/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +2 -5
- package/dist/babel_helpers/jsx/jsx.js +2 -8
- package/dist/babel_helpers/maybeArrayLike/maybeArrayLike.js +2 -3
- package/dist/babel_helpers/objectSpread/objectSpread.js +4 -6
- package/dist/babel_helpers/objectSpread2/objectSpread2.js +3 -8
- package/dist/babel_helpers/objectWithoutProperties/objectWithoutProperties.js +0 -3
- package/dist/babel_helpers/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +0 -2
- package/dist/babel_helpers/possibleConstructorReturn/possibleConstructorReturn.js +0 -1
- package/dist/babel_helpers/set/set.js +2 -12
- package/dist/babel_helpers/superPropBase/superPropBase.js +0 -1
- package/dist/babel_helpers/taggedTemplateLiteral/taggedTemplateLiteral.js +0 -1
- package/dist/babel_helpers/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +0 -1
- package/dist/babel_helpers/toPrimitive/toPrimitive.js +1 -5
- package/dist/babel_helpers/typeof/typeof.js +0 -2
- package/dist/babel_helpers/wrapNativeSuper/wrapNativeSuper.js +0 -7
- package/dist/babel_helpers/wrapRegExp/wrapRegExp.js +5 -19
- package/dist/controllable_child_process.mjs +17 -27
- package/dist/controllable_worker_thread.mjs +4 -16
- package/dist/js/autoreload.js +13 -56
- package/dist/js/execute_using_dynamic_import.js +40 -164
- package/dist/js/global_this.js +2 -10
- package/dist/js/import_meta_hot.js +3 -9
- package/dist/js/new_stylesheet.js +0 -59
- package/dist/js/regenerator_runtime.js +80 -156
- package/dist/js/s.js +25 -113
- package/dist/js/s.js.map +10 -10
- package/dist/js/script_type_module_supervisor.js +4 -13
- package/dist/js/server_events_client.js +10 -38
- package/dist/js/supervisor.js +25 -167
- package/dist/js/v8_coverage.js +29 -92
- package/dist/js/ws.js +226 -704
- package/dist/main.js +761 -4155
- package/package.json +8 -8
- package/src/plugins/import_meta_url/client/import_meta_url_browser.js +1 -2
- package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +1 -1
- package/src/plugins/plugins.js +1 -1
- package/src/plugins/transpilation/as_js_classic/helpers-string.js +1 -0
- package/src/plugins/transpilation/babel/global_this/client/global_this.js +0 -2
package/dist/js/ws.js
CHANGED
|
@@ -11,45 +11,43 @@ import require$$7 from "url";
|
|
|
11
11
|
const {
|
|
12
12
|
Duplex
|
|
13
13
|
} = require$$0;
|
|
14
|
+
|
|
14
15
|
/**
|
|
15
16
|
* Emits the `'close'` event on a stream.
|
|
16
17
|
*
|
|
17
18
|
* @param {Duplex} stream The stream.
|
|
18
19
|
* @private
|
|
19
20
|
*/
|
|
20
|
-
|
|
21
21
|
function emitClose$1(stream) {
|
|
22
22
|
stream.emit('close');
|
|
23
23
|
}
|
|
24
|
+
|
|
24
25
|
/**
|
|
25
26
|
* The listener of the `'end'` event.
|
|
26
27
|
*
|
|
27
28
|
* @private
|
|
28
29
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
30
|
function duplexOnEnd() {
|
|
32
31
|
if (!this.destroyed && this._writableState.finished) {
|
|
33
32
|
this.destroy();
|
|
34
33
|
}
|
|
35
34
|
}
|
|
35
|
+
|
|
36
36
|
/**
|
|
37
37
|
* The listener of the `'error'` event.
|
|
38
38
|
*
|
|
39
39
|
* @param {Error} err The error
|
|
40
40
|
* @private
|
|
41
41
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
42
|
function duplexOnError(err) {
|
|
45
43
|
this.removeListener('error', duplexOnError);
|
|
46
44
|
this.destroy();
|
|
47
|
-
|
|
48
45
|
if (this.listenerCount('error') === 0) {
|
|
49
46
|
// Do not suppress the throwing behavior.
|
|
50
47
|
this.emit('error', err);
|
|
51
48
|
}
|
|
52
49
|
}
|
|
50
|
+
|
|
53
51
|
/**
|
|
54
52
|
* Wraps a `WebSocket` in a duplex stream.
|
|
55
53
|
*
|
|
@@ -58,11 +56,10 @@ function duplexOnError(err) {
|
|
|
58
56
|
* @return {Duplex} The duplex stream
|
|
59
57
|
* @public
|
|
60
58
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
59
|
function createWebSocketStream(ws, options) {
|
|
64
60
|
let terminateOnDestroy = true;
|
|
65
|
-
const duplex = new Duplex({
|
|
61
|
+
const duplex = new Duplex({
|
|
62
|
+
...options,
|
|
66
63
|
autoDestroy: false,
|
|
67
64
|
emitClose: false,
|
|
68
65
|
objectMode: false,
|
|
@@ -73,7 +70,9 @@ function createWebSocketStream(ws, options) {
|
|
|
73
70
|
if (!duplex.push(data)) ws.pause();
|
|
74
71
|
});
|
|
75
72
|
ws.once('error', function error(err) {
|
|
76
|
-
if (duplex.destroyed) return;
|
|
73
|
+
if (duplex.destroyed) return;
|
|
74
|
+
|
|
75
|
+
// Prevent `ws.terminate()` from being called by `duplex._destroy()`.
|
|
77
76
|
//
|
|
78
77
|
// - If the `'error'` event is emitted before the `'open'` event, then
|
|
79
78
|
// `ws.terminate()` is a noop as no socket is assigned.
|
|
@@ -82,7 +81,6 @@ function createWebSocketStream(ws, options) {
|
|
|
82
81
|
// connection by calling `ws.close()`. This allows a close frame to be
|
|
83
82
|
// sent to the other peer. If `ws.terminate()` is called right after this,
|
|
84
83
|
// then the close frame might not be sent.
|
|
85
|
-
|
|
86
84
|
terminateOnDestroy = false;
|
|
87
85
|
duplex.destroy(err);
|
|
88
86
|
});
|
|
@@ -90,14 +88,12 @@ function createWebSocketStream(ws, options) {
|
|
|
90
88
|
if (duplex.destroyed) return;
|
|
91
89
|
duplex.push(null);
|
|
92
90
|
});
|
|
93
|
-
|
|
94
91
|
duplex._destroy = function (err, callback) {
|
|
95
92
|
if (ws.readyState === ws.CLOSED) {
|
|
96
93
|
callback(err);
|
|
97
94
|
process.nextTick(emitClose$1, duplex);
|
|
98
95
|
return;
|
|
99
96
|
}
|
|
100
|
-
|
|
101
97
|
let called = false;
|
|
102
98
|
ws.once('error', function error(err) {
|
|
103
99
|
called = true;
|
|
@@ -109,21 +105,19 @@ function createWebSocketStream(ws, options) {
|
|
|
109
105
|
});
|
|
110
106
|
if (terminateOnDestroy) ws.terminate();
|
|
111
107
|
};
|
|
112
|
-
|
|
113
108
|
duplex._final = function (callback) {
|
|
114
109
|
if (ws.readyState === ws.CONNECTING) {
|
|
115
110
|
ws.once('open', function open() {
|
|
116
111
|
duplex._final(callback);
|
|
117
112
|
});
|
|
118
113
|
return;
|
|
119
|
-
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// If the value of the `_socket` property is `null` it means that `ws` is a
|
|
120
117
|
// client websocket and the handshake failed. In fact, when this happens, a
|
|
121
118
|
// socket is never assigned to the websocket. Wait for the `'error'` event
|
|
122
119
|
// that will be emitted by the websocket.
|
|
123
|
-
|
|
124
|
-
|
|
125
120
|
if (ws._socket === null) return;
|
|
126
|
-
|
|
127
121
|
if (ws._socket._writableState.finished) {
|
|
128
122
|
callback();
|
|
129
123
|
if (duplex._readableState.endEmitted) duplex.destroy();
|
|
@@ -134,15 +128,12 @@ function createWebSocketStream(ws, options) {
|
|
|
134
128
|
// `null` chunk is, in fact, pushed when the websocket emits `'close'`.
|
|
135
129
|
callback();
|
|
136
130
|
});
|
|
137
|
-
|
|
138
131
|
ws.close();
|
|
139
132
|
}
|
|
140
133
|
};
|
|
141
|
-
|
|
142
134
|
duplex._read = function () {
|
|
143
135
|
if (ws.isPaused) ws.resume();
|
|
144
136
|
};
|
|
145
|
-
|
|
146
137
|
duplex._write = function (chunk, encoding, callback) {
|
|
147
138
|
if (ws.readyState === ws.CONNECTING) {
|
|
148
139
|
ws.once('open', function open() {
|
|
@@ -150,15 +141,12 @@ function createWebSocketStream(ws, options) {
|
|
|
150
141
|
});
|
|
151
142
|
return;
|
|
152
143
|
}
|
|
153
|
-
|
|
154
144
|
ws.send(chunk, callback);
|
|
155
145
|
};
|
|
156
|
-
|
|
157
146
|
duplex.on('end', duplexOnEnd);
|
|
158
147
|
duplex.on('error', duplexOnError);
|
|
159
148
|
return duplex;
|
|
160
149
|
}
|
|
161
|
-
|
|
162
150
|
var stream = createWebSocketStream;
|
|
163
151
|
var bufferUtil$1 = {
|
|
164
152
|
exports: {}
|
|
@@ -178,6 +166,7 @@ var mask;
|
|
|
178
166
|
const {
|
|
179
167
|
EMPTY_BUFFER: EMPTY_BUFFER$3
|
|
180
168
|
} = constants;
|
|
169
|
+
|
|
181
170
|
/**
|
|
182
171
|
* Merges an array of buffers into a new buffer.
|
|
183
172
|
*
|
|
@@ -186,22 +175,20 @@ const {
|
|
|
186
175
|
* @return {Buffer} The resulting buffer
|
|
187
176
|
* @public
|
|
188
177
|
*/
|
|
189
|
-
|
|
190
178
|
function concat$1(list, totalLength) {
|
|
191
179
|
if (list.length === 0) return EMPTY_BUFFER$3;
|
|
192
180
|
if (list.length === 1) return list[0];
|
|
193
181
|
const target = Buffer.allocUnsafe(totalLength);
|
|
194
182
|
let offset = 0;
|
|
195
|
-
|
|
196
183
|
for (let i = 0; i < list.length; i++) {
|
|
197
184
|
const buf = list[i];
|
|
198
185
|
target.set(buf, offset);
|
|
199
186
|
offset += buf.length;
|
|
200
187
|
}
|
|
201
|
-
|
|
202
188
|
if (offset < totalLength) return target.slice(0, offset);
|
|
203
189
|
return target;
|
|
204
190
|
}
|
|
191
|
+
|
|
205
192
|
/**
|
|
206
193
|
* Masks a buffer using the given mask.
|
|
207
194
|
*
|
|
@@ -212,13 +199,12 @@ function concat$1(list, totalLength) {
|
|
|
212
199
|
* @param {Number} length The number of bytes to mask.
|
|
213
200
|
* @public
|
|
214
201
|
*/
|
|
215
|
-
|
|
216
|
-
|
|
217
202
|
function _mask(source, mask, output, offset, length) {
|
|
218
203
|
for (let i = 0; i < length; i++) {
|
|
219
204
|
output[offset + i] = source[i] ^ mask[i & 3];
|
|
220
205
|
}
|
|
221
206
|
}
|
|
207
|
+
|
|
222
208
|
/**
|
|
223
209
|
* Unmasks a buffer using the given mask.
|
|
224
210
|
*
|
|
@@ -226,13 +212,12 @@ function _mask(source, mask, output, offset, length) {
|
|
|
226
212
|
* @param {Buffer} mask The mask to use
|
|
227
213
|
* @public
|
|
228
214
|
*/
|
|
229
|
-
|
|
230
|
-
|
|
231
215
|
function _unmask(buffer, mask) {
|
|
232
216
|
for (let i = 0; i < buffer.length; i++) {
|
|
233
217
|
buffer[i] ^= mask[i & 3];
|
|
234
218
|
}
|
|
235
219
|
}
|
|
220
|
+
|
|
236
221
|
/**
|
|
237
222
|
* Converts a buffer to an `ArrayBuffer`.
|
|
238
223
|
*
|
|
@@ -240,15 +225,13 @@ function _unmask(buffer, mask) {
|
|
|
240
225
|
* @return {ArrayBuffer} Converted buffer
|
|
241
226
|
* @public
|
|
242
227
|
*/
|
|
243
|
-
|
|
244
|
-
|
|
245
228
|
function toArrayBuffer$1(buf) {
|
|
246
229
|
if (buf.byteLength === buf.buffer.byteLength) {
|
|
247
230
|
return buf.buffer;
|
|
248
231
|
}
|
|
249
|
-
|
|
250
232
|
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
251
233
|
}
|
|
234
|
+
|
|
252
235
|
/**
|
|
253
236
|
* Converts `data` to a `Buffer`.
|
|
254
237
|
*
|
|
@@ -257,13 +240,10 @@ function toArrayBuffer$1(buf) {
|
|
|
257
240
|
* @throws {TypeError}
|
|
258
241
|
* @public
|
|
259
242
|
*/
|
|
260
|
-
|
|
261
|
-
|
|
262
243
|
function toBuffer$2(data) {
|
|
263
244
|
toBuffer$2.readOnly = true;
|
|
264
245
|
if (Buffer.isBuffer(data)) return data;
|
|
265
246
|
let buf;
|
|
266
|
-
|
|
267
247
|
if (data instanceof ArrayBuffer) {
|
|
268
248
|
buf = Buffer.from(data);
|
|
269
249
|
} else if (ArrayBuffer.isView(data)) {
|
|
@@ -272,10 +252,8 @@ function toBuffer$2(data) {
|
|
|
272
252
|
buf = Buffer.from(data);
|
|
273
253
|
toBuffer$2.readOnly = false;
|
|
274
254
|
}
|
|
275
|
-
|
|
276
255
|
return buf;
|
|
277
256
|
}
|
|
278
|
-
|
|
279
257
|
bufferUtil$1.exports = {
|
|
280
258
|
concat: concat$1,
|
|
281
259
|
mask: _mask,
|
|
@@ -283,30 +261,28 @@ bufferUtil$1.exports = {
|
|
|
283
261
|
toBuffer: toBuffer$2,
|
|
284
262
|
unmask: _unmask
|
|
285
263
|
};
|
|
286
|
-
/* istanbul ignore else */
|
|
287
264
|
|
|
265
|
+
/* istanbul ignore else */
|
|
288
266
|
if (!process.env.WS_NO_BUFFER_UTIL) {
|
|
289
267
|
try {
|
|
290
268
|
const bufferUtil = require('bufferutil');
|
|
291
|
-
|
|
292
269
|
mask = bufferUtil$1.exports.mask = function (source, mask, output, offset, length) {
|
|
293
270
|
if (length < 48) _mask(source, mask, output, offset, length);else bufferUtil.mask(source, mask, output, offset, length);
|
|
294
271
|
};
|
|
295
|
-
|
|
296
272
|
unmask$1 = bufferUtil$1.exports.unmask = function (buffer, mask) {
|
|
297
273
|
if (buffer.length < 32) _unmask(buffer, mask);else bufferUtil.unmask(buffer, mask);
|
|
298
274
|
};
|
|
299
|
-
} catch (e) {
|
|
275
|
+
} catch (e) {
|
|
276
|
+
// Continue regardless of the error.
|
|
300
277
|
}
|
|
301
278
|
}
|
|
302
|
-
|
|
303
279
|
const kDone = Symbol('kDone');
|
|
304
280
|
const kRun = Symbol('kRun');
|
|
281
|
+
|
|
305
282
|
/**
|
|
306
283
|
* A very simple job queue with adjustable concurrency. Adapted from
|
|
307
284
|
* https://github.com/STRML/async-limiter
|
|
308
285
|
*/
|
|
309
|
-
|
|
310
286
|
class Limiter$1 {
|
|
311
287
|
/**
|
|
312
288
|
* Creates a new `Limiter`.
|
|
@@ -319,42 +295,36 @@ class Limiter$1 {
|
|
|
319
295
|
this.pending--;
|
|
320
296
|
this[kRun]();
|
|
321
297
|
};
|
|
322
|
-
|
|
323
298
|
this.concurrency = concurrency || Infinity;
|
|
324
299
|
this.jobs = [];
|
|
325
300
|
this.pending = 0;
|
|
326
301
|
}
|
|
302
|
+
|
|
327
303
|
/**
|
|
328
304
|
* Adds a job to the queue.
|
|
329
305
|
*
|
|
330
306
|
* @param {Function} job The job to run
|
|
331
307
|
* @public
|
|
332
308
|
*/
|
|
333
|
-
|
|
334
|
-
|
|
335
309
|
add(job) {
|
|
336
310
|
this.jobs.push(job);
|
|
337
311
|
this[kRun]();
|
|
338
312
|
}
|
|
313
|
+
|
|
339
314
|
/**
|
|
340
315
|
* Removes a job from the queue and runs it if possible.
|
|
341
316
|
*
|
|
342
317
|
* @private
|
|
343
318
|
*/
|
|
344
|
-
|
|
345
|
-
|
|
346
319
|
[kRun]() {
|
|
347
320
|
if (this.pending === this.concurrency) return;
|
|
348
|
-
|
|
349
321
|
if (this.jobs.length) {
|
|
350
322
|
const job = this.jobs.shift();
|
|
351
323
|
this.pending++;
|
|
352
324
|
job(this[kDone]);
|
|
353
325
|
}
|
|
354
326
|
}
|
|
355
|
-
|
|
356
327
|
}
|
|
357
|
-
|
|
358
328
|
var limiter = Limiter$1;
|
|
359
329
|
const zlib = require$$0$1;
|
|
360
330
|
const bufferUtil = bufferUtil$1.exports;
|
|
@@ -367,19 +337,20 @@ const kPerMessageDeflate = Symbol('permessage-deflate');
|
|
|
367
337
|
const kTotalLength = Symbol('total-length');
|
|
368
338
|
const kCallback = Symbol('callback');
|
|
369
339
|
const kBuffers = Symbol('buffers');
|
|
370
|
-
const kError$1 = Symbol('error');
|
|
340
|
+
const kError$1 = Symbol('error');
|
|
341
|
+
|
|
342
|
+
//
|
|
371
343
|
// We limit zlib concurrency, which prevents severe memory fragmentation
|
|
372
344
|
// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913
|
|
373
345
|
// and https://github.com/websockets/ws/issues/1202
|
|
374
346
|
//
|
|
375
347
|
// Intentionally global; it's the global thread pool that's an issue.
|
|
376
348
|
//
|
|
377
|
-
|
|
378
349
|
let zlibLimiter;
|
|
350
|
+
|
|
379
351
|
/**
|
|
380
352
|
* permessage-deflate implementation.
|
|
381
353
|
*/
|
|
382
|
-
|
|
383
354
|
class PerMessageDeflate$4 {
|
|
384
355
|
/**
|
|
385
356
|
* Creates a PerMessageDeflate instance.
|
|
@@ -413,51 +384,44 @@ class PerMessageDeflate$4 {
|
|
|
413
384
|
this._deflate = null;
|
|
414
385
|
this._inflate = null;
|
|
415
386
|
this.params = null;
|
|
416
|
-
|
|
417
387
|
if (!zlibLimiter) {
|
|
418
388
|
const concurrency = this._options.concurrencyLimit !== undefined ? this._options.concurrencyLimit : 10;
|
|
419
389
|
zlibLimiter = new Limiter(concurrency);
|
|
420
390
|
}
|
|
421
391
|
}
|
|
392
|
+
|
|
422
393
|
/**
|
|
423
394
|
* @type {String}
|
|
424
395
|
*/
|
|
425
|
-
|
|
426
|
-
|
|
427
396
|
static get extensionName() {
|
|
428
397
|
return 'permessage-deflate';
|
|
429
398
|
}
|
|
399
|
+
|
|
430
400
|
/**
|
|
431
401
|
* Create an extension negotiation offer.
|
|
432
402
|
*
|
|
433
403
|
* @return {Object} Extension parameters
|
|
434
404
|
* @public
|
|
435
405
|
*/
|
|
436
|
-
|
|
437
|
-
|
|
438
406
|
offer() {
|
|
439
407
|
const params = {};
|
|
440
|
-
|
|
441
408
|
if (this._options.serverNoContextTakeover) {
|
|
442
409
|
params.server_no_context_takeover = true;
|
|
443
410
|
}
|
|
444
|
-
|
|
445
411
|
if (this._options.clientNoContextTakeover) {
|
|
446
412
|
params.client_no_context_takeover = true;
|
|
447
413
|
}
|
|
448
|
-
|
|
449
414
|
if (this._options.serverMaxWindowBits) {
|
|
450
415
|
params.server_max_window_bits = this._options.serverMaxWindowBits;
|
|
451
416
|
}
|
|
452
|
-
|
|
453
417
|
if (this._options.clientMaxWindowBits) {
|
|
454
418
|
params.client_max_window_bits = this._options.clientMaxWindowBits;
|
|
455
419
|
} else if (this._options.clientMaxWindowBits == null) {
|
|
456
420
|
params.client_max_window_bits = true;
|
|
457
421
|
}
|
|
458
|
-
|
|
459
422
|
return params;
|
|
460
423
|
}
|
|
424
|
+
|
|
461
425
|
/**
|
|
462
426
|
* Accept an extension negotiation offer/response.
|
|
463
427
|
*
|
|
@@ -465,39 +429,32 @@ class PerMessageDeflate$4 {
|
|
|
465
429
|
* @return {Object} Accepted configuration
|
|
466
430
|
* @public
|
|
467
431
|
*/
|
|
468
|
-
|
|
469
|
-
|
|
470
432
|
accept(configurations) {
|
|
471
433
|
configurations = this.normalizeParams(configurations);
|
|
472
434
|
this.params = this._isServer ? this.acceptAsServer(configurations) : this.acceptAsClient(configurations);
|
|
473
435
|
return this.params;
|
|
474
436
|
}
|
|
437
|
+
|
|
475
438
|
/**
|
|
476
439
|
* Releases all resources used by the extension.
|
|
477
440
|
*
|
|
478
441
|
* @public
|
|
479
442
|
*/
|
|
480
|
-
|
|
481
|
-
|
|
482
443
|
cleanup() {
|
|
483
444
|
if (this._inflate) {
|
|
484
445
|
this._inflate.close();
|
|
485
|
-
|
|
486
446
|
this._inflate = null;
|
|
487
447
|
}
|
|
488
|
-
|
|
489
448
|
if (this._deflate) {
|
|
490
449
|
const callback = this._deflate[kCallback];
|
|
491
|
-
|
|
492
450
|
this._deflate.close();
|
|
493
|
-
|
|
494
451
|
this._deflate = null;
|
|
495
|
-
|
|
496
452
|
if (callback) {
|
|
497
453
|
callback(new Error('The deflate stream was closed while data was being processed'));
|
|
498
454
|
}
|
|
499
455
|
}
|
|
500
456
|
}
|
|
457
|
+
|
|
501
458
|
/**
|
|
502
459
|
* Accept an extension negotiation offer.
|
|
503
460
|
*
|
|
@@ -505,42 +462,34 @@ class PerMessageDeflate$4 {
|
|
|
505
462
|
* @return {Object} Accepted configuration
|
|
506
463
|
* @private
|
|
507
464
|
*/
|
|
508
|
-
|
|
509
|
-
|
|
510
465
|
acceptAsServer(offers) {
|
|
511
466
|
const opts = this._options;
|
|
512
467
|
const accepted = offers.find(params => {
|
|
513
468
|
if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === 'number' && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === 'number' && !params.client_max_window_bits) {
|
|
514
469
|
return false;
|
|
515
470
|
}
|
|
516
|
-
|
|
517
471
|
return true;
|
|
518
472
|
});
|
|
519
|
-
|
|
520
473
|
if (!accepted) {
|
|
521
474
|
throw new Error('None of the extension offers can be accepted');
|
|
522
475
|
}
|
|
523
|
-
|
|
524
476
|
if (opts.serverNoContextTakeover) {
|
|
525
477
|
accepted.server_no_context_takeover = true;
|
|
526
478
|
}
|
|
527
|
-
|
|
528
479
|
if (opts.clientNoContextTakeover) {
|
|
529
480
|
accepted.client_no_context_takeover = true;
|
|
530
481
|
}
|
|
531
|
-
|
|
532
482
|
if (typeof opts.serverMaxWindowBits === 'number') {
|
|
533
483
|
accepted.server_max_window_bits = opts.serverMaxWindowBits;
|
|
534
484
|
}
|
|
535
|
-
|
|
536
485
|
if (typeof opts.clientMaxWindowBits === 'number') {
|
|
537
486
|
accepted.client_max_window_bits = opts.clientMaxWindowBits;
|
|
538
487
|
} else if (accepted.client_max_window_bits === true || opts.clientMaxWindowBits === false) {
|
|
539
488
|
delete accepted.client_max_window_bits;
|
|
540
489
|
}
|
|
541
|
-
|
|
542
490
|
return accepted;
|
|
543
491
|
}
|
|
492
|
+
|
|
544
493
|
/**
|
|
545
494
|
* Accept the extension negotiation response.
|
|
546
495
|
*
|
|
@@ -548,15 +497,11 @@ class PerMessageDeflate$4 {
|
|
|
548
497
|
* @return {Object} Accepted configuration
|
|
549
498
|
* @private
|
|
550
499
|
*/
|
|
551
|
-
|
|
552
|
-
|
|
553
500
|
acceptAsClient(response) {
|
|
554
501
|
const params = response[0];
|
|
555
|
-
|
|
556
502
|
if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) {
|
|
557
503
|
throw new Error('Unexpected parameter "client_no_context_takeover"');
|
|
558
504
|
}
|
|
559
|
-
|
|
560
505
|
if (!params.client_max_window_bits) {
|
|
561
506
|
if (typeof this._options.clientMaxWindowBits === 'number') {
|
|
562
507
|
params.client_max_window_bits = this._options.clientMaxWindowBits;
|
|
@@ -564,9 +509,9 @@ class PerMessageDeflate$4 {
|
|
|
564
509
|
} else if (this._options.clientMaxWindowBits === false || typeof this._options.clientMaxWindowBits === 'number' && params.client_max_window_bits > this._options.clientMaxWindowBits) {
|
|
565
510
|
throw new Error('Unexpected or invalid parameter "client_max_window_bits"');
|
|
566
511
|
}
|
|
567
|
-
|
|
568
512
|
return params;
|
|
569
513
|
}
|
|
514
|
+
|
|
570
515
|
/**
|
|
571
516
|
* Normalize parameters.
|
|
572
517
|
*
|
|
@@ -574,38 +519,29 @@ class PerMessageDeflate$4 {
|
|
|
574
519
|
* @return {Array} The offers/response with normalized parameters
|
|
575
520
|
* @private
|
|
576
521
|
*/
|
|
577
|
-
|
|
578
|
-
|
|
579
522
|
normalizeParams(configurations) {
|
|
580
523
|
configurations.forEach(params => {
|
|
581
524
|
Object.keys(params).forEach(key => {
|
|
582
525
|
let value = params[key];
|
|
583
|
-
|
|
584
526
|
if (value.length > 1) {
|
|
585
527
|
throw new Error(`Parameter "${key}" must have only a single value`);
|
|
586
528
|
}
|
|
587
|
-
|
|
588
529
|
value = value[0];
|
|
589
|
-
|
|
590
530
|
if (key === 'client_max_window_bits') {
|
|
591
531
|
if (value !== true) {
|
|
592
532
|
const num = +value;
|
|
593
|
-
|
|
594
533
|
if (!Number.isInteger(num) || num < 8 || num > 15) {
|
|
595
534
|
throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
|
|
596
535
|
}
|
|
597
|
-
|
|
598
536
|
value = num;
|
|
599
537
|
} else if (!this._isServer) {
|
|
600
538
|
throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
|
|
601
539
|
}
|
|
602
540
|
} else if (key === 'server_max_window_bits') {
|
|
603
541
|
const num = +value;
|
|
604
|
-
|
|
605
542
|
if (!Number.isInteger(num) || num < 8 || num > 15) {
|
|
606
543
|
throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
|
|
607
544
|
}
|
|
608
|
-
|
|
609
545
|
value = num;
|
|
610
546
|
} else if (key === 'client_no_context_takeover' || key === 'server_no_context_takeover') {
|
|
611
547
|
if (value !== true) {
|
|
@@ -614,12 +550,12 @@ class PerMessageDeflate$4 {
|
|
|
614
550
|
} else {
|
|
615
551
|
throw new Error(`Unknown parameter "${key}"`);
|
|
616
552
|
}
|
|
617
|
-
|
|
618
553
|
params[key] = value;
|
|
619
554
|
});
|
|
620
555
|
});
|
|
621
556
|
return configurations;
|
|
622
557
|
}
|
|
558
|
+
|
|
623
559
|
/**
|
|
624
560
|
* Decompress data. Concurrency limited.
|
|
625
561
|
*
|
|
@@ -628,8 +564,6 @@ class PerMessageDeflate$4 {
|
|
|
628
564
|
* @param {Function} callback Callback
|
|
629
565
|
* @public
|
|
630
566
|
*/
|
|
631
|
-
|
|
632
|
-
|
|
633
567
|
decompress(data, fin, callback) {
|
|
634
568
|
zlibLimiter.add(done => {
|
|
635
569
|
this._decompress(data, fin, (err, result) => {
|
|
@@ -638,6 +572,7 @@ class PerMessageDeflate$4 {
|
|
|
638
572
|
});
|
|
639
573
|
});
|
|
640
574
|
}
|
|
575
|
+
|
|
641
576
|
/**
|
|
642
577
|
* Compress data. Concurrency limited.
|
|
643
578
|
*
|
|
@@ -646,8 +581,6 @@ class PerMessageDeflate$4 {
|
|
|
646
581
|
* @param {Function} callback Callback
|
|
647
582
|
* @public
|
|
648
583
|
*/
|
|
649
|
-
|
|
650
|
-
|
|
651
584
|
compress(data, fin, callback) {
|
|
652
585
|
zlibLimiter.add(done => {
|
|
653
586
|
this._compress(data, fin, (err, result) => {
|
|
@@ -656,6 +589,7 @@ class PerMessageDeflate$4 {
|
|
|
656
589
|
});
|
|
657
590
|
});
|
|
658
591
|
}
|
|
592
|
+
|
|
659
593
|
/**
|
|
660
594
|
* Decompress data.
|
|
661
595
|
*
|
|
@@ -664,61 +598,47 @@ class PerMessageDeflate$4 {
|
|
|
664
598
|
* @param {Function} callback Callback
|
|
665
599
|
* @private
|
|
666
600
|
*/
|
|
667
|
-
|
|
668
|
-
|
|
669
601
|
_decompress(data, fin, callback) {
|
|
670
602
|
const endpoint = this._isServer ? 'client' : 'server';
|
|
671
|
-
|
|
672
603
|
if (!this._inflate) {
|
|
673
604
|
const key = `${endpoint}_max_window_bits`;
|
|
674
605
|
const windowBits = typeof this.params[key] !== 'number' ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key];
|
|
675
|
-
this._inflate = zlib.createInflateRaw({
|
|
606
|
+
this._inflate = zlib.createInflateRaw({
|
|
607
|
+
...this._options.zlibInflateOptions,
|
|
676
608
|
windowBits
|
|
677
609
|
});
|
|
678
610
|
this._inflate[kPerMessageDeflate] = this;
|
|
679
611
|
this._inflate[kTotalLength] = 0;
|
|
680
612
|
this._inflate[kBuffers] = [];
|
|
681
|
-
|
|
682
613
|
this._inflate.on('error', inflateOnError);
|
|
683
|
-
|
|
684
614
|
this._inflate.on('data', inflateOnData);
|
|
685
615
|
}
|
|
686
|
-
|
|
687
616
|
this._inflate[kCallback] = callback;
|
|
688
|
-
|
|
689
617
|
this._inflate.write(data);
|
|
690
|
-
|
|
691
618
|
if (fin) this._inflate.write(TRAILER);
|
|
692
|
-
|
|
693
619
|
this._inflate.flush(() => {
|
|
694
620
|
const err = this._inflate[kError$1];
|
|
695
|
-
|
|
696
621
|
if (err) {
|
|
697
622
|
this._inflate.close();
|
|
698
|
-
|
|
699
623
|
this._inflate = null;
|
|
700
624
|
callback(err);
|
|
701
625
|
return;
|
|
702
626
|
}
|
|
703
|
-
|
|
704
627
|
const data = bufferUtil.concat(this._inflate[kBuffers], this._inflate[kTotalLength]);
|
|
705
|
-
|
|
706
628
|
if (this._inflate._readableState.endEmitted) {
|
|
707
629
|
this._inflate.close();
|
|
708
|
-
|
|
709
630
|
this._inflate = null;
|
|
710
631
|
} else {
|
|
711
632
|
this._inflate[kTotalLength] = 0;
|
|
712
633
|
this._inflate[kBuffers] = [];
|
|
713
|
-
|
|
714
634
|
if (fin && this.params[`${endpoint}_no_context_takeover`]) {
|
|
715
635
|
this._inflate.reset();
|
|
716
636
|
}
|
|
717
637
|
}
|
|
718
|
-
|
|
719
638
|
callback(null, data);
|
|
720
639
|
});
|
|
721
640
|
}
|
|
641
|
+
|
|
722
642
|
/**
|
|
723
643
|
* Compress data.
|
|
724
644
|
*
|
|
@@ -727,27 +647,21 @@ class PerMessageDeflate$4 {
|
|
|
727
647
|
* @param {Function} callback Callback
|
|
728
648
|
* @private
|
|
729
649
|
*/
|
|
730
|
-
|
|
731
|
-
|
|
732
650
|
_compress(data, fin, callback) {
|
|
733
651
|
const endpoint = this._isServer ? 'server' : 'client';
|
|
734
|
-
|
|
735
652
|
if (!this._deflate) {
|
|
736
653
|
const key = `${endpoint}_max_window_bits`;
|
|
737
654
|
const windowBits = typeof this.params[key] !== 'number' ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key];
|
|
738
|
-
this._deflate = zlib.createDeflateRaw({
|
|
655
|
+
this._deflate = zlib.createDeflateRaw({
|
|
656
|
+
...this._options.zlibDeflateOptions,
|
|
739
657
|
windowBits
|
|
740
658
|
});
|
|
741
659
|
this._deflate[kTotalLength] = 0;
|
|
742
660
|
this._deflate[kBuffers] = [];
|
|
743
|
-
|
|
744
661
|
this._deflate.on('data', deflateOnData);
|
|
745
662
|
}
|
|
746
|
-
|
|
747
663
|
this._deflate[kCallback] = callback;
|
|
748
|
-
|
|
749
664
|
this._deflate.write(data);
|
|
750
|
-
|
|
751
665
|
this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
|
|
752
666
|
if (!this._deflate) {
|
|
753
667
|
//
|
|
@@ -755,69 +669,61 @@ class PerMessageDeflate$4 {
|
|
|
755
669
|
//
|
|
756
670
|
return;
|
|
757
671
|
}
|
|
758
|
-
|
|
759
672
|
let data = bufferUtil.concat(this._deflate[kBuffers], this._deflate[kTotalLength]);
|
|
760
|
-
if (fin) data = data.slice(0, data.length - 4);
|
|
673
|
+
if (fin) data = data.slice(0, data.length - 4);
|
|
674
|
+
|
|
675
|
+
//
|
|
761
676
|
// Ensure that the callback will not be called again in
|
|
762
677
|
// `PerMessageDeflate#cleanup()`.
|
|
763
678
|
//
|
|
764
|
-
|
|
765
679
|
this._deflate[kCallback] = null;
|
|
766
680
|
this._deflate[kTotalLength] = 0;
|
|
767
681
|
this._deflate[kBuffers] = [];
|
|
768
|
-
|
|
769
682
|
if (fin && this.params[`${endpoint}_no_context_takeover`]) {
|
|
770
683
|
this._deflate.reset();
|
|
771
684
|
}
|
|
772
|
-
|
|
773
685
|
callback(null, data);
|
|
774
686
|
});
|
|
775
687
|
}
|
|
776
|
-
|
|
777
688
|
}
|
|
778
|
-
|
|
779
689
|
var permessageDeflate = PerMessageDeflate$4;
|
|
690
|
+
|
|
780
691
|
/**
|
|
781
692
|
* The listener of the `zlib.DeflateRaw` stream `'data'` event.
|
|
782
693
|
*
|
|
783
694
|
* @param {Buffer} chunk A chunk of data
|
|
784
695
|
* @private
|
|
785
696
|
*/
|
|
786
|
-
|
|
787
697
|
function deflateOnData(chunk) {
|
|
788
698
|
this[kBuffers].push(chunk);
|
|
789
699
|
this[kTotalLength] += chunk.length;
|
|
790
700
|
}
|
|
701
|
+
|
|
791
702
|
/**
|
|
792
703
|
* The listener of the `zlib.InflateRaw` stream `'data'` event.
|
|
793
704
|
*
|
|
794
705
|
* @param {Buffer} chunk A chunk of data
|
|
795
706
|
* @private
|
|
796
707
|
*/
|
|
797
|
-
|
|
798
|
-
|
|
799
708
|
function inflateOnData(chunk) {
|
|
800
709
|
this[kTotalLength] += chunk.length;
|
|
801
|
-
|
|
802
710
|
if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) {
|
|
803
711
|
this[kBuffers].push(chunk);
|
|
804
712
|
return;
|
|
805
713
|
}
|
|
806
|
-
|
|
807
714
|
this[kError$1] = new RangeError('Max payload size exceeded');
|
|
808
715
|
this[kError$1].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';
|
|
809
716
|
this[kError$1][kStatusCode$2] = 1009;
|
|
810
717
|
this.removeListener('data', inflateOnData);
|
|
811
718
|
this.reset();
|
|
812
719
|
}
|
|
720
|
+
|
|
813
721
|
/**
|
|
814
722
|
* The listener of the `zlib.InflateRaw` stream `'error'` event.
|
|
815
723
|
*
|
|
816
724
|
* @param {Error} err The emitted error
|
|
817
725
|
* @private
|
|
818
726
|
*/
|
|
819
|
-
|
|
820
|
-
|
|
821
727
|
function inflateOnError(err) {
|
|
822
728
|
//
|
|
823
729
|
// There is no need to call `Zlib#close()` as the handle is automatically
|
|
@@ -827,11 +733,12 @@ function inflateOnError(err) {
|
|
|
827
733
|
err[kStatusCode$2] = 1007;
|
|
828
734
|
this[kCallback](err);
|
|
829
735
|
}
|
|
830
|
-
|
|
831
736
|
var validation = {
|
|
832
737
|
exports: {}
|
|
833
738
|
};
|
|
834
|
-
var isValidUTF8_1;
|
|
739
|
+
var isValidUTF8_1;
|
|
740
|
+
|
|
741
|
+
//
|
|
835
742
|
// Allowed token characters:
|
|
836
743
|
//
|
|
837
744
|
// '!', '#', '$', '%', '&', ''', '*', '+', '-',
|
|
@@ -843,16 +750,23 @@ var isValidUTF8_1; //
|
|
|
843
750
|
// ...
|
|
844
751
|
//
|
|
845
752
|
// prettier-ignore
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
853
|
-
|
|
753
|
+
const tokenChars$2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
754
|
+
// 0 - 15
|
|
755
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
756
|
+
// 16 - 31
|
|
757
|
+
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
|
|
758
|
+
// 32 - 47
|
|
759
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
760
|
+
// 48 - 63
|
|
761
|
+
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
762
|
+
// 64 - 79
|
|
763
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
|
764
|
+
// 80 - 95
|
|
765
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
766
|
+
// 96 - 111
|
|
854
767
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127
|
|
855
768
|
];
|
|
769
|
+
|
|
856
770
|
/**
|
|
857
771
|
* Checks if a status code is allowed in a close frame.
|
|
858
772
|
*
|
|
@@ -860,10 +774,10 @@ const tokenChars$2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15
|
|
|
860
774
|
* @return {Boolean} `true` if the status code is valid, else `false`
|
|
861
775
|
* @public
|
|
862
776
|
*/
|
|
863
|
-
|
|
864
777
|
function isValidStatusCode$2(code) {
|
|
865
778
|
return code >= 1000 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3000 && code <= 4999;
|
|
866
779
|
}
|
|
780
|
+
|
|
867
781
|
/**
|
|
868
782
|
* Checks if a given buffer contains only correct UTF-8.
|
|
869
783
|
* Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by
|
|
@@ -873,12 +787,9 @@ function isValidStatusCode$2(code) {
|
|
|
873
787
|
* @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`
|
|
874
788
|
* @public
|
|
875
789
|
*/
|
|
876
|
-
|
|
877
|
-
|
|
878
790
|
function _isValidUTF8(buf) {
|
|
879
791
|
const len = buf.length;
|
|
880
792
|
let i = 0;
|
|
881
|
-
|
|
882
793
|
while (i < len) {
|
|
883
794
|
if ((buf[i] & 0x80) === 0) {
|
|
884
795
|
// 0xxxxxxx
|
|
@@ -889,52 +800,48 @@ function _isValidUTF8(buf) {
|
|
|
889
800
|
) {
|
|
890
801
|
return false;
|
|
891
802
|
}
|
|
892
|
-
|
|
893
803
|
i += 2;
|
|
894
804
|
} else if ((buf[i] & 0xf0) === 0xe0) {
|
|
895
805
|
// 1110xxxx 10xxxxxx 10xxxxxx
|
|
896
|
-
if (i + 2 >= len || (buf[i + 1] & 0xc0) !== 0x80 || (buf[i + 2] & 0xc0) !== 0x80 || buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80 ||
|
|
806
|
+
if (i + 2 >= len || (buf[i + 1] & 0xc0) !== 0x80 || (buf[i + 2] & 0xc0) !== 0x80 || buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80 ||
|
|
807
|
+
// Overlong
|
|
897
808
|
buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0 // Surrogate (U+D800 - U+DFFF)
|
|
898
809
|
) {
|
|
899
810
|
return false;
|
|
900
811
|
}
|
|
901
|
-
|
|
902
812
|
i += 3;
|
|
903
813
|
} else if ((buf[i] & 0xf8) === 0xf0) {
|
|
904
814
|
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
905
|
-
if (i + 3 >= len || (buf[i + 1] & 0xc0) !== 0x80 || (buf[i + 2] & 0xc0) !== 0x80 || (buf[i + 3] & 0xc0) !== 0x80 || buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80 ||
|
|
815
|
+
if (i + 3 >= len || (buf[i + 1] & 0xc0) !== 0x80 || (buf[i + 2] & 0xc0) !== 0x80 || (buf[i + 3] & 0xc0) !== 0x80 || buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80 ||
|
|
816
|
+
// Overlong
|
|
906
817
|
buf[i] === 0xf4 && buf[i + 1] > 0x8f || buf[i] > 0xf4 // > U+10FFFF
|
|
907
818
|
) {
|
|
908
819
|
return false;
|
|
909
820
|
}
|
|
910
|
-
|
|
911
821
|
i += 4;
|
|
912
822
|
} else {
|
|
913
823
|
return false;
|
|
914
824
|
}
|
|
915
825
|
}
|
|
916
|
-
|
|
917
826
|
return true;
|
|
918
827
|
}
|
|
919
|
-
|
|
920
828
|
validation.exports = {
|
|
921
829
|
isValidStatusCode: isValidStatusCode$2,
|
|
922
830
|
isValidUTF8: _isValidUTF8,
|
|
923
831
|
tokenChars: tokenChars$2
|
|
924
832
|
};
|
|
925
|
-
/* istanbul ignore else */
|
|
926
833
|
|
|
834
|
+
/* istanbul ignore else */
|
|
927
835
|
if (!process.env.WS_NO_UTF_8_VALIDATE) {
|
|
928
836
|
try {
|
|
929
837
|
const isValidUTF8 = require('utf-8-validate');
|
|
930
|
-
|
|
931
838
|
isValidUTF8_1 = validation.exports.isValidUTF8 = function (buf) {
|
|
932
839
|
return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf);
|
|
933
840
|
};
|
|
934
|
-
} catch (e) {
|
|
841
|
+
} catch (e) {
|
|
842
|
+
// Continue regardless of the error.
|
|
935
843
|
}
|
|
936
844
|
}
|
|
937
|
-
|
|
938
845
|
const {
|
|
939
846
|
Writable
|
|
940
847
|
} = require$$0;
|
|
@@ -960,12 +867,12 @@ const GET_PAYLOAD_LENGTH_64 = 2;
|
|
|
960
867
|
const GET_MASK = 3;
|
|
961
868
|
const GET_DATA = 4;
|
|
962
869
|
const INFLATING = 5;
|
|
870
|
+
|
|
963
871
|
/**
|
|
964
872
|
* HyBi Receiver implementation.
|
|
965
873
|
*
|
|
966
874
|
* @extends Writable
|
|
967
875
|
*/
|
|
968
|
-
|
|
969
876
|
class Receiver$1 extends Writable {
|
|
970
877
|
/**
|
|
971
878
|
* Creates a Receiver instance.
|
|
@@ -1003,6 +910,7 @@ class Receiver$1 extends Writable {
|
|
|
1003
910
|
this._state = GET_INFO;
|
|
1004
911
|
this._loop = false;
|
|
1005
912
|
}
|
|
913
|
+
|
|
1006
914
|
/**
|
|
1007
915
|
* Implements `Writable.prototype._write()`.
|
|
1008
916
|
*
|
|
@@ -1011,16 +919,13 @@ class Receiver$1 extends Writable {
|
|
|
1011
919
|
* @param {Function} cb Callback
|
|
1012
920
|
* @private
|
|
1013
921
|
*/
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
922
|
_write(chunk, encoding, cb) {
|
|
1017
923
|
if (this._opcode === 0x08 && this._state == GET_INFO) return cb();
|
|
1018
924
|
this._bufferedBytes += chunk.length;
|
|
1019
|
-
|
|
1020
925
|
this._buffers.push(chunk);
|
|
1021
|
-
|
|
1022
926
|
this.startLoop(cb);
|
|
1023
927
|
}
|
|
928
|
+
|
|
1024
929
|
/**
|
|
1025
930
|
* Consumes `n` bytes from the buffered data.
|
|
1026
931
|
*
|
|
@@ -1028,141 +933,113 @@ class Receiver$1 extends Writable {
|
|
|
1028
933
|
* @return {Buffer} The consumed bytes
|
|
1029
934
|
* @private
|
|
1030
935
|
*/
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
936
|
consume(n) {
|
|
1034
937
|
this._bufferedBytes -= n;
|
|
1035
938
|
if (n === this._buffers[0].length) return this._buffers.shift();
|
|
1036
|
-
|
|
1037
939
|
if (n < this._buffers[0].length) {
|
|
1038
940
|
const buf = this._buffers[0];
|
|
1039
941
|
this._buffers[0] = buf.slice(n);
|
|
1040
942
|
return buf.slice(0, n);
|
|
1041
943
|
}
|
|
1042
|
-
|
|
1043
944
|
const dst = Buffer.allocUnsafe(n);
|
|
1044
|
-
|
|
1045
945
|
do {
|
|
1046
946
|
const buf = this._buffers[0];
|
|
1047
947
|
const offset = dst.length - n;
|
|
1048
|
-
|
|
1049
948
|
if (n >= buf.length) {
|
|
1050
949
|
dst.set(this._buffers.shift(), offset);
|
|
1051
950
|
} else {
|
|
1052
951
|
dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
|
|
1053
952
|
this._buffers[0] = buf.slice(n);
|
|
1054
953
|
}
|
|
1055
|
-
|
|
1056
954
|
n -= buf.length;
|
|
1057
955
|
} while (n > 0);
|
|
1058
|
-
|
|
1059
956
|
return dst;
|
|
1060
957
|
}
|
|
958
|
+
|
|
1061
959
|
/**
|
|
1062
960
|
* Starts the parsing loop.
|
|
1063
961
|
*
|
|
1064
962
|
* @param {Function} cb Callback
|
|
1065
963
|
* @private
|
|
1066
964
|
*/
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
965
|
startLoop(cb) {
|
|
1070
966
|
let err;
|
|
1071
967
|
this._loop = true;
|
|
1072
|
-
|
|
1073
968
|
do {
|
|
1074
969
|
switch (this._state) {
|
|
1075
970
|
case GET_INFO:
|
|
1076
971
|
err = this.getInfo();
|
|
1077
972
|
break;
|
|
1078
|
-
|
|
1079
973
|
case GET_PAYLOAD_LENGTH_16:
|
|
1080
974
|
err = this.getPayloadLength16();
|
|
1081
975
|
break;
|
|
1082
|
-
|
|
1083
976
|
case GET_PAYLOAD_LENGTH_64:
|
|
1084
977
|
err = this.getPayloadLength64();
|
|
1085
978
|
break;
|
|
1086
|
-
|
|
1087
979
|
case GET_MASK:
|
|
1088
980
|
this.getMask();
|
|
1089
981
|
break;
|
|
1090
|
-
|
|
1091
982
|
case GET_DATA:
|
|
1092
983
|
err = this.getData(cb);
|
|
1093
984
|
break;
|
|
1094
|
-
|
|
1095
985
|
default:
|
|
1096
986
|
// `INFLATING`
|
|
1097
987
|
this._loop = false;
|
|
1098
988
|
return;
|
|
1099
989
|
}
|
|
1100
990
|
} while (this._loop);
|
|
1101
|
-
|
|
1102
991
|
cb(err);
|
|
1103
992
|
}
|
|
993
|
+
|
|
1104
994
|
/**
|
|
1105
995
|
* Reads the first two bytes of a frame.
|
|
1106
996
|
*
|
|
1107
997
|
* @return {(RangeError|undefined)} A possible error
|
|
1108
998
|
* @private
|
|
1109
999
|
*/
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
1000
|
getInfo() {
|
|
1113
1001
|
if (this._bufferedBytes < 2) {
|
|
1114
1002
|
this._loop = false;
|
|
1115
1003
|
return;
|
|
1116
1004
|
}
|
|
1117
|
-
|
|
1118
1005
|
const buf = this.consume(2);
|
|
1119
|
-
|
|
1120
1006
|
if ((buf[0] & 0x30) !== 0x00) {
|
|
1121
1007
|
this._loop = false;
|
|
1122
1008
|
return error(RangeError, 'RSV2 and RSV3 must be clear', true, 1002, 'WS_ERR_UNEXPECTED_RSV_2_3');
|
|
1123
1009
|
}
|
|
1124
|
-
|
|
1125
1010
|
const compressed = (buf[0] & 0x40) === 0x40;
|
|
1126
|
-
|
|
1127
1011
|
if (compressed && !this._extensions[PerMessageDeflate$3.extensionName]) {
|
|
1128
1012
|
this._loop = false;
|
|
1129
1013
|
return error(RangeError, 'RSV1 must be clear', true, 1002, 'WS_ERR_UNEXPECTED_RSV_1');
|
|
1130
1014
|
}
|
|
1131
|
-
|
|
1132
1015
|
this._fin = (buf[0] & 0x80) === 0x80;
|
|
1133
1016
|
this._opcode = buf[0] & 0x0f;
|
|
1134
1017
|
this._payloadLength = buf[1] & 0x7f;
|
|
1135
|
-
|
|
1136
1018
|
if (this._opcode === 0x00) {
|
|
1137
1019
|
if (compressed) {
|
|
1138
1020
|
this._loop = false;
|
|
1139
1021
|
return error(RangeError, 'RSV1 must be clear', true, 1002, 'WS_ERR_UNEXPECTED_RSV_1');
|
|
1140
1022
|
}
|
|
1141
|
-
|
|
1142
1023
|
if (!this._fragmented) {
|
|
1143
1024
|
this._loop = false;
|
|
1144
1025
|
return error(RangeError, 'invalid opcode 0', true, 1002, 'WS_ERR_INVALID_OPCODE');
|
|
1145
1026
|
}
|
|
1146
|
-
|
|
1147
1027
|
this._opcode = this._fragmented;
|
|
1148
1028
|
} else if (this._opcode === 0x01 || this._opcode === 0x02) {
|
|
1149
1029
|
if (this._fragmented) {
|
|
1150
1030
|
this._loop = false;
|
|
1151
1031
|
return error(RangeError, `invalid opcode ${this._opcode}`, true, 1002, 'WS_ERR_INVALID_OPCODE');
|
|
1152
1032
|
}
|
|
1153
|
-
|
|
1154
1033
|
this._compressed = compressed;
|
|
1155
1034
|
} else if (this._opcode > 0x07 && this._opcode < 0x0b) {
|
|
1156
1035
|
if (!this._fin) {
|
|
1157
1036
|
this._loop = false;
|
|
1158
1037
|
return error(RangeError, 'FIN must be set', true, 1002, 'WS_ERR_EXPECTED_FIN');
|
|
1159
1038
|
}
|
|
1160
|
-
|
|
1161
1039
|
if (compressed) {
|
|
1162
1040
|
this._loop = false;
|
|
1163
1041
|
return error(RangeError, 'RSV1 must be clear', true, 1002, 'WS_ERR_UNEXPECTED_RSV_1');
|
|
1164
1042
|
}
|
|
1165
|
-
|
|
1166
1043
|
if (this._payloadLength > 0x7d) {
|
|
1167
1044
|
this._loop = false;
|
|
1168
1045
|
return error(RangeError, `invalid payload length ${this._payloadLength}`, true, 1002, 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH');
|
|
@@ -1171,10 +1048,8 @@ class Receiver$1 extends Writable {
|
|
|
1171
1048
|
this._loop = false;
|
|
1172
1049
|
return error(RangeError, `invalid opcode ${this._opcode}`, true, 1002, 'WS_ERR_INVALID_OPCODE');
|
|
1173
1050
|
}
|
|
1174
|
-
|
|
1175
1051
|
if (!this._fin && !this._fragmented) this._fragmented = this._opcode;
|
|
1176
1052
|
this._masked = (buf[1] & 0x80) === 0x80;
|
|
1177
|
-
|
|
1178
1053
|
if (this._isServer) {
|
|
1179
1054
|
if (!this._masked) {
|
|
1180
1055
|
this._loop = false;
|
|
@@ -1184,90 +1059,81 @@ class Receiver$1 extends Writable {
|
|
|
1184
1059
|
this._loop = false;
|
|
1185
1060
|
return error(RangeError, 'MASK must be clear', true, 1002, 'WS_ERR_UNEXPECTED_MASK');
|
|
1186
1061
|
}
|
|
1187
|
-
|
|
1188
1062
|
if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;else return this.haveLength();
|
|
1189
1063
|
}
|
|
1064
|
+
|
|
1190
1065
|
/**
|
|
1191
1066
|
* Gets extended payload length (7+16).
|
|
1192
1067
|
*
|
|
1193
1068
|
* @return {(RangeError|undefined)} A possible error
|
|
1194
1069
|
* @private
|
|
1195
1070
|
*/
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
1071
|
getPayloadLength16() {
|
|
1199
1072
|
if (this._bufferedBytes < 2) {
|
|
1200
1073
|
this._loop = false;
|
|
1201
1074
|
return;
|
|
1202
1075
|
}
|
|
1203
|
-
|
|
1204
1076
|
this._payloadLength = this.consume(2).readUInt16BE(0);
|
|
1205
1077
|
return this.haveLength();
|
|
1206
1078
|
}
|
|
1079
|
+
|
|
1207
1080
|
/**
|
|
1208
1081
|
* Gets extended payload length (7+64).
|
|
1209
1082
|
*
|
|
1210
1083
|
* @return {(RangeError|undefined)} A possible error
|
|
1211
1084
|
* @private
|
|
1212
1085
|
*/
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
1086
|
getPayloadLength64() {
|
|
1216
1087
|
if (this._bufferedBytes < 8) {
|
|
1217
1088
|
this._loop = false;
|
|
1218
1089
|
return;
|
|
1219
1090
|
}
|
|
1220
|
-
|
|
1221
1091
|
const buf = this.consume(8);
|
|
1222
|
-
const num = buf.readUInt32BE(0);
|
|
1092
|
+
const num = buf.readUInt32BE(0);
|
|
1093
|
+
|
|
1094
|
+
//
|
|
1223
1095
|
// The maximum safe integer in JavaScript is 2^53 - 1. An error is returned
|
|
1224
1096
|
// if payload length is greater than this number.
|
|
1225
1097
|
//
|
|
1226
|
-
|
|
1227
1098
|
if (num > Math.pow(2, 53 - 32) - 1) {
|
|
1228
1099
|
this._loop = false;
|
|
1229
1100
|
return error(RangeError, 'Unsupported WebSocket frame: payload length > 2^53 - 1', false, 1009, 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH');
|
|
1230
1101
|
}
|
|
1231
|
-
|
|
1232
1102
|
this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);
|
|
1233
1103
|
return this.haveLength();
|
|
1234
1104
|
}
|
|
1105
|
+
|
|
1235
1106
|
/**
|
|
1236
1107
|
* Payload length has been read.
|
|
1237
1108
|
*
|
|
1238
1109
|
* @return {(RangeError|undefined)} A possible error
|
|
1239
1110
|
* @private
|
|
1240
1111
|
*/
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
1112
|
haveLength() {
|
|
1244
1113
|
if (this._payloadLength && this._opcode < 0x08) {
|
|
1245
1114
|
this._totalPayloadLength += this._payloadLength;
|
|
1246
|
-
|
|
1247
1115
|
if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
|
|
1248
1116
|
this._loop = false;
|
|
1249
1117
|
return error(RangeError, 'Max payload size exceeded', false, 1009, 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH');
|
|
1250
1118
|
}
|
|
1251
1119
|
}
|
|
1252
|
-
|
|
1253
1120
|
if (this._masked) this._state = GET_MASK;else this._state = GET_DATA;
|
|
1254
1121
|
}
|
|
1122
|
+
|
|
1255
1123
|
/**
|
|
1256
1124
|
* Reads mask bytes.
|
|
1257
1125
|
*
|
|
1258
1126
|
* @private
|
|
1259
1127
|
*/
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
1128
|
getMask() {
|
|
1263
1129
|
if (this._bufferedBytes < 4) {
|
|
1264
1130
|
this._loop = false;
|
|
1265
1131
|
return;
|
|
1266
1132
|
}
|
|
1267
|
-
|
|
1268
1133
|
this._mask = this.consume(4);
|
|
1269
1134
|
this._state = GET_DATA;
|
|
1270
1135
|
}
|
|
1136
|
+
|
|
1271
1137
|
/**
|
|
1272
1138
|
* Reads data bytes.
|
|
1273
1139
|
*
|
|
@@ -1275,44 +1141,35 @@ class Receiver$1 extends Writable {
|
|
|
1275
1141
|
* @return {(Error|RangeError|undefined)} A possible error
|
|
1276
1142
|
* @private
|
|
1277
1143
|
*/
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
1144
|
getData(cb) {
|
|
1281
1145
|
let data = EMPTY_BUFFER$2;
|
|
1282
|
-
|
|
1283
1146
|
if (this._payloadLength) {
|
|
1284
1147
|
if (this._bufferedBytes < this._payloadLength) {
|
|
1285
1148
|
this._loop = false;
|
|
1286
1149
|
return;
|
|
1287
1150
|
}
|
|
1288
|
-
|
|
1289
1151
|
data = this.consume(this._payloadLength);
|
|
1290
|
-
|
|
1291
1152
|
if (this._masked && (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0) {
|
|
1292
1153
|
unmask(data, this._mask);
|
|
1293
1154
|
}
|
|
1294
1155
|
}
|
|
1295
|
-
|
|
1296
1156
|
if (this._opcode > 0x07) return this.controlMessage(data);
|
|
1297
|
-
|
|
1298
1157
|
if (this._compressed) {
|
|
1299
1158
|
this._state = INFLATING;
|
|
1300
1159
|
this.decompress(data, cb);
|
|
1301
1160
|
return;
|
|
1302
1161
|
}
|
|
1303
|
-
|
|
1304
1162
|
if (data.length) {
|
|
1305
1163
|
//
|
|
1306
1164
|
// This message is not compressed so its length is the sum of the payload
|
|
1307
1165
|
// length of all fragments.
|
|
1308
1166
|
//
|
|
1309
1167
|
this._messageLength = this._totalPayloadLength;
|
|
1310
|
-
|
|
1311
1168
|
this._fragments.push(data);
|
|
1312
1169
|
}
|
|
1313
|
-
|
|
1314
1170
|
return this.dataMessage();
|
|
1315
1171
|
}
|
|
1172
|
+
|
|
1316
1173
|
/**
|
|
1317
1174
|
* Decompresses data.
|
|
1318
1175
|
*
|
|
@@ -1320,36 +1177,29 @@ class Receiver$1 extends Writable {
|
|
|
1320
1177
|
* @param {Function} cb Callback
|
|
1321
1178
|
* @private
|
|
1322
1179
|
*/
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
1180
|
decompress(data, cb) {
|
|
1326
1181
|
const perMessageDeflate = this._extensions[PerMessageDeflate$3.extensionName];
|
|
1327
1182
|
perMessageDeflate.decompress(data, this._fin, (err, buf) => {
|
|
1328
1183
|
if (err) return cb(err);
|
|
1329
|
-
|
|
1330
1184
|
if (buf.length) {
|
|
1331
1185
|
this._messageLength += buf.length;
|
|
1332
|
-
|
|
1333
1186
|
if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
|
|
1334
1187
|
return cb(error(RangeError, 'Max payload size exceeded', false, 1009, 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'));
|
|
1335
1188
|
}
|
|
1336
|
-
|
|
1337
1189
|
this._fragments.push(buf);
|
|
1338
1190
|
}
|
|
1339
|
-
|
|
1340
1191
|
const er = this.dataMessage();
|
|
1341
1192
|
if (er) return cb(er);
|
|
1342
1193
|
this.startLoop(cb);
|
|
1343
1194
|
});
|
|
1344
1195
|
}
|
|
1196
|
+
|
|
1345
1197
|
/**
|
|
1346
1198
|
* Handles a data message.
|
|
1347
1199
|
*
|
|
1348
1200
|
* @return {(Error|undefined)} A possible error
|
|
1349
1201
|
* @private
|
|
1350
1202
|
*/
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
1203
|
dataMessage() {
|
|
1354
1204
|
if (this._fin) {
|
|
1355
1205
|
const messageLength = this._messageLength;
|
|
@@ -1358,10 +1208,8 @@ class Receiver$1 extends Writable {
|
|
|
1358
1208
|
this._messageLength = 0;
|
|
1359
1209
|
this._fragmented = 0;
|
|
1360
1210
|
this._fragments = [];
|
|
1361
|
-
|
|
1362
1211
|
if (this._opcode === 2) {
|
|
1363
1212
|
let data;
|
|
1364
|
-
|
|
1365
1213
|
if (this._binaryType === 'nodebuffer') {
|
|
1366
1214
|
data = concat(fragments, messageLength);
|
|
1367
1215
|
} else if (this._binaryType === 'arraybuffer') {
|
|
@@ -1369,22 +1217,19 @@ class Receiver$1 extends Writable {
|
|
|
1369
1217
|
} else {
|
|
1370
1218
|
data = fragments;
|
|
1371
1219
|
}
|
|
1372
|
-
|
|
1373
1220
|
this.emit('message', data, true);
|
|
1374
1221
|
} else {
|
|
1375
1222
|
const buf = concat(fragments, messageLength);
|
|
1376
|
-
|
|
1377
1223
|
if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
|
|
1378
1224
|
this._loop = false;
|
|
1379
1225
|
return error(Error, 'invalid UTF-8 sequence', true, 1007, 'WS_ERR_INVALID_UTF8');
|
|
1380
1226
|
}
|
|
1381
|
-
|
|
1382
1227
|
this.emit('message', buf, false);
|
|
1383
1228
|
}
|
|
1384
1229
|
}
|
|
1385
|
-
|
|
1386
1230
|
this._state = GET_INFO;
|
|
1387
1231
|
}
|
|
1232
|
+
|
|
1388
1233
|
/**
|
|
1389
1234
|
* Handles a control message.
|
|
1390
1235
|
*
|
|
@@ -1392,12 +1237,9 @@ class Receiver$1 extends Writable {
|
|
|
1392
1237
|
* @return {(Error|RangeError|undefined)} A possible error
|
|
1393
1238
|
* @private
|
|
1394
1239
|
*/
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
1240
|
controlMessage(data) {
|
|
1398
1241
|
if (this._opcode === 0x08) {
|
|
1399
1242
|
this._loop = false;
|
|
1400
|
-
|
|
1401
1243
|
if (data.length === 0) {
|
|
1402
1244
|
this.emit('conclude', 1005, EMPTY_BUFFER$2);
|
|
1403
1245
|
this.end();
|
|
@@ -1405,17 +1247,13 @@ class Receiver$1 extends Writable {
|
|
|
1405
1247
|
return error(RangeError, 'invalid payload length 1', true, 1002, 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH');
|
|
1406
1248
|
} else {
|
|
1407
1249
|
const code = data.readUInt16BE(0);
|
|
1408
|
-
|
|
1409
1250
|
if (!isValidStatusCode$1(code)) {
|
|
1410
1251
|
return error(RangeError, `invalid status code ${code}`, true, 1002, 'WS_ERR_INVALID_CLOSE_CODE');
|
|
1411
1252
|
}
|
|
1412
|
-
|
|
1413
1253
|
const buf = data.slice(2);
|
|
1414
|
-
|
|
1415
1254
|
if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
|
|
1416
1255
|
return error(Error, 'invalid UTF-8 sequence', true, 1007, 'WS_ERR_INVALID_UTF8');
|
|
1417
1256
|
}
|
|
1418
|
-
|
|
1419
1257
|
this.emit('conclude', code, buf);
|
|
1420
1258
|
this.end();
|
|
1421
1259
|
}
|
|
@@ -1424,13 +1262,11 @@ class Receiver$1 extends Writable {
|
|
|
1424
1262
|
} else {
|
|
1425
1263
|
this.emit('pong', data);
|
|
1426
1264
|
}
|
|
1427
|
-
|
|
1428
1265
|
this._state = GET_INFO;
|
|
1429
1266
|
}
|
|
1430
|
-
|
|
1431
1267
|
}
|
|
1432
|
-
|
|
1433
1268
|
var receiver = Receiver$1;
|
|
1269
|
+
|
|
1434
1270
|
/**
|
|
1435
1271
|
* Builds an error object.
|
|
1436
1272
|
*
|
|
@@ -1443,7 +1279,6 @@ var receiver = Receiver$1;
|
|
|
1443
1279
|
* @return {(Error|RangeError)} The error
|
|
1444
1280
|
* @private
|
|
1445
1281
|
*/
|
|
1446
|
-
|
|
1447
1282
|
function error(ErrorCtor, message, prefix, statusCode, errorCode) {
|
|
1448
1283
|
const err = new ErrorCtor(prefix ? `Invalid WebSocket frame: ${message}` : message);
|
|
1449
1284
|
Error.captureStackTrace(err, error);
|
|
@@ -1451,9 +1286,8 @@ function error(ErrorCtor, message, prefix, statusCode, errorCode) {
|
|
|
1451
1286
|
err[kStatusCode$1] = statusCode;
|
|
1452
1287
|
return err;
|
|
1453
1288
|
}
|
|
1454
|
-
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls$" }] */
|
|
1455
|
-
|
|
1456
1289
|
|
|
1290
|
+
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls$" }] */
|
|
1457
1291
|
const {
|
|
1458
1292
|
randomFillSync
|
|
1459
1293
|
} = require$$5;
|
|
@@ -1470,10 +1304,10 @@ const {
|
|
|
1470
1304
|
} = bufferUtil$1.exports;
|
|
1471
1305
|
const kByteLength = Symbol('kByteLength');
|
|
1472
1306
|
const maskBuffer = Buffer.alloc(4);
|
|
1307
|
+
|
|
1473
1308
|
/**
|
|
1474
1309
|
* HyBi Sender implementation.
|
|
1475
1310
|
*/
|
|
1476
|
-
|
|
1477
1311
|
class Sender$1 {
|
|
1478
1312
|
/**
|
|
1479
1313
|
* Creates a Sender instance.
|
|
@@ -1485,12 +1319,10 @@ class Sender$1 {
|
|
|
1485
1319
|
*/
|
|
1486
1320
|
constructor(socket, extensions, generateMask) {
|
|
1487
1321
|
this._extensions = extensions || {};
|
|
1488
|
-
|
|
1489
1322
|
if (generateMask) {
|
|
1490
1323
|
this._generateMask = generateMask;
|
|
1491
1324
|
this._maskBuffer = Buffer.alloc(4);
|
|
1492
1325
|
}
|
|
1493
|
-
|
|
1494
1326
|
this._socket = socket;
|
|
1495
1327
|
this._firstFragment = true;
|
|
1496
1328
|
this._compress = false;
|
|
@@ -1498,6 +1330,7 @@ class Sender$1 {
|
|
|
1498
1330
|
this._deflating = false;
|
|
1499
1331
|
this._queue = [];
|
|
1500
1332
|
}
|
|
1333
|
+
|
|
1501
1334
|
/**
|
|
1502
1335
|
* Frames a piece of data according to the HyBi WebSocket protocol.
|
|
1503
1336
|
*
|
|
@@ -1519,29 +1352,22 @@ class Sender$1 {
|
|
|
1519
1352
|
* @return {(Buffer|String)[]} The framed data
|
|
1520
1353
|
* @public
|
|
1521
1354
|
*/
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
1355
|
static frame(data, options) {
|
|
1525
1356
|
let mask;
|
|
1526
1357
|
let merge = false;
|
|
1527
1358
|
let offset = 2;
|
|
1528
1359
|
let skipMasking = false;
|
|
1529
|
-
|
|
1530
1360
|
if (options.mask) {
|
|
1531
1361
|
mask = options.maskBuffer || maskBuffer;
|
|
1532
|
-
|
|
1533
1362
|
if (options.generateMask) {
|
|
1534
1363
|
options.generateMask(mask);
|
|
1535
1364
|
} else {
|
|
1536
1365
|
randomFillSync(mask, 0, 4);
|
|
1537
1366
|
}
|
|
1538
|
-
|
|
1539
1367
|
skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
|
|
1540
1368
|
offset = 6;
|
|
1541
1369
|
}
|
|
1542
|
-
|
|
1543
1370
|
let dataLength;
|
|
1544
|
-
|
|
1545
1371
|
if (typeof data === 'string') {
|
|
1546
1372
|
if ((!options.mask || skipMasking) && options[kByteLength] !== undefined) {
|
|
1547
1373
|
dataLength = options[kByteLength];
|
|
@@ -1553,9 +1379,7 @@ class Sender$1 {
|
|
|
1553
1379
|
dataLength = data.length;
|
|
1554
1380
|
merge = options.mask && options.readOnly && !skipMasking;
|
|
1555
1381
|
}
|
|
1556
|
-
|
|
1557
1382
|
let payloadLength = dataLength;
|
|
1558
|
-
|
|
1559
1383
|
if (dataLength >= 65536) {
|
|
1560
1384
|
offset += 8;
|
|
1561
1385
|
payloadLength = 127;
|
|
@@ -1563,19 +1387,16 @@ class Sender$1 {
|
|
|
1563
1387
|
offset += 2;
|
|
1564
1388
|
payloadLength = 126;
|
|
1565
1389
|
}
|
|
1566
|
-
|
|
1567
1390
|
const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);
|
|
1568
1391
|
target[0] = options.fin ? options.opcode | 0x80 : options.opcode;
|
|
1569
1392
|
if (options.rsv1) target[0] |= 0x40;
|
|
1570
1393
|
target[1] = payloadLength;
|
|
1571
|
-
|
|
1572
1394
|
if (payloadLength === 126) {
|
|
1573
1395
|
target.writeUInt16BE(dataLength, 2);
|
|
1574
1396
|
} else if (payloadLength === 127) {
|
|
1575
1397
|
target[2] = target[3] = 0;
|
|
1576
1398
|
target.writeUIntBE(dataLength, 4, 6);
|
|
1577
1399
|
}
|
|
1578
|
-
|
|
1579
1400
|
if (!options.mask) return [target, data];
|
|
1580
1401
|
target[1] |= 0x80;
|
|
1581
1402
|
target[offset - 4] = mask[0];
|
|
@@ -1583,15 +1404,14 @@ class Sender$1 {
|
|
|
1583
1404
|
target[offset - 2] = mask[2];
|
|
1584
1405
|
target[offset - 1] = mask[3];
|
|
1585
1406
|
if (skipMasking) return [target, data];
|
|
1586
|
-
|
|
1587
1407
|
if (merge) {
|
|
1588
1408
|
applyMask(data, mask, target, offset, dataLength);
|
|
1589
1409
|
return [target];
|
|
1590
1410
|
}
|
|
1591
|
-
|
|
1592
1411
|
applyMask(data, mask, data, 0, dataLength);
|
|
1593
1412
|
return [target, data];
|
|
1594
1413
|
}
|
|
1414
|
+
|
|
1595
1415
|
/**
|
|
1596
1416
|
* Sends a close message to the other peer.
|
|
1597
1417
|
*
|
|
@@ -1601,11 +1421,8 @@ class Sender$1 {
|
|
|
1601
1421
|
* @param {Function} [cb] Callback
|
|
1602
1422
|
* @public
|
|
1603
1423
|
*/
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
1424
|
close(code, data, mask, cb) {
|
|
1607
1425
|
let buf;
|
|
1608
|
-
|
|
1609
1426
|
if (code === undefined) {
|
|
1610
1427
|
buf = EMPTY_BUFFER$1;
|
|
1611
1428
|
} else if (typeof code !== 'number' || !isValidStatusCode(code)) {
|
|
@@ -1615,21 +1432,17 @@ class Sender$1 {
|
|
|
1615
1432
|
buf.writeUInt16BE(code, 0);
|
|
1616
1433
|
} else {
|
|
1617
1434
|
const length = Buffer.byteLength(data);
|
|
1618
|
-
|
|
1619
1435
|
if (length > 123) {
|
|
1620
1436
|
throw new RangeError('The message must not be greater than 123 bytes');
|
|
1621
1437
|
}
|
|
1622
|
-
|
|
1623
1438
|
buf = Buffer.allocUnsafe(2 + length);
|
|
1624
1439
|
buf.writeUInt16BE(code, 0);
|
|
1625
|
-
|
|
1626
1440
|
if (typeof data === 'string') {
|
|
1627
1441
|
buf.write(data, 2);
|
|
1628
1442
|
} else {
|
|
1629
1443
|
buf.set(data, 2);
|
|
1630
1444
|
}
|
|
1631
1445
|
}
|
|
1632
|
-
|
|
1633
1446
|
const options = {
|
|
1634
1447
|
[kByteLength]: buf.length,
|
|
1635
1448
|
fin: true,
|
|
@@ -1640,13 +1453,13 @@ class Sender$1 {
|
|
|
1640
1453
|
readOnly: false,
|
|
1641
1454
|
rsv1: false
|
|
1642
1455
|
};
|
|
1643
|
-
|
|
1644
1456
|
if (this._deflating) {
|
|
1645
1457
|
this.enqueue([this.dispatch, buf, false, options, cb]);
|
|
1646
1458
|
} else {
|
|
1647
1459
|
this.sendFrame(Sender$1.frame(buf, options), cb);
|
|
1648
1460
|
}
|
|
1649
1461
|
}
|
|
1462
|
+
|
|
1650
1463
|
/**
|
|
1651
1464
|
* Sends a ping message to the other peer.
|
|
1652
1465
|
*
|
|
@@ -1655,12 +1468,9 @@ class Sender$1 {
|
|
|
1655
1468
|
* @param {Function} [cb] Callback
|
|
1656
1469
|
* @public
|
|
1657
1470
|
*/
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
1471
|
ping(data, mask, cb) {
|
|
1661
1472
|
let byteLength;
|
|
1662
1473
|
let readOnly;
|
|
1663
|
-
|
|
1664
1474
|
if (typeof data === 'string') {
|
|
1665
1475
|
byteLength = Buffer.byteLength(data);
|
|
1666
1476
|
readOnly = false;
|
|
@@ -1669,11 +1479,9 @@ class Sender$1 {
|
|
|
1669
1479
|
byteLength = data.length;
|
|
1670
1480
|
readOnly = toBuffer$1.readOnly;
|
|
1671
1481
|
}
|
|
1672
|
-
|
|
1673
1482
|
if (byteLength > 125) {
|
|
1674
1483
|
throw new RangeError('The data size must not be greater than 125 bytes');
|
|
1675
1484
|
}
|
|
1676
|
-
|
|
1677
1485
|
const options = {
|
|
1678
1486
|
[kByteLength]: byteLength,
|
|
1679
1487
|
fin: true,
|
|
@@ -1684,13 +1492,13 @@ class Sender$1 {
|
|
|
1684
1492
|
readOnly,
|
|
1685
1493
|
rsv1: false
|
|
1686
1494
|
};
|
|
1687
|
-
|
|
1688
1495
|
if (this._deflating) {
|
|
1689
1496
|
this.enqueue([this.dispatch, data, false, options, cb]);
|
|
1690
1497
|
} else {
|
|
1691
1498
|
this.sendFrame(Sender$1.frame(data, options), cb);
|
|
1692
1499
|
}
|
|
1693
1500
|
}
|
|
1501
|
+
|
|
1694
1502
|
/**
|
|
1695
1503
|
* Sends a pong message to the other peer.
|
|
1696
1504
|
*
|
|
@@ -1699,12 +1507,9 @@ class Sender$1 {
|
|
|
1699
1507
|
* @param {Function} [cb] Callback
|
|
1700
1508
|
* @public
|
|
1701
1509
|
*/
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
1510
|
pong(data, mask, cb) {
|
|
1705
1511
|
let byteLength;
|
|
1706
1512
|
let readOnly;
|
|
1707
|
-
|
|
1708
1513
|
if (typeof data === 'string') {
|
|
1709
1514
|
byteLength = Buffer.byteLength(data);
|
|
1710
1515
|
readOnly = false;
|
|
@@ -1713,11 +1518,9 @@ class Sender$1 {
|
|
|
1713
1518
|
byteLength = data.length;
|
|
1714
1519
|
readOnly = toBuffer$1.readOnly;
|
|
1715
1520
|
}
|
|
1716
|
-
|
|
1717
1521
|
if (byteLength > 125) {
|
|
1718
1522
|
throw new RangeError('The data size must not be greater than 125 bytes');
|
|
1719
1523
|
}
|
|
1720
|
-
|
|
1721
1524
|
const options = {
|
|
1722
1525
|
[kByteLength]: byteLength,
|
|
1723
1526
|
fin: true,
|
|
@@ -1728,13 +1531,13 @@ class Sender$1 {
|
|
|
1728
1531
|
readOnly,
|
|
1729
1532
|
rsv1: false
|
|
1730
1533
|
};
|
|
1731
|
-
|
|
1732
1534
|
if (this._deflating) {
|
|
1733
1535
|
this.enqueue([this.dispatch, data, false, options, cb]);
|
|
1734
1536
|
} else {
|
|
1735
1537
|
this.sendFrame(Sender$1.frame(data, options), cb);
|
|
1736
1538
|
}
|
|
1737
1539
|
}
|
|
1540
|
+
|
|
1738
1541
|
/**
|
|
1739
1542
|
* Sends a data message to the other peer.
|
|
1740
1543
|
*
|
|
@@ -1751,15 +1554,12 @@ class Sender$1 {
|
|
|
1751
1554
|
* @param {Function} [cb] Callback
|
|
1752
1555
|
* @public
|
|
1753
1556
|
*/
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
1557
|
send(data, options, cb) {
|
|
1757
1558
|
const perMessageDeflate = this._extensions[PerMessageDeflate$2.extensionName];
|
|
1758
1559
|
let opcode = options.binary ? 2 : 1;
|
|
1759
1560
|
let rsv1 = options.compress;
|
|
1760
1561
|
let byteLength;
|
|
1761
1562
|
let readOnly;
|
|
1762
|
-
|
|
1763
1563
|
if (typeof data === 'string') {
|
|
1764
1564
|
byteLength = Buffer.byteLength(data);
|
|
1765
1565
|
readOnly = false;
|
|
@@ -1768,22 +1568,17 @@ class Sender$1 {
|
|
|
1768
1568
|
byteLength = data.length;
|
|
1769
1569
|
readOnly = toBuffer$1.readOnly;
|
|
1770
1570
|
}
|
|
1771
|
-
|
|
1772
1571
|
if (this._firstFragment) {
|
|
1773
1572
|
this._firstFragment = false;
|
|
1774
|
-
|
|
1775
1573
|
if (rsv1 && perMessageDeflate && perMessageDeflate.params[perMessageDeflate._isServer ? 'server_no_context_takeover' : 'client_no_context_takeover']) {
|
|
1776
1574
|
rsv1 = byteLength >= perMessageDeflate._threshold;
|
|
1777
1575
|
}
|
|
1778
|
-
|
|
1779
1576
|
this._compress = rsv1;
|
|
1780
1577
|
} else {
|
|
1781
1578
|
rsv1 = false;
|
|
1782
1579
|
opcode = 0;
|
|
1783
1580
|
}
|
|
1784
|
-
|
|
1785
1581
|
if (options.fin) this._firstFragment = true;
|
|
1786
|
-
|
|
1787
1582
|
if (perMessageDeflate) {
|
|
1788
1583
|
const opts = {
|
|
1789
1584
|
[kByteLength]: byteLength,
|
|
@@ -1795,7 +1590,6 @@ class Sender$1 {
|
|
|
1795
1590
|
readOnly,
|
|
1796
1591
|
rsv1
|
|
1797
1592
|
};
|
|
1798
|
-
|
|
1799
1593
|
if (this._deflating) {
|
|
1800
1594
|
this.enqueue([this.dispatch, data, this._compress, opts, cb]);
|
|
1801
1595
|
} else {
|
|
@@ -1814,6 +1608,7 @@ class Sender$1 {
|
|
|
1814
1608
|
}), cb);
|
|
1815
1609
|
}
|
|
1816
1610
|
}
|
|
1611
|
+
|
|
1817
1612
|
/**
|
|
1818
1613
|
* Dispatches a message.
|
|
1819
1614
|
*
|
|
@@ -1837,14 +1632,11 @@ class Sender$1 {
|
|
|
1837
1632
|
* @param {Function} [cb] Callback
|
|
1838
1633
|
* @private
|
|
1839
1634
|
*/
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
1635
|
dispatch(data, compress, options, cb) {
|
|
1843
1636
|
if (!compress) {
|
|
1844
1637
|
this.sendFrame(Sender$1.frame(data, options), cb);
|
|
1845
1638
|
return;
|
|
1846
1639
|
}
|
|
1847
|
-
|
|
1848
1640
|
const perMessageDeflate = this._extensions[PerMessageDeflate$2.extensionName];
|
|
1849
1641
|
this._bufferedBytes += options[kByteLength];
|
|
1850
1642
|
this._deflating = true;
|
|
@@ -1852,16 +1644,13 @@ class Sender$1 {
|
|
|
1852
1644
|
if (this._socket.destroyed) {
|
|
1853
1645
|
const err = new Error('The socket was closed while data was being compressed');
|
|
1854
1646
|
if (typeof cb === 'function') cb(err);
|
|
1855
|
-
|
|
1856
1647
|
for (let i = 0; i < this._queue.length; i++) {
|
|
1857
1648
|
const params = this._queue[i];
|
|
1858
1649
|
const callback = params[params.length - 1];
|
|
1859
1650
|
if (typeof callback === 'function') callback(err);
|
|
1860
1651
|
}
|
|
1861
|
-
|
|
1862
1652
|
return;
|
|
1863
1653
|
}
|
|
1864
|
-
|
|
1865
1654
|
this._bufferedBytes -= options[kByteLength];
|
|
1866
1655
|
this._deflating = false;
|
|
1867
1656
|
options.readOnly = false;
|
|
@@ -1869,34 +1658,31 @@ class Sender$1 {
|
|
|
1869
1658
|
this.dequeue();
|
|
1870
1659
|
});
|
|
1871
1660
|
}
|
|
1661
|
+
|
|
1872
1662
|
/**
|
|
1873
1663
|
* Executes queued send operations.
|
|
1874
1664
|
*
|
|
1875
1665
|
* @private
|
|
1876
1666
|
*/
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
1667
|
dequeue() {
|
|
1880
1668
|
while (!this._deflating && this._queue.length) {
|
|
1881
1669
|
const params = this._queue.shift();
|
|
1882
|
-
|
|
1883
1670
|
this._bufferedBytes -= params[3][kByteLength];
|
|
1884
1671
|
Reflect.apply(params[0], this, params.slice(1));
|
|
1885
1672
|
}
|
|
1886
1673
|
}
|
|
1674
|
+
|
|
1887
1675
|
/**
|
|
1888
1676
|
* Enqueues a send operation.
|
|
1889
1677
|
*
|
|
1890
1678
|
* @param {Array} params Send operation parameters.
|
|
1891
1679
|
* @private
|
|
1892
1680
|
*/
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
1681
|
enqueue(params) {
|
|
1896
1682
|
this._bufferedBytes += params[3][kByteLength];
|
|
1897
|
-
|
|
1898
1683
|
this._queue.push(params);
|
|
1899
1684
|
}
|
|
1685
|
+
|
|
1900
1686
|
/**
|
|
1901
1687
|
* Sends a frame.
|
|
1902
1688
|
*
|
|
@@ -1904,24 +1690,17 @@ class Sender$1 {
|
|
|
1904
1690
|
* @param {Function} [cb] Callback
|
|
1905
1691
|
* @private
|
|
1906
1692
|
*/
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
1693
|
sendFrame(list, cb) {
|
|
1910
1694
|
if (list.length === 2) {
|
|
1911
1695
|
this._socket.cork();
|
|
1912
|
-
|
|
1913
1696
|
this._socket.write(list[0]);
|
|
1914
|
-
|
|
1915
1697
|
this._socket.write(list[1], cb);
|
|
1916
|
-
|
|
1917
1698
|
this._socket.uncork();
|
|
1918
1699
|
} else {
|
|
1919
1700
|
this._socket.write(list[0], cb);
|
|
1920
1701
|
}
|
|
1921
1702
|
}
|
|
1922
|
-
|
|
1923
1703
|
}
|
|
1924
|
-
|
|
1925
1704
|
var sender = Sender$1;
|
|
1926
1705
|
const {
|
|
1927
1706
|
kForOnEventAttribute: kForOnEventAttribute$1,
|
|
@@ -1935,10 +1714,10 @@ const kReason = Symbol('kReason');
|
|
|
1935
1714
|
const kTarget = Symbol('kTarget');
|
|
1936
1715
|
const kType = Symbol('kType');
|
|
1937
1716
|
const kWasClean = Symbol('kWasClean');
|
|
1717
|
+
|
|
1938
1718
|
/**
|
|
1939
1719
|
* Class representing an event.
|
|
1940
1720
|
*/
|
|
1941
|
-
|
|
1942
1721
|
class Event {
|
|
1943
1722
|
/**
|
|
1944
1723
|
* Create a new `Event`.
|
|
@@ -1950,37 +1729,33 @@ class Event {
|
|
|
1950
1729
|
this[kTarget] = null;
|
|
1951
1730
|
this[kType] = type;
|
|
1952
1731
|
}
|
|
1732
|
+
|
|
1953
1733
|
/**
|
|
1954
1734
|
* @type {*}
|
|
1955
1735
|
*/
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
1736
|
get target() {
|
|
1959
1737
|
return this[kTarget];
|
|
1960
1738
|
}
|
|
1739
|
+
|
|
1961
1740
|
/**
|
|
1962
1741
|
* @type {String}
|
|
1963
1742
|
*/
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
1743
|
get type() {
|
|
1967
1744
|
return this[kType];
|
|
1968
1745
|
}
|
|
1969
|
-
|
|
1970
1746
|
}
|
|
1971
|
-
|
|
1972
1747
|
Object.defineProperty(Event.prototype, 'target', {
|
|
1973
1748
|
enumerable: true
|
|
1974
1749
|
});
|
|
1975
1750
|
Object.defineProperty(Event.prototype, 'type', {
|
|
1976
1751
|
enumerable: true
|
|
1977
1752
|
});
|
|
1753
|
+
|
|
1978
1754
|
/**
|
|
1979
1755
|
* Class representing a close event.
|
|
1980
1756
|
*
|
|
1981
1757
|
* @extends Event
|
|
1982
1758
|
*/
|
|
1983
|
-
|
|
1984
1759
|
class CloseEvent extends Event {
|
|
1985
1760
|
/**
|
|
1986
1761
|
* Create a new `CloseEvent`.
|
|
@@ -2001,33 +1776,28 @@ class CloseEvent extends Event {
|
|
|
2001
1776
|
this[kReason] = options.reason === undefined ? '' : options.reason;
|
|
2002
1777
|
this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;
|
|
2003
1778
|
}
|
|
1779
|
+
|
|
2004
1780
|
/**
|
|
2005
1781
|
* @type {Number}
|
|
2006
1782
|
*/
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
1783
|
get code() {
|
|
2010
1784
|
return this[kCode];
|
|
2011
1785
|
}
|
|
1786
|
+
|
|
2012
1787
|
/**
|
|
2013
1788
|
* @type {String}
|
|
2014
1789
|
*/
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
1790
|
get reason() {
|
|
2018
1791
|
return this[kReason];
|
|
2019
1792
|
}
|
|
1793
|
+
|
|
2020
1794
|
/**
|
|
2021
1795
|
* @type {Boolean}
|
|
2022
1796
|
*/
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
1797
|
get wasClean() {
|
|
2026
1798
|
return this[kWasClean];
|
|
2027
1799
|
}
|
|
2028
|
-
|
|
2029
1800
|
}
|
|
2030
|
-
|
|
2031
1801
|
Object.defineProperty(CloseEvent.prototype, 'code', {
|
|
2032
1802
|
enumerable: true
|
|
2033
1803
|
});
|
|
@@ -2037,12 +1807,12 @@ Object.defineProperty(CloseEvent.prototype, 'reason', {
|
|
|
2037
1807
|
Object.defineProperty(CloseEvent.prototype, 'wasClean', {
|
|
2038
1808
|
enumerable: true
|
|
2039
1809
|
});
|
|
1810
|
+
|
|
2040
1811
|
/**
|
|
2041
1812
|
* Class representing an error event.
|
|
2042
1813
|
*
|
|
2043
1814
|
* @extends Event
|
|
2044
1815
|
*/
|
|
2045
|
-
|
|
2046
1816
|
class ErrorEvent extends Event {
|
|
2047
1817
|
/**
|
|
2048
1818
|
* Create a new `ErrorEvent`.
|
|
@@ -2058,37 +1828,33 @@ class ErrorEvent extends Event {
|
|
|
2058
1828
|
this[kError] = options.error === undefined ? null : options.error;
|
|
2059
1829
|
this[kMessage] = options.message === undefined ? '' : options.message;
|
|
2060
1830
|
}
|
|
1831
|
+
|
|
2061
1832
|
/**
|
|
2062
1833
|
* @type {*}
|
|
2063
1834
|
*/
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
1835
|
get error() {
|
|
2067
1836
|
return this[kError];
|
|
2068
1837
|
}
|
|
1838
|
+
|
|
2069
1839
|
/**
|
|
2070
1840
|
* @type {String}
|
|
2071
1841
|
*/
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
1842
|
get message() {
|
|
2075
1843
|
return this[kMessage];
|
|
2076
1844
|
}
|
|
2077
|
-
|
|
2078
1845
|
}
|
|
2079
|
-
|
|
2080
1846
|
Object.defineProperty(ErrorEvent.prototype, 'error', {
|
|
2081
1847
|
enumerable: true
|
|
2082
1848
|
});
|
|
2083
1849
|
Object.defineProperty(ErrorEvent.prototype, 'message', {
|
|
2084
1850
|
enumerable: true
|
|
2085
1851
|
});
|
|
1852
|
+
|
|
2086
1853
|
/**
|
|
2087
1854
|
* Class representing a message event.
|
|
2088
1855
|
*
|
|
2089
1856
|
* @extends Event
|
|
2090
1857
|
*/
|
|
2091
|
-
|
|
2092
1858
|
class MessageEvent extends Event {
|
|
2093
1859
|
/**
|
|
2094
1860
|
* Create a new `MessageEvent`.
|
|
@@ -2102,27 +1868,24 @@ class MessageEvent extends Event {
|
|
|
2102
1868
|
super(type);
|
|
2103
1869
|
this[kData] = options.data === undefined ? null : options.data;
|
|
2104
1870
|
}
|
|
1871
|
+
|
|
2105
1872
|
/**
|
|
2106
1873
|
* @type {*}
|
|
2107
1874
|
*/
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
1875
|
get data() {
|
|
2111
1876
|
return this[kData];
|
|
2112
1877
|
}
|
|
2113
|
-
|
|
2114
1878
|
}
|
|
2115
|
-
|
|
2116
1879
|
Object.defineProperty(MessageEvent.prototype, 'data', {
|
|
2117
1880
|
enumerable: true
|
|
2118
1881
|
});
|
|
1882
|
+
|
|
2119
1883
|
/**
|
|
2120
1884
|
* This provides methods for emulating the `EventTarget` interface. It's not
|
|
2121
1885
|
* meant to be used directly.
|
|
2122
1886
|
*
|
|
2123
1887
|
* @mixin
|
|
2124
1888
|
*/
|
|
2125
|
-
|
|
2126
1889
|
const EventTarget = {
|
|
2127
1890
|
/**
|
|
2128
1891
|
* Register an event listener.
|
|
@@ -2138,7 +1901,6 @@ const EventTarget = {
|
|
|
2138
1901
|
*/
|
|
2139
1902
|
addEventListener(type, listener, options = {}) {
|
|
2140
1903
|
let wrapper;
|
|
2141
|
-
|
|
2142
1904
|
if (type === 'message') {
|
|
2143
1905
|
wrapper = function onMessage(data, isBinary) {
|
|
2144
1906
|
const event = new MessageEvent('message', {
|
|
@@ -2175,17 +1937,14 @@ const EventTarget = {
|
|
|
2175
1937
|
} else {
|
|
2176
1938
|
return;
|
|
2177
1939
|
}
|
|
2178
|
-
|
|
2179
1940
|
wrapper[kForOnEventAttribute$1] = !!options[kForOnEventAttribute$1];
|
|
2180
1941
|
wrapper[kListener$1] = listener;
|
|
2181
|
-
|
|
2182
1942
|
if (options.once) {
|
|
2183
1943
|
this.once(type, wrapper);
|
|
2184
1944
|
} else {
|
|
2185
1945
|
this.on(type, wrapper);
|
|
2186
1946
|
}
|
|
2187
1947
|
},
|
|
2188
|
-
|
|
2189
1948
|
/**
|
|
2190
1949
|
* Remove an event listener.
|
|
2191
1950
|
*
|
|
@@ -2201,7 +1960,6 @@ const EventTarget = {
|
|
|
2201
1960
|
}
|
|
2202
1961
|
}
|
|
2203
1962
|
}
|
|
2204
|
-
|
|
2205
1963
|
};
|
|
2206
1964
|
var eventTarget = {
|
|
2207
1965
|
CloseEvent,
|
|
@@ -2213,6 +1971,7 @@ var eventTarget = {
|
|
|
2213
1971
|
const {
|
|
2214
1972
|
tokenChars: tokenChars$1
|
|
2215
1973
|
} = validation.exports;
|
|
1974
|
+
|
|
2216
1975
|
/**
|
|
2217
1976
|
* Adds an offer to the map of extension offers or a parameter to the map of
|
|
2218
1977
|
* parameters.
|
|
@@ -2223,10 +1982,10 @@ const {
|
|
|
2223
1982
|
* parameter value
|
|
2224
1983
|
* @private
|
|
2225
1984
|
*/
|
|
2226
|
-
|
|
2227
1985
|
function push(dest, name, elem) {
|
|
2228
1986
|
if (dest[name] === undefined) dest[name] = [elem];else dest[name].push(elem);
|
|
2229
1987
|
}
|
|
1988
|
+
|
|
2230
1989
|
/**
|
|
2231
1990
|
* Parses the `Sec-WebSocket-Extensions` header into an object.
|
|
2232
1991
|
*
|
|
@@ -2234,8 +1993,6 @@ function push(dest, name, elem) {
|
|
|
2234
1993
|
* @return {Object} The parsed object
|
|
2235
1994
|
* @public
|
|
2236
1995
|
*/
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
1996
|
function parse$2(header) {
|
|
2240
1997
|
const offers = Object.create(null);
|
|
2241
1998
|
let params = Object.create(null);
|
|
@@ -2248,38 +2005,25 @@ function parse$2(header) {
|
|
|
2248
2005
|
let code = -1;
|
|
2249
2006
|
let end = -1;
|
|
2250
2007
|
let i = 0;
|
|
2251
|
-
|
|
2252
2008
|
for (; i < header.length; i++) {
|
|
2253
2009
|
code = header.charCodeAt(i);
|
|
2254
|
-
|
|
2255
2010
|
if (extensionName === undefined) {
|
|
2256
2011
|
if (end === -1 && tokenChars$1[code] === 1) {
|
|
2257
2012
|
if (start === -1) start = i;
|
|
2258
|
-
} else if (i !== 0 && (code === 0x20
|
|
2259
|
-
/* ' ' */
|
|
2260
|
-
|| code === 0x09)
|
|
2261
|
-
/* '\t' */
|
|
2262
|
-
) {
|
|
2013
|
+
} else if (i !== 0 && (code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */) {
|
|
2263
2014
|
if (end === -1 && start !== -1) end = i;
|
|
2264
|
-
} else if (code === 0x3b
|
|
2265
|
-
/* ';' */
|
|
2266
|
-
|| code === 0x2c
|
|
2267
|
-
/* ',' */
|
|
2268
|
-
) {
|
|
2015
|
+
} else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {
|
|
2269
2016
|
if (start === -1) {
|
|
2270
2017
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
2271
2018
|
}
|
|
2272
|
-
|
|
2273
2019
|
if (end === -1) end = i;
|
|
2274
2020
|
const name = header.slice(start, end);
|
|
2275
|
-
|
|
2276
2021
|
if (code === 0x2c) {
|
|
2277
2022
|
push(offers, name, params);
|
|
2278
2023
|
params = Object.create(null);
|
|
2279
2024
|
} else {
|
|
2280
2025
|
extensionName = name;
|
|
2281
2026
|
}
|
|
2282
|
-
|
|
2283
2027
|
start = end = -1;
|
|
2284
2028
|
} else {
|
|
2285
2029
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
@@ -2293,20 +2037,15 @@ function parse$2(header) {
|
|
|
2293
2037
|
if (start === -1) {
|
|
2294
2038
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
2295
2039
|
}
|
|
2296
|
-
|
|
2297
2040
|
if (end === -1) end = i;
|
|
2298
2041
|
push(params, header.slice(start, end), true);
|
|
2299
|
-
|
|
2300
2042
|
if (code === 0x2c) {
|
|
2301
2043
|
push(offers, extensionName, params);
|
|
2302
2044
|
params = Object.create(null);
|
|
2303
2045
|
extensionName = undefined;
|
|
2304
2046
|
}
|
|
2305
|
-
|
|
2306
2047
|
start = end = -1;
|
|
2307
|
-
} else if (code === 0x3d
|
|
2308
|
-
/* '=' */
|
|
2309
|
-
&& start !== -1 && end === -1) {
|
|
2048
|
+
} else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {
|
|
2310
2049
|
paramName = header.slice(start, i);
|
|
2311
2050
|
start = end = -1;
|
|
2312
2051
|
} else {
|
|
@@ -2322,20 +2061,15 @@ function parse$2(header) {
|
|
|
2322
2061
|
if (tokenChars$1[code] !== 1) {
|
|
2323
2062
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
2324
2063
|
}
|
|
2325
|
-
|
|
2326
2064
|
if (start === -1) start = i;else if (!mustUnescape) mustUnescape = true;
|
|
2327
2065
|
isEscaping = false;
|
|
2328
2066
|
} else if (inQuotes) {
|
|
2329
2067
|
if (tokenChars$1[code] === 1) {
|
|
2330
2068
|
if (start === -1) start = i;
|
|
2331
|
-
} else if (code === 0x22
|
|
2332
|
-
/* '"' */
|
|
2333
|
-
&& start !== -1) {
|
|
2069
|
+
} else if (code === 0x22 /* '"' */ && start !== -1) {
|
|
2334
2070
|
inQuotes = false;
|
|
2335
2071
|
end = i;
|
|
2336
|
-
} else if (code === 0x5c
|
|
2337
|
-
/* '\' */
|
|
2338
|
-
) {
|
|
2072
|
+
} else if (code === 0x5c /* '\' */) {
|
|
2339
2073
|
isEscaping = true;
|
|
2340
2074
|
} else {
|
|
2341
2075
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
@@ -2350,23 +2084,18 @@ function parse$2(header) {
|
|
|
2350
2084
|
if (start === -1) {
|
|
2351
2085
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
2352
2086
|
}
|
|
2353
|
-
|
|
2354
2087
|
if (end === -1) end = i;
|
|
2355
2088
|
let value = header.slice(start, end);
|
|
2356
|
-
|
|
2357
2089
|
if (mustUnescape) {
|
|
2358
2090
|
value = value.replace(/\\/g, '');
|
|
2359
2091
|
mustUnescape = false;
|
|
2360
2092
|
}
|
|
2361
|
-
|
|
2362
2093
|
push(params, paramName, value);
|
|
2363
|
-
|
|
2364
2094
|
if (code === 0x2c) {
|
|
2365
2095
|
push(offers, extensionName, params);
|
|
2366
2096
|
params = Object.create(null);
|
|
2367
2097
|
extensionName = undefined;
|
|
2368
2098
|
}
|
|
2369
|
-
|
|
2370
2099
|
paramName = undefined;
|
|
2371
2100
|
start = end = -1;
|
|
2372
2101
|
} else {
|
|
@@ -2374,14 +2103,11 @@ function parse$2(header) {
|
|
|
2374
2103
|
}
|
|
2375
2104
|
}
|
|
2376
2105
|
}
|
|
2377
|
-
|
|
2378
2106
|
if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {
|
|
2379
2107
|
throw new SyntaxError('Unexpected end of input');
|
|
2380
2108
|
}
|
|
2381
|
-
|
|
2382
2109
|
if (end === -1) end = i;
|
|
2383
2110
|
const token = header.slice(start, end);
|
|
2384
|
-
|
|
2385
2111
|
if (extensionName === undefined) {
|
|
2386
2112
|
push(offers, token, params);
|
|
2387
2113
|
} else {
|
|
@@ -2392,12 +2118,11 @@ function parse$2(header) {
|
|
|
2392
2118
|
} else {
|
|
2393
2119
|
push(params, paramName, token);
|
|
2394
2120
|
}
|
|
2395
|
-
|
|
2396
2121
|
push(offers, extensionName, params);
|
|
2397
2122
|
}
|
|
2398
|
-
|
|
2399
2123
|
return offers;
|
|
2400
2124
|
}
|
|
2125
|
+
|
|
2401
2126
|
/**
|
|
2402
2127
|
* Builds the `Sec-WebSocket-Extensions` header field value.
|
|
2403
2128
|
*
|
|
@@ -2405,8 +2130,6 @@ function parse$2(header) {
|
|
|
2405
2130
|
* @return {String} A string representing the given object
|
|
2406
2131
|
* @public
|
|
2407
2132
|
*/
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
2133
|
function format$1(extensions) {
|
|
2411
2134
|
return Object.keys(extensions).map(extension => {
|
|
2412
2135
|
let configurations = extensions[extension];
|
|
@@ -2420,11 +2143,11 @@ function format$1(extensions) {
|
|
|
2420
2143
|
}).join(', ');
|
|
2421
2144
|
}).join(', ');
|
|
2422
2145
|
}
|
|
2423
|
-
|
|
2424
2146
|
var extension$1 = {
|
|
2425
2147
|
format: format$1,
|
|
2426
2148
|
parse: parse$2
|
|
2427
2149
|
};
|
|
2150
|
+
|
|
2428
2151
|
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Readable$" }] */
|
|
2429
2152
|
|
|
2430
2153
|
const EventEmitter$1 = require$$0$2;
|
|
@@ -2470,12 +2193,12 @@ const kAborted = Symbol('kAborted');
|
|
|
2470
2193
|
const protocolVersions = [8, 13];
|
|
2471
2194
|
const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
|
|
2472
2195
|
const subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
|
|
2196
|
+
|
|
2473
2197
|
/**
|
|
2474
2198
|
* Class representing a WebSocket.
|
|
2475
2199
|
*
|
|
2476
2200
|
* @extends EventEmitter
|
|
2477
2201
|
*/
|
|
2478
|
-
|
|
2479
2202
|
class WebSocket$1 extends EventEmitter$1 {
|
|
2480
2203
|
/**
|
|
2481
2204
|
* Create a new `WebSocket`.
|
|
@@ -2499,12 +2222,10 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2499
2222
|
this._receiver = null;
|
|
2500
2223
|
this._sender = null;
|
|
2501
2224
|
this._socket = null;
|
|
2502
|
-
|
|
2503
2225
|
if (address !== null) {
|
|
2504
2226
|
this._bufferedAmount = 0;
|
|
2505
2227
|
this._isServer = false;
|
|
2506
2228
|
this._redirects = 0;
|
|
2507
|
-
|
|
2508
2229
|
if (protocols === undefined) {
|
|
2509
2230
|
protocols = [];
|
|
2510
2231
|
} else if (!Array.isArray(protocols)) {
|
|
@@ -2515,12 +2236,12 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2515
2236
|
protocols = [protocols];
|
|
2516
2237
|
}
|
|
2517
2238
|
}
|
|
2518
|
-
|
|
2519
2239
|
initAsClient(this, address, protocols, options);
|
|
2520
2240
|
} else {
|
|
2521
2241
|
this._isServer = true;
|
|
2522
2242
|
}
|
|
2523
2243
|
}
|
|
2244
|
+
|
|
2524
2245
|
/**
|
|
2525
2246
|
* This deviates from the WHATWG interface since ws doesn't support the
|
|
2526
2247
|
* required default "blob" type (instead we define a custom "nodebuffer"
|
|
@@ -2528,109 +2249,94 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2528
2249
|
*
|
|
2529
2250
|
* @type {String}
|
|
2530
2251
|
*/
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
2252
|
get binaryType() {
|
|
2534
2253
|
return this._binaryType;
|
|
2535
2254
|
}
|
|
2536
|
-
|
|
2537
2255
|
set binaryType(type) {
|
|
2538
2256
|
if (!BINARY_TYPES.includes(type)) return;
|
|
2539
|
-
this._binaryType = type;
|
|
2257
|
+
this._binaryType = type;
|
|
2258
|
+
|
|
2259
|
+
//
|
|
2540
2260
|
// Allow to change `binaryType` on the fly.
|
|
2541
2261
|
//
|
|
2542
|
-
|
|
2543
2262
|
if (this._receiver) this._receiver._binaryType = type;
|
|
2544
2263
|
}
|
|
2264
|
+
|
|
2545
2265
|
/**
|
|
2546
2266
|
* @type {Number}
|
|
2547
2267
|
*/
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
2268
|
get bufferedAmount() {
|
|
2551
2269
|
if (!this._socket) return this._bufferedAmount;
|
|
2552
2270
|
return this._socket._writableState.length + this._sender._bufferedBytes;
|
|
2553
2271
|
}
|
|
2272
|
+
|
|
2554
2273
|
/**
|
|
2555
2274
|
* @type {String}
|
|
2556
2275
|
*/
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
2276
|
get extensions() {
|
|
2560
2277
|
return Object.keys(this._extensions).join();
|
|
2561
2278
|
}
|
|
2279
|
+
|
|
2562
2280
|
/**
|
|
2563
2281
|
* @type {Boolean}
|
|
2564
2282
|
*/
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
2283
|
get isPaused() {
|
|
2568
2284
|
return this._paused;
|
|
2569
2285
|
}
|
|
2286
|
+
|
|
2570
2287
|
/**
|
|
2571
2288
|
* @type {Function}
|
|
2572
2289
|
*/
|
|
2573
|
-
|
|
2574
2290
|
/* istanbul ignore next */
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
2291
|
get onclose() {
|
|
2578
2292
|
return null;
|
|
2579
2293
|
}
|
|
2294
|
+
|
|
2580
2295
|
/**
|
|
2581
2296
|
* @type {Function}
|
|
2582
2297
|
*/
|
|
2583
|
-
|
|
2584
2298
|
/* istanbul ignore next */
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
2299
|
get onerror() {
|
|
2588
2300
|
return null;
|
|
2589
2301
|
}
|
|
2302
|
+
|
|
2590
2303
|
/**
|
|
2591
2304
|
* @type {Function}
|
|
2592
2305
|
*/
|
|
2593
|
-
|
|
2594
2306
|
/* istanbul ignore next */
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
2307
|
get onopen() {
|
|
2598
2308
|
return null;
|
|
2599
2309
|
}
|
|
2310
|
+
|
|
2600
2311
|
/**
|
|
2601
2312
|
* @type {Function}
|
|
2602
2313
|
*/
|
|
2603
|
-
|
|
2604
2314
|
/* istanbul ignore next */
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
2315
|
get onmessage() {
|
|
2608
2316
|
return null;
|
|
2609
2317
|
}
|
|
2318
|
+
|
|
2610
2319
|
/**
|
|
2611
2320
|
* @type {String}
|
|
2612
2321
|
*/
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
2322
|
get protocol() {
|
|
2616
2323
|
return this._protocol;
|
|
2617
2324
|
}
|
|
2325
|
+
|
|
2618
2326
|
/**
|
|
2619
2327
|
* @type {Number}
|
|
2620
2328
|
*/
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
2329
|
get readyState() {
|
|
2624
2330
|
return this._readyState;
|
|
2625
2331
|
}
|
|
2332
|
+
|
|
2626
2333
|
/**
|
|
2627
2334
|
* @type {String}
|
|
2628
2335
|
*/
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
2336
|
get url() {
|
|
2632
2337
|
return this._url;
|
|
2633
2338
|
}
|
|
2339
|
+
|
|
2634
2340
|
/**
|
|
2635
2341
|
* Set up the socket and the internal resources.
|
|
2636
2342
|
*
|
|
@@ -2645,8 +2351,6 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2645
2351
|
* not to skip UTF-8 validation for text and close messages
|
|
2646
2352
|
* @private
|
|
2647
2353
|
*/
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
2354
|
setSocket(socket, head, options) {
|
|
2651
2355
|
const receiver = new Receiver({
|
|
2652
2356
|
binaryType: this.binaryType,
|
|
@@ -2676,29 +2380,26 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2676
2380
|
this._readyState = WebSocket$1.OPEN;
|
|
2677
2381
|
this.emit('open');
|
|
2678
2382
|
}
|
|
2383
|
+
|
|
2679
2384
|
/**
|
|
2680
2385
|
* Emit the `'close'` event.
|
|
2681
2386
|
*
|
|
2682
2387
|
* @private
|
|
2683
2388
|
*/
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
2389
|
emitClose() {
|
|
2687
2390
|
if (!this._socket) {
|
|
2688
2391
|
this._readyState = WebSocket$1.CLOSED;
|
|
2689
2392
|
this.emit('close', this._closeCode, this._closeMessage);
|
|
2690
2393
|
return;
|
|
2691
2394
|
}
|
|
2692
|
-
|
|
2693
2395
|
if (this._extensions[PerMessageDeflate$1.extensionName]) {
|
|
2694
2396
|
this._extensions[PerMessageDeflate$1.extensionName].cleanup();
|
|
2695
2397
|
}
|
|
2696
|
-
|
|
2697
2398
|
this._receiver.removeAllListeners();
|
|
2698
|
-
|
|
2699
2399
|
this._readyState = WebSocket$1.CLOSED;
|
|
2700
2400
|
this.emit('close', this._closeCode, this._closeMessage);
|
|
2701
2401
|
}
|
|
2402
|
+
|
|
2702
2403
|
/**
|
|
2703
2404
|
* Start a closing handshake.
|
|
2704
2405
|
*
|
|
@@ -2719,26 +2420,19 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2719
2420
|
* closing
|
|
2720
2421
|
* @public
|
|
2721
2422
|
*/
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
2423
|
close(code, data) {
|
|
2725
2424
|
if (this.readyState === WebSocket$1.CLOSED) return;
|
|
2726
|
-
|
|
2727
2425
|
if (this.readyState === WebSocket$1.CONNECTING) {
|
|
2728
2426
|
const msg = 'WebSocket was closed before the connection was established';
|
|
2729
2427
|
return abortHandshake$1(this, this._req, msg);
|
|
2730
2428
|
}
|
|
2731
|
-
|
|
2732
2429
|
if (this.readyState === WebSocket$1.CLOSING) {
|
|
2733
2430
|
if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) {
|
|
2734
2431
|
this._socket.end();
|
|
2735
2432
|
}
|
|
2736
|
-
|
|
2737
2433
|
return;
|
|
2738
2434
|
}
|
|
2739
|
-
|
|
2740
2435
|
this._readyState = WebSocket$1.CLOSING;
|
|
2741
|
-
|
|
2742
2436
|
this._sender.close(code, data, !this._isServer, err => {
|
|
2743
2437
|
//
|
|
2744
2438
|
// This error is handled by the `'error'` listener on the socket. We only
|
|
@@ -2746,33 +2440,30 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2746
2440
|
//
|
|
2747
2441
|
if (err) return;
|
|
2748
2442
|
this._closeFrameSent = true;
|
|
2749
|
-
|
|
2750
2443
|
if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) {
|
|
2751
2444
|
this._socket.end();
|
|
2752
2445
|
}
|
|
2753
|
-
});
|
|
2446
|
+
});
|
|
2447
|
+
|
|
2448
|
+
//
|
|
2754
2449
|
// Specify a timeout for the closing handshake to complete.
|
|
2755
2450
|
//
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
2451
|
this._closeTimer = setTimeout(this._socket.destroy.bind(this._socket), closeTimeout);
|
|
2759
2452
|
}
|
|
2453
|
+
|
|
2760
2454
|
/**
|
|
2761
2455
|
* Pause the socket.
|
|
2762
2456
|
*
|
|
2763
2457
|
* @public
|
|
2764
2458
|
*/
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
2459
|
pause() {
|
|
2768
2460
|
if (this.readyState === WebSocket$1.CONNECTING || this.readyState === WebSocket$1.CLOSED) {
|
|
2769
2461
|
return;
|
|
2770
2462
|
}
|
|
2771
|
-
|
|
2772
2463
|
this._paused = true;
|
|
2773
|
-
|
|
2774
2464
|
this._socket.pause();
|
|
2775
2465
|
}
|
|
2466
|
+
|
|
2776
2467
|
/**
|
|
2777
2468
|
* Send a ping.
|
|
2778
2469
|
*
|
|
@@ -2781,13 +2472,10 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2781
2472
|
* @param {Function} [cb] Callback which is executed when the ping is sent
|
|
2782
2473
|
* @public
|
|
2783
2474
|
*/
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
2475
|
ping(data, mask, cb) {
|
|
2787
2476
|
if (this.readyState === WebSocket$1.CONNECTING) {
|
|
2788
2477
|
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
|
|
2789
2478
|
}
|
|
2790
|
-
|
|
2791
2479
|
if (typeof data === 'function') {
|
|
2792
2480
|
cb = data;
|
|
2793
2481
|
data = mask = undefined;
|
|
@@ -2795,18 +2483,15 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2795
2483
|
cb = mask;
|
|
2796
2484
|
mask = undefined;
|
|
2797
2485
|
}
|
|
2798
|
-
|
|
2799
2486
|
if (typeof data === 'number') data = data.toString();
|
|
2800
|
-
|
|
2801
2487
|
if (this.readyState !== WebSocket$1.OPEN) {
|
|
2802
2488
|
sendAfterClose(this, data, cb);
|
|
2803
2489
|
return;
|
|
2804
2490
|
}
|
|
2805
|
-
|
|
2806
2491
|
if (mask === undefined) mask = !this._isServer;
|
|
2807
|
-
|
|
2808
2492
|
this._sender.ping(data || EMPTY_BUFFER, mask, cb);
|
|
2809
2493
|
}
|
|
2494
|
+
|
|
2810
2495
|
/**
|
|
2811
2496
|
* Send a pong.
|
|
2812
2497
|
*
|
|
@@ -2815,13 +2500,10 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2815
2500
|
* @param {Function} [cb] Callback which is executed when the pong is sent
|
|
2816
2501
|
* @public
|
|
2817
2502
|
*/
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
2503
|
pong(data, mask, cb) {
|
|
2821
2504
|
if (this.readyState === WebSocket$1.CONNECTING) {
|
|
2822
2505
|
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
|
|
2823
2506
|
}
|
|
2824
|
-
|
|
2825
2507
|
if (typeof data === 'function') {
|
|
2826
2508
|
cb = data;
|
|
2827
2509
|
data = mask = undefined;
|
|
@@ -2829,33 +2511,28 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2829
2511
|
cb = mask;
|
|
2830
2512
|
mask = undefined;
|
|
2831
2513
|
}
|
|
2832
|
-
|
|
2833
2514
|
if (typeof data === 'number') data = data.toString();
|
|
2834
|
-
|
|
2835
2515
|
if (this.readyState !== WebSocket$1.OPEN) {
|
|
2836
2516
|
sendAfterClose(this, data, cb);
|
|
2837
2517
|
return;
|
|
2838
2518
|
}
|
|
2839
|
-
|
|
2840
2519
|
if (mask === undefined) mask = !this._isServer;
|
|
2841
|
-
|
|
2842
2520
|
this._sender.pong(data || EMPTY_BUFFER, mask, cb);
|
|
2843
2521
|
}
|
|
2522
|
+
|
|
2844
2523
|
/**
|
|
2845
2524
|
* Resume the socket.
|
|
2846
2525
|
*
|
|
2847
2526
|
* @public
|
|
2848
2527
|
*/
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
2528
|
resume() {
|
|
2852
2529
|
if (this.readyState === WebSocket$1.CONNECTING || this.readyState === WebSocket$1.CLOSED) {
|
|
2853
2530
|
return;
|
|
2854
2531
|
}
|
|
2855
|
-
|
|
2856
2532
|
this._paused = false;
|
|
2857
2533
|
if (!this._receiver._writableState.needDrain) this._socket.resume();
|
|
2858
2534
|
}
|
|
2535
|
+
|
|
2859
2536
|
/**
|
|
2860
2537
|
* Send a data message.
|
|
2861
2538
|
*
|
|
@@ -2871,25 +2548,19 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2871
2548
|
* @param {Function} [cb] Callback which is executed when data is written out
|
|
2872
2549
|
* @public
|
|
2873
2550
|
*/
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
2551
|
send(data, options, cb) {
|
|
2877
2552
|
if (this.readyState === WebSocket$1.CONNECTING) {
|
|
2878
2553
|
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
|
|
2879
2554
|
}
|
|
2880
|
-
|
|
2881
2555
|
if (typeof options === 'function') {
|
|
2882
2556
|
cb = options;
|
|
2883
2557
|
options = {};
|
|
2884
2558
|
}
|
|
2885
|
-
|
|
2886
2559
|
if (typeof data === 'number') data = data.toString();
|
|
2887
|
-
|
|
2888
2560
|
if (this.readyState !== WebSocket$1.OPEN) {
|
|
2889
2561
|
sendAfterClose(this, data, cb);
|
|
2890
2562
|
return;
|
|
2891
2563
|
}
|
|
2892
|
-
|
|
2893
2564
|
const opts = {
|
|
2894
2565
|
binary: typeof data !== 'string',
|
|
2895
2566
|
mask: !this._isServer,
|
|
@@ -2897,105 +2568,97 @@ class WebSocket$1 extends EventEmitter$1 {
|
|
|
2897
2568
|
fin: true,
|
|
2898
2569
|
...options
|
|
2899
2570
|
};
|
|
2900
|
-
|
|
2901
2571
|
if (!this._extensions[PerMessageDeflate$1.extensionName]) {
|
|
2902
2572
|
opts.compress = false;
|
|
2903
2573
|
}
|
|
2904
|
-
|
|
2905
2574
|
this._sender.send(data || EMPTY_BUFFER, opts, cb);
|
|
2906
2575
|
}
|
|
2576
|
+
|
|
2907
2577
|
/**
|
|
2908
2578
|
* Forcibly close the connection.
|
|
2909
2579
|
*
|
|
2910
2580
|
* @public
|
|
2911
2581
|
*/
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
2582
|
terminate() {
|
|
2915
2583
|
if (this.readyState === WebSocket$1.CLOSED) return;
|
|
2916
|
-
|
|
2917
2584
|
if (this.readyState === WebSocket$1.CONNECTING) {
|
|
2918
2585
|
const msg = 'WebSocket was closed before the connection was established';
|
|
2919
2586
|
return abortHandshake$1(this, this._req, msg);
|
|
2920
2587
|
}
|
|
2921
|
-
|
|
2922
2588
|
if (this._socket) {
|
|
2923
2589
|
this._readyState = WebSocket$1.CLOSING;
|
|
2924
|
-
|
|
2925
2590
|
this._socket.destroy();
|
|
2926
2591
|
}
|
|
2927
2592
|
}
|
|
2928
|
-
|
|
2929
2593
|
}
|
|
2594
|
+
|
|
2930
2595
|
/**
|
|
2931
2596
|
* @constant {Number} CONNECTING
|
|
2932
2597
|
* @memberof WebSocket
|
|
2933
|
-
*/
|
|
2934
|
-
|
|
2935
|
-
|
|
2598
|
+
*/
|
|
2936
2599
|
Object.defineProperty(WebSocket$1, 'CONNECTING', {
|
|
2937
2600
|
enumerable: true,
|
|
2938
2601
|
value: readyStates.indexOf('CONNECTING')
|
|
2939
2602
|
});
|
|
2603
|
+
|
|
2940
2604
|
/**
|
|
2941
2605
|
* @constant {Number} CONNECTING
|
|
2942
2606
|
* @memberof WebSocket.prototype
|
|
2943
2607
|
*/
|
|
2944
|
-
|
|
2945
2608
|
Object.defineProperty(WebSocket$1.prototype, 'CONNECTING', {
|
|
2946
2609
|
enumerable: true,
|
|
2947
2610
|
value: readyStates.indexOf('CONNECTING')
|
|
2948
2611
|
});
|
|
2612
|
+
|
|
2949
2613
|
/**
|
|
2950
2614
|
* @constant {Number} OPEN
|
|
2951
2615
|
* @memberof WebSocket
|
|
2952
2616
|
*/
|
|
2953
|
-
|
|
2954
2617
|
Object.defineProperty(WebSocket$1, 'OPEN', {
|
|
2955
2618
|
enumerable: true,
|
|
2956
2619
|
value: readyStates.indexOf('OPEN')
|
|
2957
2620
|
});
|
|
2621
|
+
|
|
2958
2622
|
/**
|
|
2959
2623
|
* @constant {Number} OPEN
|
|
2960
2624
|
* @memberof WebSocket.prototype
|
|
2961
2625
|
*/
|
|
2962
|
-
|
|
2963
2626
|
Object.defineProperty(WebSocket$1.prototype, 'OPEN', {
|
|
2964
2627
|
enumerable: true,
|
|
2965
2628
|
value: readyStates.indexOf('OPEN')
|
|
2966
2629
|
});
|
|
2630
|
+
|
|
2967
2631
|
/**
|
|
2968
2632
|
* @constant {Number} CLOSING
|
|
2969
2633
|
* @memberof WebSocket
|
|
2970
2634
|
*/
|
|
2971
|
-
|
|
2972
2635
|
Object.defineProperty(WebSocket$1, 'CLOSING', {
|
|
2973
2636
|
enumerable: true,
|
|
2974
2637
|
value: readyStates.indexOf('CLOSING')
|
|
2975
2638
|
});
|
|
2639
|
+
|
|
2976
2640
|
/**
|
|
2977
2641
|
* @constant {Number} CLOSING
|
|
2978
2642
|
* @memberof WebSocket.prototype
|
|
2979
2643
|
*/
|
|
2980
|
-
|
|
2981
2644
|
Object.defineProperty(WebSocket$1.prototype, 'CLOSING', {
|
|
2982
2645
|
enumerable: true,
|
|
2983
2646
|
value: readyStates.indexOf('CLOSING')
|
|
2984
2647
|
});
|
|
2648
|
+
|
|
2985
2649
|
/**
|
|
2986
2650
|
* @constant {Number} CLOSED
|
|
2987
2651
|
* @memberof WebSocket
|
|
2988
2652
|
*/
|
|
2989
|
-
|
|
2990
2653
|
Object.defineProperty(WebSocket$1, 'CLOSED', {
|
|
2991
2654
|
enumerable: true,
|
|
2992
2655
|
value: readyStates.indexOf('CLOSED')
|
|
2993
2656
|
});
|
|
2657
|
+
|
|
2994
2658
|
/**
|
|
2995
2659
|
* @constant {Number} CLOSED
|
|
2996
2660
|
* @memberof WebSocket.prototype
|
|
2997
2661
|
*/
|
|
2998
|
-
|
|
2999
2662
|
Object.defineProperty(WebSocket$1.prototype, 'CLOSED', {
|
|
3000
2663
|
enumerable: true,
|
|
3001
2664
|
value: readyStates.indexOf('CLOSED')
|
|
@@ -3004,23 +2667,21 @@ Object.defineProperty(WebSocket$1.prototype, 'CLOSED', {
|
|
|
3004
2667
|
Object.defineProperty(WebSocket$1.prototype, property, {
|
|
3005
2668
|
enumerable: true
|
|
3006
2669
|
});
|
|
3007
|
-
});
|
|
2670
|
+
});
|
|
2671
|
+
|
|
2672
|
+
//
|
|
3008
2673
|
// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.
|
|
3009
2674
|
// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface
|
|
3010
2675
|
//
|
|
3011
|
-
|
|
3012
2676
|
['open', 'error', 'close', 'message'].forEach(method => {
|
|
3013
2677
|
Object.defineProperty(WebSocket$1.prototype, `on${method}`, {
|
|
3014
2678
|
enumerable: true,
|
|
3015
|
-
|
|
3016
2679
|
get() {
|
|
3017
2680
|
for (const listener of this.listeners(method)) {
|
|
3018
2681
|
if (listener[kForOnEventAttribute]) return listener[kListener];
|
|
3019
2682
|
}
|
|
3020
|
-
|
|
3021
2683
|
return null;
|
|
3022
2684
|
},
|
|
3023
|
-
|
|
3024
2685
|
set(handler) {
|
|
3025
2686
|
for (const listener of this.listeners(method)) {
|
|
3026
2687
|
if (listener[kForOnEventAttribute]) {
|
|
@@ -3028,18 +2689,17 @@ Object.defineProperty(WebSocket$1.prototype, 'CLOSED', {
|
|
|
3028
2689
|
break;
|
|
3029
2690
|
}
|
|
3030
2691
|
}
|
|
3031
|
-
|
|
3032
2692
|
if (typeof handler !== 'function') return;
|
|
3033
2693
|
this.addEventListener(method, handler, {
|
|
3034
2694
|
[kForOnEventAttribute]: true
|
|
3035
2695
|
});
|
|
3036
2696
|
}
|
|
3037
|
-
|
|
3038
2697
|
});
|
|
3039
2698
|
});
|
|
3040
2699
|
WebSocket$1.prototype.addEventListener = addEventListener;
|
|
3041
2700
|
WebSocket$1.prototype.removeEventListener = removeEventListener;
|
|
3042
2701
|
var websocket = WebSocket$1;
|
|
2702
|
+
|
|
3043
2703
|
/**
|
|
3044
2704
|
* Initialize a WebSocket client.
|
|
3045
2705
|
*
|
|
@@ -3067,7 +2727,6 @@ var websocket = WebSocket$1;
|
|
|
3067
2727
|
* not to skip UTF-8 validation for text and close messages
|
|
3068
2728
|
* @private
|
|
3069
2729
|
*/
|
|
3070
|
-
|
|
3071
2730
|
function initAsClient(websocket, address, protocols, options) {
|
|
3072
2731
|
const opts = {
|
|
3073
2732
|
protocolVersion: protocolVersions[1],
|
|
@@ -3087,13 +2746,10 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3087
2746
|
path: undefined,
|
|
3088
2747
|
port: undefined
|
|
3089
2748
|
};
|
|
3090
|
-
|
|
3091
2749
|
if (!protocolVersions.includes(opts.protocolVersion)) {
|
|
3092
2750
|
throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} ` + `(supported versions: ${protocolVersions.join(', ')})`);
|
|
3093
2751
|
}
|
|
3094
|
-
|
|
3095
2752
|
let parsedUrl;
|
|
3096
|
-
|
|
3097
2753
|
if (address instanceof URL) {
|
|
3098
2754
|
parsedUrl = address;
|
|
3099
2755
|
websocket._url = address.href;
|
|
@@ -3103,14 +2759,11 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3103
2759
|
} catch (e) {
|
|
3104
2760
|
throw new SyntaxError(`Invalid URL: ${address}`);
|
|
3105
2761
|
}
|
|
3106
|
-
|
|
3107
2762
|
websocket._url = address;
|
|
3108
2763
|
}
|
|
3109
|
-
|
|
3110
2764
|
const isSecure = parsedUrl.protocol === 'wss:';
|
|
3111
2765
|
const isUnixSocket = parsedUrl.protocol === 'ws+unix:';
|
|
3112
2766
|
let invalidURLMessage;
|
|
3113
|
-
|
|
3114
2767
|
if (parsedUrl.protocol !== 'ws:' && !isSecure && !isUnixSocket) {
|
|
3115
2768
|
invalidURLMessage = 'The URL\'s protocol must be one of "ws:", "wss:", or "ws+unix:"';
|
|
3116
2769
|
} else if (isUnixSocket && !parsedUrl.pathname) {
|
|
@@ -3118,10 +2771,8 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3118
2771
|
} else if (parsedUrl.hash) {
|
|
3119
2772
|
invalidURLMessage = 'The URL contains a fragment identifier';
|
|
3120
2773
|
}
|
|
3121
|
-
|
|
3122
2774
|
if (invalidURLMessage) {
|
|
3123
2775
|
const err = new SyntaxError(invalidURLMessage);
|
|
3124
|
-
|
|
3125
2776
|
if (websocket._redirects === 0) {
|
|
3126
2777
|
throw err;
|
|
3127
2778
|
} else {
|
|
@@ -3129,7 +2780,6 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3129
2780
|
return;
|
|
3130
2781
|
}
|
|
3131
2782
|
}
|
|
3132
|
-
|
|
3133
2783
|
const defaultPort = isSecure ? 443 : 80;
|
|
3134
2784
|
const key = randomBytes(16).toString('base64');
|
|
3135
2785
|
const request = isSecure ? https.request : http$1.request;
|
|
@@ -3139,7 +2789,8 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3139
2789
|
opts.defaultPort = opts.defaultPort || defaultPort;
|
|
3140
2790
|
opts.port = parsedUrl.port || defaultPort;
|
|
3141
2791
|
opts.host = parsedUrl.hostname.startsWith('[') ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname;
|
|
3142
|
-
opts.headers = {
|
|
2792
|
+
opts.headers = {
|
|
2793
|
+
...opts.headers,
|
|
3143
2794
|
'Sec-WebSocket-Version': opts.protocolVersion,
|
|
3144
2795
|
'Sec-WebSocket-Key': key,
|
|
3145
2796
|
Connection: 'Upgrade',
|
|
@@ -3147,26 +2798,21 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3147
2798
|
};
|
|
3148
2799
|
opts.path = parsedUrl.pathname + parsedUrl.search;
|
|
3149
2800
|
opts.timeout = opts.handshakeTimeout;
|
|
3150
|
-
|
|
3151
2801
|
if (opts.perMessageDeflate) {
|
|
3152
2802
|
perMessageDeflate = new PerMessageDeflate$1(opts.perMessageDeflate !== true ? opts.perMessageDeflate : {}, false, opts.maxPayload);
|
|
3153
2803
|
opts.headers['Sec-WebSocket-Extensions'] = format({
|
|
3154
2804
|
[PerMessageDeflate$1.extensionName]: perMessageDeflate.offer()
|
|
3155
2805
|
});
|
|
3156
2806
|
}
|
|
3157
|
-
|
|
3158
2807
|
if (protocols.length) {
|
|
3159
2808
|
for (const protocol of protocols) {
|
|
3160
2809
|
if (typeof protocol !== 'string' || !subprotocolRegex.test(protocol) || protocolSet.has(protocol)) {
|
|
3161
2810
|
throw new SyntaxError('An invalid or duplicated subprotocol was specified');
|
|
3162
2811
|
}
|
|
3163
|
-
|
|
3164
2812
|
protocolSet.add(protocol);
|
|
3165
2813
|
}
|
|
3166
|
-
|
|
3167
2814
|
opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');
|
|
3168
2815
|
}
|
|
3169
|
-
|
|
3170
2816
|
if (opts.origin) {
|
|
3171
2817
|
if (opts.protocolVersion < 13) {
|
|
3172
2818
|
opts.headers['Sec-WebSocket-Origin'] = opts.origin;
|
|
@@ -3174,33 +2820,30 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3174
2820
|
opts.headers.Origin = opts.origin;
|
|
3175
2821
|
}
|
|
3176
2822
|
}
|
|
3177
|
-
|
|
3178
2823
|
if (parsedUrl.username || parsedUrl.password) {
|
|
3179
2824
|
opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
|
|
3180
2825
|
}
|
|
3181
|
-
|
|
3182
2826
|
if (isUnixSocket) {
|
|
3183
2827
|
const parts = opts.path.split(':');
|
|
3184
2828
|
opts.socketPath = parts[0];
|
|
3185
2829
|
opts.path = parts[1];
|
|
3186
2830
|
}
|
|
3187
|
-
|
|
3188
2831
|
let req;
|
|
3189
|
-
|
|
3190
2832
|
if (opts.followRedirects) {
|
|
3191
2833
|
if (websocket._redirects === 0) {
|
|
3192
2834
|
websocket._originalUnixSocket = isUnixSocket;
|
|
3193
2835
|
websocket._originalSecure = isSecure;
|
|
3194
2836
|
websocket._originalHostOrSocketPath = isUnixSocket ? opts.socketPath : parsedUrl.host;
|
|
3195
|
-
const headers = options && options.headers;
|
|
2837
|
+
const headers = options && options.headers;
|
|
2838
|
+
|
|
2839
|
+
//
|
|
3196
2840
|
// Shallow copy the user provided options so that headers can be changed
|
|
3197
2841
|
// without mutating the original object.
|
|
3198
2842
|
//
|
|
3199
|
-
|
|
3200
|
-
|
|
2843
|
+
options = {
|
|
2844
|
+
...options,
|
|
3201
2845
|
headers: {}
|
|
3202
2846
|
};
|
|
3203
|
-
|
|
3204
2847
|
if (headers) {
|
|
3205
2848
|
for (const [key, value] of Object.entries(headers)) {
|
|
3206
2849
|
options.headers[key.toLowerCase()] = value;
|
|
@@ -3208,7 +2851,6 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3208
2851
|
}
|
|
3209
2852
|
} else if (websocket.listenerCount('redirect') === 0) {
|
|
3210
2853
|
const isSameHost = isUnixSocket ? websocket._originalUnixSocket ? opts.socketPath === websocket._originalHostOrSocketPath : false : websocket._originalUnixSocket ? false : parsedUrl.host === websocket._originalHostOrSocketPath;
|
|
3211
|
-
|
|
3212
2854
|
if (!isSameHost || websocket._originalSecure && !isSecure) {
|
|
3213
2855
|
//
|
|
3214
2856
|
// Match curl 7.77.0 behavior and drop the following headers. These
|
|
@@ -3219,19 +2861,17 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3219
2861
|
if (!isSameHost) delete opts.headers.host;
|
|
3220
2862
|
opts.auth = undefined;
|
|
3221
2863
|
}
|
|
3222
|
-
}
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
//
|
|
3223
2867
|
// Match curl 7.77.0 behavior and make the first `Authorization` header win.
|
|
3224
2868
|
// If the `Authorization` header is set, then there is nothing to do as it
|
|
3225
2869
|
// will take precedence.
|
|
3226
2870
|
//
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
2871
|
if (opts.auth && !options.headers.authorization) {
|
|
3230
2872
|
options.headers.authorization = 'Basic ' + Buffer.from(opts.auth).toString('base64');
|
|
3231
2873
|
}
|
|
3232
|
-
|
|
3233
2874
|
req = websocket._req = request(opts);
|
|
3234
|
-
|
|
3235
2875
|
if (websocket._redirects) {
|
|
3236
2876
|
//
|
|
3237
2877
|
// Unlike what is done for the `'upgrade'` event, no early exit is
|
|
@@ -3247,13 +2887,11 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3247
2887
|
} else {
|
|
3248
2888
|
req = websocket._req = request(opts);
|
|
3249
2889
|
}
|
|
3250
|
-
|
|
3251
2890
|
if (opts.timeout) {
|
|
3252
2891
|
req.on('timeout', () => {
|
|
3253
2892
|
abortHandshake$1(websocket, req, 'Opening handshake has timed out');
|
|
3254
2893
|
});
|
|
3255
2894
|
}
|
|
3256
|
-
|
|
3257
2895
|
req.on('error', err => {
|
|
3258
2896
|
if (req === null || req[kAborted]) return;
|
|
3259
2897
|
req = websocket._req = null;
|
|
@@ -3262,16 +2900,13 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3262
2900
|
req.on('response', res => {
|
|
3263
2901
|
const location = res.headers.location;
|
|
3264
2902
|
const statusCode = res.statusCode;
|
|
3265
|
-
|
|
3266
2903
|
if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) {
|
|
3267
2904
|
if (++websocket._redirects > opts.maxRedirects) {
|
|
3268
2905
|
abortHandshake$1(websocket, req, 'Maximum redirects exceeded');
|
|
3269
2906
|
return;
|
|
3270
2907
|
}
|
|
3271
|
-
|
|
3272
2908
|
req.abort();
|
|
3273
2909
|
let addr;
|
|
3274
|
-
|
|
3275
2910
|
try {
|
|
3276
2911
|
addr = new URL(location, address);
|
|
3277
2912
|
} catch (e) {
|
|
@@ -3279,36 +2914,31 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3279
2914
|
emitErrorAndClose(websocket, err);
|
|
3280
2915
|
return;
|
|
3281
2916
|
}
|
|
3282
|
-
|
|
3283
2917
|
initAsClient(websocket, addr, protocols, options);
|
|
3284
2918
|
} else if (!websocket.emit('unexpected-response', req, res)) {
|
|
3285
2919
|
abortHandshake$1(websocket, req, `Unexpected server response: ${res.statusCode}`);
|
|
3286
2920
|
}
|
|
3287
2921
|
});
|
|
3288
2922
|
req.on('upgrade', (res, socket, head) => {
|
|
3289
|
-
websocket.emit('upgrade', res);
|
|
2923
|
+
websocket.emit('upgrade', res);
|
|
2924
|
+
|
|
2925
|
+
//
|
|
3290
2926
|
// The user may have closed the connection from a listener of the
|
|
3291
2927
|
// `'upgrade'` event.
|
|
3292
2928
|
//
|
|
3293
|
-
|
|
3294
2929
|
if (websocket.readyState !== WebSocket$1.CONNECTING) return;
|
|
3295
2930
|
req = websocket._req = null;
|
|
3296
|
-
|
|
3297
2931
|
if (res.headers.upgrade.toLowerCase() !== 'websocket') {
|
|
3298
2932
|
abortHandshake$1(websocket, socket, 'Invalid Upgrade header');
|
|
3299
2933
|
return;
|
|
3300
2934
|
}
|
|
3301
|
-
|
|
3302
2935
|
const digest = createHash$1('sha1').update(key + GUID$1).digest('base64');
|
|
3303
|
-
|
|
3304
2936
|
if (res.headers['sec-websocket-accept'] !== digest) {
|
|
3305
2937
|
abortHandshake$1(websocket, socket, 'Invalid Sec-WebSocket-Accept header');
|
|
3306
2938
|
return;
|
|
3307
2939
|
}
|
|
3308
|
-
|
|
3309
2940
|
const serverProt = res.headers['sec-websocket-protocol'];
|
|
3310
2941
|
let protError;
|
|
3311
|
-
|
|
3312
2942
|
if (serverProt !== undefined) {
|
|
3313
2943
|
if (!protocolSet.size) {
|
|
3314
2944
|
protError = 'Server sent a subprotocol but none was requested';
|
|
@@ -3318,24 +2948,19 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3318
2948
|
} else if (protocolSet.size) {
|
|
3319
2949
|
protError = 'Server sent no subprotocol';
|
|
3320
2950
|
}
|
|
3321
|
-
|
|
3322
2951
|
if (protError) {
|
|
3323
2952
|
abortHandshake$1(websocket, socket, protError);
|
|
3324
2953
|
return;
|
|
3325
2954
|
}
|
|
3326
|
-
|
|
3327
2955
|
if (serverProt) websocket._protocol = serverProt;
|
|
3328
2956
|
const secWebSocketExtensions = res.headers['sec-websocket-extensions'];
|
|
3329
|
-
|
|
3330
2957
|
if (secWebSocketExtensions !== undefined) {
|
|
3331
2958
|
if (!perMessageDeflate) {
|
|
3332
2959
|
const message = 'Server sent a Sec-WebSocket-Extensions header but no extension ' + 'was requested';
|
|
3333
2960
|
abortHandshake$1(websocket, socket, message);
|
|
3334
2961
|
return;
|
|
3335
2962
|
}
|
|
3336
|
-
|
|
3337
2963
|
let extensions;
|
|
3338
|
-
|
|
3339
2964
|
try {
|
|
3340
2965
|
extensions = parse$1(secWebSocketExtensions);
|
|
3341
2966
|
} catch (err) {
|
|
@@ -3343,15 +2968,12 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3343
2968
|
abortHandshake$1(websocket, socket, message);
|
|
3344
2969
|
return;
|
|
3345
2970
|
}
|
|
3346
|
-
|
|
3347
2971
|
const extensionNames = Object.keys(extensions);
|
|
3348
|
-
|
|
3349
2972
|
if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate$1.extensionName) {
|
|
3350
2973
|
const message = 'Server indicated an extension that was not requested';
|
|
3351
2974
|
abortHandshake$1(websocket, socket, message);
|
|
3352
2975
|
return;
|
|
3353
2976
|
}
|
|
3354
|
-
|
|
3355
2977
|
try {
|
|
3356
2978
|
perMessageDeflate.accept(extensions[PerMessageDeflate$1.extensionName]);
|
|
3357
2979
|
} catch (err) {
|
|
@@ -3359,10 +2981,8 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3359
2981
|
abortHandshake$1(websocket, socket, message);
|
|
3360
2982
|
return;
|
|
3361
2983
|
}
|
|
3362
|
-
|
|
3363
2984
|
websocket._extensions[PerMessageDeflate$1.extensionName] = perMessageDeflate;
|
|
3364
2985
|
}
|
|
3365
|
-
|
|
3366
2986
|
websocket.setSocket(socket, head, {
|
|
3367
2987
|
generateMask: opts.generateMask,
|
|
3368
2988
|
maxPayload: opts.maxPayload,
|
|
@@ -3371,6 +2991,7 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3371
2991
|
});
|
|
3372
2992
|
req.end();
|
|
3373
2993
|
}
|
|
2994
|
+
|
|
3374
2995
|
/**
|
|
3375
2996
|
* Emit the `'error'` and `'close'` events.
|
|
3376
2997
|
*
|
|
@@ -3378,13 +2999,12 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
3378
2999
|
* @param {Error} The error to emit
|
|
3379
3000
|
* @private
|
|
3380
3001
|
*/
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
3002
|
function emitErrorAndClose(websocket, err) {
|
|
3384
3003
|
websocket._readyState = WebSocket$1.CLOSING;
|
|
3385
3004
|
websocket.emit('error', err);
|
|
3386
3005
|
websocket.emitClose();
|
|
3387
3006
|
}
|
|
3007
|
+
|
|
3388
3008
|
/**
|
|
3389
3009
|
* Create a `net.Socket` and initiate a connection.
|
|
3390
3010
|
*
|
|
@@ -3392,12 +3012,11 @@ function emitErrorAndClose(websocket, err) {
|
|
|
3392
3012
|
* @return {net.Socket} The newly created socket used to start the connection
|
|
3393
3013
|
* @private
|
|
3394
3014
|
*/
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
3015
|
function netConnect(options) {
|
|
3398
3016
|
options.path = options.socketPath;
|
|
3399
3017
|
return net.connect(options);
|
|
3400
3018
|
}
|
|
3019
|
+
|
|
3401
3020
|
/**
|
|
3402
3021
|
* Create a `tls.TLSSocket` and initiate a connection.
|
|
3403
3022
|
*
|
|
@@ -3405,17 +3024,14 @@ function netConnect(options) {
|
|
|
3405
3024
|
* @return {tls.TLSSocket} The newly created socket used to start the connection
|
|
3406
3025
|
* @private
|
|
3407
3026
|
*/
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
3027
|
function tlsConnect(options) {
|
|
3411
3028
|
options.path = undefined;
|
|
3412
|
-
|
|
3413
3029
|
if (!options.servername && options.servername !== '') {
|
|
3414
3030
|
options.servername = net.isIP(options.host) ? '' : options.host;
|
|
3415
3031
|
}
|
|
3416
|
-
|
|
3417
3032
|
return tls.connect(options);
|
|
3418
3033
|
}
|
|
3034
|
+
|
|
3419
3035
|
/**
|
|
3420
3036
|
* Abort the handshake and emit an error.
|
|
3421
3037
|
*
|
|
@@ -3425,17 +3041,13 @@ function tlsConnect(options) {
|
|
|
3425
3041
|
* @param {String} message The error message
|
|
3426
3042
|
* @private
|
|
3427
3043
|
*/
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
3044
|
function abortHandshake$1(websocket, stream, message) {
|
|
3431
3045
|
websocket._readyState = WebSocket$1.CLOSING;
|
|
3432
3046
|
const err = new Error(message);
|
|
3433
3047
|
Error.captureStackTrace(err, abortHandshake$1);
|
|
3434
|
-
|
|
3435
3048
|
if (stream.setHeader) {
|
|
3436
3049
|
stream[kAborted] = true;
|
|
3437
3050
|
stream.abort();
|
|
3438
|
-
|
|
3439
3051
|
if (stream.socket && !stream.socket.destroyed) {
|
|
3440
3052
|
//
|
|
3441
3053
|
// On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if
|
|
@@ -3444,7 +3056,6 @@ function abortHandshake$1(websocket, stream, message) {
|
|
|
3444
3056
|
//
|
|
3445
3057
|
stream.socket.destroy();
|
|
3446
3058
|
}
|
|
3447
|
-
|
|
3448
3059
|
process.nextTick(emitErrorAndClose, websocket, err);
|
|
3449
3060
|
} else {
|
|
3450
3061
|
stream.destroy(err);
|
|
@@ -3452,6 +3063,7 @@ function abortHandshake$1(websocket, stream, message) {
|
|
|
3452
3063
|
stream.once('close', websocket.emitClose.bind(websocket));
|
|
3453
3064
|
}
|
|
3454
3065
|
}
|
|
3066
|
+
|
|
3455
3067
|
/**
|
|
3456
3068
|
* Handle cases where the `ping()`, `pong()`, or `send()` methods are called
|
|
3457
3069
|
* when the `readyState` attribute is `CLOSING` or `CLOSED`.
|
|
@@ -3461,25 +3073,24 @@ function abortHandshake$1(websocket, stream, message) {
|
|
|
3461
3073
|
* @param {Function} [cb] Callback
|
|
3462
3074
|
* @private
|
|
3463
3075
|
*/
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
3076
|
function sendAfterClose(websocket, data, cb) {
|
|
3467
3077
|
if (data) {
|
|
3468
|
-
const length = toBuffer(data).length;
|
|
3078
|
+
const length = toBuffer(data).length;
|
|
3079
|
+
|
|
3080
|
+
//
|
|
3469
3081
|
// The `_bufferedAmount` property is used only when the peer is a client and
|
|
3470
3082
|
// the opening handshake fails. Under these circumstances, in fact, the
|
|
3471
3083
|
// `setSocket()` method is not called, so the `_socket` and `_sender`
|
|
3472
3084
|
// properties are set to `null`.
|
|
3473
3085
|
//
|
|
3474
|
-
|
|
3475
3086
|
if (websocket._socket) websocket._sender._bufferedBytes += length;else websocket._bufferedAmount += length;
|
|
3476
3087
|
}
|
|
3477
|
-
|
|
3478
3088
|
if (cb) {
|
|
3479
3089
|
const err = new Error(`WebSocket is not open: readyState ${websocket.readyState} ` + `(${readyStates[websocket.readyState]})`);
|
|
3480
3090
|
cb(err);
|
|
3481
3091
|
}
|
|
3482
3092
|
}
|
|
3093
|
+
|
|
3483
3094
|
/**
|
|
3484
3095
|
* The listener of the `Receiver` `'conclude'` event.
|
|
3485
3096
|
*
|
|
@@ -3487,65 +3098,57 @@ function sendAfterClose(websocket, data, cb) {
|
|
|
3487
3098
|
* @param {Buffer} reason The reason for closing
|
|
3488
3099
|
* @private
|
|
3489
3100
|
*/
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
3101
|
function receiverOnConclude(code, reason) {
|
|
3493
3102
|
const websocket = this[kWebSocket$1];
|
|
3494
3103
|
websocket._closeFrameReceived = true;
|
|
3495
3104
|
websocket._closeMessage = reason;
|
|
3496
3105
|
websocket._closeCode = code;
|
|
3497
3106
|
if (websocket._socket[kWebSocket$1] === undefined) return;
|
|
3498
|
-
|
|
3499
3107
|
websocket._socket.removeListener('data', socketOnData);
|
|
3500
|
-
|
|
3501
3108
|
process.nextTick(resume, websocket._socket);
|
|
3502
3109
|
if (code === 1005) websocket.close();else websocket.close(code, reason);
|
|
3503
3110
|
}
|
|
3111
|
+
|
|
3504
3112
|
/**
|
|
3505
3113
|
* The listener of the `Receiver` `'drain'` event.
|
|
3506
3114
|
*
|
|
3507
3115
|
* @private
|
|
3508
3116
|
*/
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
3117
|
function receiverOnDrain() {
|
|
3512
3118
|
const websocket = this[kWebSocket$1];
|
|
3513
3119
|
if (!websocket.isPaused) websocket._socket.resume();
|
|
3514
3120
|
}
|
|
3121
|
+
|
|
3515
3122
|
/**
|
|
3516
3123
|
* The listener of the `Receiver` `'error'` event.
|
|
3517
3124
|
*
|
|
3518
3125
|
* @param {(RangeError|Error)} err The emitted error
|
|
3519
3126
|
* @private
|
|
3520
3127
|
*/
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
3128
|
function receiverOnError(err) {
|
|
3524
3129
|
const websocket = this[kWebSocket$1];
|
|
3525
|
-
|
|
3526
3130
|
if (websocket._socket[kWebSocket$1] !== undefined) {
|
|
3527
|
-
websocket._socket.removeListener('data', socketOnData);
|
|
3131
|
+
websocket._socket.removeListener('data', socketOnData);
|
|
3132
|
+
|
|
3133
|
+
//
|
|
3528
3134
|
// On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See
|
|
3529
3135
|
// https://github.com/websockets/ws/issues/1940.
|
|
3530
3136
|
//
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
3137
|
process.nextTick(resume, websocket._socket);
|
|
3534
3138
|
websocket.close(err[kStatusCode]);
|
|
3535
3139
|
}
|
|
3536
|
-
|
|
3537
3140
|
websocket.emit('error', err);
|
|
3538
3141
|
}
|
|
3142
|
+
|
|
3539
3143
|
/**
|
|
3540
3144
|
* The listener of the `Receiver` `'finish'` event.
|
|
3541
3145
|
*
|
|
3542
3146
|
* @private
|
|
3543
3147
|
*/
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
3148
|
function receiverOnFinish() {
|
|
3547
3149
|
this[kWebSocket$1].emitClose();
|
|
3548
3150
|
}
|
|
3151
|
+
|
|
3549
3152
|
/**
|
|
3550
3153
|
* The listener of the `Receiver` `'message'` event.
|
|
3551
3154
|
*
|
|
@@ -3553,60 +3156,56 @@ function receiverOnFinish() {
|
|
|
3553
3156
|
* @param {Boolean} isBinary Specifies whether the message is binary or not
|
|
3554
3157
|
* @private
|
|
3555
3158
|
*/
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
3159
|
function receiverOnMessage(data, isBinary) {
|
|
3559
3160
|
this[kWebSocket$1].emit('message', data, isBinary);
|
|
3560
3161
|
}
|
|
3162
|
+
|
|
3561
3163
|
/**
|
|
3562
3164
|
* The listener of the `Receiver` `'ping'` event.
|
|
3563
3165
|
*
|
|
3564
3166
|
* @param {Buffer} data The data included in the ping frame
|
|
3565
3167
|
* @private
|
|
3566
3168
|
*/
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
3169
|
function receiverOnPing(data) {
|
|
3570
3170
|
const websocket = this[kWebSocket$1];
|
|
3571
3171
|
websocket.pong(data, !websocket._isServer, NOOP);
|
|
3572
3172
|
websocket.emit('ping', data);
|
|
3573
3173
|
}
|
|
3174
|
+
|
|
3574
3175
|
/**
|
|
3575
3176
|
* The listener of the `Receiver` `'pong'` event.
|
|
3576
3177
|
*
|
|
3577
3178
|
* @param {Buffer} data The data included in the pong frame
|
|
3578
3179
|
* @private
|
|
3579
3180
|
*/
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
3181
|
function receiverOnPong(data) {
|
|
3583
3182
|
this[kWebSocket$1].emit('pong', data);
|
|
3584
3183
|
}
|
|
3184
|
+
|
|
3585
3185
|
/**
|
|
3586
3186
|
* Resume a readable stream
|
|
3587
3187
|
*
|
|
3588
3188
|
* @param {Readable} stream The readable stream
|
|
3589
3189
|
* @private
|
|
3590
3190
|
*/
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
3191
|
function resume(stream) {
|
|
3594
3192
|
stream.resume();
|
|
3595
3193
|
}
|
|
3194
|
+
|
|
3596
3195
|
/**
|
|
3597
3196
|
* The listener of the `net.Socket` `'close'` event.
|
|
3598
3197
|
*
|
|
3599
3198
|
* @private
|
|
3600
3199
|
*/
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
3200
|
function socketOnClose() {
|
|
3604
3201
|
const websocket = this[kWebSocket$1];
|
|
3605
3202
|
this.removeListener('close', socketOnClose);
|
|
3606
3203
|
this.removeListener('data', socketOnData);
|
|
3607
3204
|
this.removeListener('end', socketOnEnd);
|
|
3608
3205
|
websocket._readyState = WebSocket$1.CLOSING;
|
|
3609
|
-
let chunk;
|
|
3206
|
+
let chunk;
|
|
3207
|
+
|
|
3208
|
+
//
|
|
3610
3209
|
// The close frame might not have been received or the `'end'` event emitted,
|
|
3611
3210
|
// for example, if the socket was destroyed due to an error. Ensure that the
|
|
3612
3211
|
// `receiver` stream is closed after writing any remaining buffered data to
|
|
@@ -3615,73 +3214,62 @@ function socketOnClose() {
|
|
|
3615
3214
|
// will return `null`. If instead, the socket is paused, any possible buffered
|
|
3616
3215
|
// data will be read as a single chunk.
|
|
3617
3216
|
//
|
|
3618
|
-
|
|
3619
3217
|
if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && (chunk = websocket._socket.read()) !== null) {
|
|
3620
3218
|
websocket._receiver.write(chunk);
|
|
3621
3219
|
}
|
|
3622
|
-
|
|
3623
3220
|
websocket._receiver.end();
|
|
3624
|
-
|
|
3625
3221
|
this[kWebSocket$1] = undefined;
|
|
3626
3222
|
clearTimeout(websocket._closeTimer);
|
|
3627
|
-
|
|
3628
3223
|
if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) {
|
|
3629
3224
|
websocket.emitClose();
|
|
3630
3225
|
} else {
|
|
3631
3226
|
websocket._receiver.on('error', receiverOnFinish);
|
|
3632
|
-
|
|
3633
3227
|
websocket._receiver.on('finish', receiverOnFinish);
|
|
3634
3228
|
}
|
|
3635
3229
|
}
|
|
3230
|
+
|
|
3636
3231
|
/**
|
|
3637
3232
|
* The listener of the `net.Socket` `'data'` event.
|
|
3638
3233
|
*
|
|
3639
3234
|
* @param {Buffer} chunk A chunk of data
|
|
3640
3235
|
* @private
|
|
3641
3236
|
*/
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
3237
|
function socketOnData(chunk) {
|
|
3645
3238
|
if (!this[kWebSocket$1]._receiver.write(chunk)) {
|
|
3646
3239
|
this.pause();
|
|
3647
3240
|
}
|
|
3648
3241
|
}
|
|
3242
|
+
|
|
3649
3243
|
/**
|
|
3650
3244
|
* The listener of the `net.Socket` `'end'` event.
|
|
3651
3245
|
*
|
|
3652
3246
|
* @private
|
|
3653
3247
|
*/
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
3248
|
function socketOnEnd() {
|
|
3657
3249
|
const websocket = this[kWebSocket$1];
|
|
3658
3250
|
websocket._readyState = WebSocket$1.CLOSING;
|
|
3659
|
-
|
|
3660
3251
|
websocket._receiver.end();
|
|
3661
|
-
|
|
3662
3252
|
this.end();
|
|
3663
3253
|
}
|
|
3254
|
+
|
|
3664
3255
|
/**
|
|
3665
3256
|
* The listener of the `net.Socket` `'error'` event.
|
|
3666
3257
|
*
|
|
3667
3258
|
* @private
|
|
3668
3259
|
*/
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
3260
|
function socketOnError$1() {
|
|
3672
3261
|
const websocket = this[kWebSocket$1];
|
|
3673
3262
|
this.removeListener('error', socketOnError$1);
|
|
3674
3263
|
this.on('error', NOOP);
|
|
3675
|
-
|
|
3676
3264
|
if (websocket) {
|
|
3677
3265
|
websocket._readyState = WebSocket$1.CLOSING;
|
|
3678
3266
|
this.destroy();
|
|
3679
3267
|
}
|
|
3680
3268
|
}
|
|
3681
|
-
|
|
3682
3269
|
const {
|
|
3683
3270
|
tokenChars
|
|
3684
3271
|
} = validation.exports;
|
|
3272
|
+
|
|
3685
3273
|
/**
|
|
3686
3274
|
* Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.
|
|
3687
3275
|
*
|
|
@@ -3689,62 +3277,46 @@ const {
|
|
|
3689
3277
|
* @return {Set} The subprotocol names
|
|
3690
3278
|
* @public
|
|
3691
3279
|
*/
|
|
3692
|
-
|
|
3693
3280
|
function parse(header) {
|
|
3694
3281
|
const protocols = new Set();
|
|
3695
3282
|
let start = -1;
|
|
3696
3283
|
let end = -1;
|
|
3697
3284
|
let i = 0;
|
|
3698
|
-
|
|
3699
3285
|
for (i; i < header.length; i++) {
|
|
3700
3286
|
const code = header.charCodeAt(i);
|
|
3701
|
-
|
|
3702
3287
|
if (end === -1 && tokenChars[code] === 1) {
|
|
3703
3288
|
if (start === -1) start = i;
|
|
3704
|
-
} else if (i !== 0 && (code === 0x20
|
|
3705
|
-
/* ' ' */
|
|
3706
|
-
|| code === 0x09)
|
|
3707
|
-
/* '\t' */
|
|
3708
|
-
) {
|
|
3289
|
+
} else if (i !== 0 && (code === 0x20 /* ' ' */ || code === 0x09) /* '\t' */) {
|
|
3709
3290
|
if (end === -1 && start !== -1) end = i;
|
|
3710
|
-
} else if (code === 0x2c
|
|
3711
|
-
/* ',' */
|
|
3712
|
-
) {
|
|
3291
|
+
} else if (code === 0x2c /* ',' */) {
|
|
3713
3292
|
if (start === -1) {
|
|
3714
3293
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
3715
3294
|
}
|
|
3716
|
-
|
|
3717
3295
|
if (end === -1) end = i;
|
|
3718
3296
|
const protocol = header.slice(start, end);
|
|
3719
|
-
|
|
3720
3297
|
if (protocols.has(protocol)) {
|
|
3721
3298
|
throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
|
|
3722
3299
|
}
|
|
3723
|
-
|
|
3724
3300
|
protocols.add(protocol);
|
|
3725
3301
|
start = end = -1;
|
|
3726
3302
|
} else {
|
|
3727
3303
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
3728
3304
|
}
|
|
3729
3305
|
}
|
|
3730
|
-
|
|
3731
3306
|
if (start === -1 || end !== -1) {
|
|
3732
3307
|
throw new SyntaxError('Unexpected end of input');
|
|
3733
3308
|
}
|
|
3734
|
-
|
|
3735
3309
|
const protocol = header.slice(start, i);
|
|
3736
|
-
|
|
3737
3310
|
if (protocols.has(protocol)) {
|
|
3738
3311
|
throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
|
|
3739
3312
|
}
|
|
3740
|
-
|
|
3741
3313
|
protocols.add(protocol);
|
|
3742
3314
|
return protocols;
|
|
3743
3315
|
}
|
|
3744
|
-
|
|
3745
3316
|
var subprotocol$1 = {
|
|
3746
3317
|
parse
|
|
3747
3318
|
};
|
|
3319
|
+
|
|
3748
3320
|
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls|https$" }] */
|
|
3749
3321
|
|
|
3750
3322
|
const EventEmitter = require$$0$2;
|
|
@@ -3764,12 +3336,12 @@ const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
|
|
|
3764
3336
|
const RUNNING = 0;
|
|
3765
3337
|
const CLOSING = 1;
|
|
3766
3338
|
const CLOSED = 2;
|
|
3339
|
+
|
|
3767
3340
|
/**
|
|
3768
3341
|
* Class representing a WebSocket server.
|
|
3769
3342
|
*
|
|
3770
3343
|
* @extends EventEmitter
|
|
3771
3344
|
*/
|
|
3772
|
-
|
|
3773
3345
|
class WebSocketServer extends EventEmitter {
|
|
3774
3346
|
/**
|
|
3775
3347
|
* Create a `WebSocketServer` instance.
|
|
@@ -3816,11 +3388,9 @@ class WebSocketServer extends EventEmitter {
|
|
|
3816
3388
|
WebSocket,
|
|
3817
3389
|
...options
|
|
3818
3390
|
};
|
|
3819
|
-
|
|
3820
3391
|
if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) {
|
|
3821
3392
|
throw new TypeError('One and only one of the "port", "server", or "noServer" options ' + 'must be specified');
|
|
3822
3393
|
}
|
|
3823
|
-
|
|
3824
3394
|
if (options.port != null) {
|
|
3825
3395
|
this._server = http.createServer((req, res) => {
|
|
3826
3396
|
const body = http.STATUS_CODES[426];
|
|
@@ -3830,12 +3400,10 @@ class WebSocketServer extends EventEmitter {
|
|
|
3830
3400
|
});
|
|
3831
3401
|
res.end(body);
|
|
3832
3402
|
});
|
|
3833
|
-
|
|
3834
3403
|
this._server.listen(options.port, options.host, options.backlog, callback);
|
|
3835
3404
|
} else if (options.server) {
|
|
3836
3405
|
this._server = options.server;
|
|
3837
3406
|
}
|
|
3838
|
-
|
|
3839
3407
|
if (this._server) {
|
|
3840
3408
|
const emitConnection = this.emit.bind(this, 'connection');
|
|
3841
3409
|
this._removeListeners = addListeners(this._server, {
|
|
@@ -3846,17 +3414,15 @@ class WebSocketServer extends EventEmitter {
|
|
|
3846
3414
|
}
|
|
3847
3415
|
});
|
|
3848
3416
|
}
|
|
3849
|
-
|
|
3850
3417
|
if (options.perMessageDeflate === true) options.perMessageDeflate = {};
|
|
3851
|
-
|
|
3852
3418
|
if (options.clientTracking) {
|
|
3853
3419
|
this.clients = new Set();
|
|
3854
3420
|
this._shouldEmitClose = false;
|
|
3855
3421
|
}
|
|
3856
|
-
|
|
3857
3422
|
this.options = options;
|
|
3858
3423
|
this._state = RUNNING;
|
|
3859
3424
|
}
|
|
3425
|
+
|
|
3860
3426
|
/**
|
|
3861
3427
|
* Returns the bound address, the address family name, and port of the server
|
|
3862
3428
|
* as reported by the operating system if listening on an IP socket.
|
|
@@ -3866,16 +3432,14 @@ class WebSocketServer extends EventEmitter {
|
|
|
3866
3432
|
* @return {(Object|String|null)} The address of the server
|
|
3867
3433
|
* @public
|
|
3868
3434
|
*/
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
3435
|
address() {
|
|
3872
3436
|
if (this.options.noServer) {
|
|
3873
3437
|
throw new Error('The server is operating in "noServer" mode');
|
|
3874
3438
|
}
|
|
3875
|
-
|
|
3876
3439
|
if (!this._server) return null;
|
|
3877
3440
|
return this._server.address();
|
|
3878
3441
|
}
|
|
3442
|
+
|
|
3879
3443
|
/**
|
|
3880
3444
|
* Stop the server from accepting new connections and emit the `'close'` event
|
|
3881
3445
|
* when all existing connections are closed.
|
|
@@ -3883,8 +3447,6 @@ class WebSocketServer extends EventEmitter {
|
|
|
3883
3447
|
* @param {Function} [cb] A one-time listener for the `'close'` event
|
|
3884
3448
|
* @public
|
|
3885
3449
|
*/
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
3450
|
close(cb) {
|
|
3889
3451
|
if (this._state === CLOSED) {
|
|
3890
3452
|
if (cb) {
|
|
@@ -3892,22 +3454,17 @@ class WebSocketServer extends EventEmitter {
|
|
|
3892
3454
|
cb(new Error('The server is not running'));
|
|
3893
3455
|
});
|
|
3894
3456
|
}
|
|
3895
|
-
|
|
3896
3457
|
process.nextTick(emitClose, this);
|
|
3897
3458
|
return;
|
|
3898
3459
|
}
|
|
3899
|
-
|
|
3900
3460
|
if (cb) this.once('close', cb);
|
|
3901
3461
|
if (this._state === CLOSING) return;
|
|
3902
3462
|
this._state = CLOSING;
|
|
3903
|
-
|
|
3904
3463
|
if (this.options.noServer || this.options.server) {
|
|
3905
3464
|
if (this._server) {
|
|
3906
3465
|
this._removeListeners();
|
|
3907
|
-
|
|
3908
3466
|
this._removeListeners = this._server = null;
|
|
3909
3467
|
}
|
|
3910
|
-
|
|
3911
3468
|
if (this.clients) {
|
|
3912
3469
|
if (!this.clients.size) {
|
|
3913
3470
|
process.nextTick(emitClose, this);
|
|
@@ -3919,19 +3476,19 @@ class WebSocketServer extends EventEmitter {
|
|
|
3919
3476
|
}
|
|
3920
3477
|
} else {
|
|
3921
3478
|
const server = this._server;
|
|
3922
|
-
|
|
3923
3479
|
this._removeListeners();
|
|
3480
|
+
this._removeListeners = this._server = null;
|
|
3924
3481
|
|
|
3925
|
-
|
|
3482
|
+
//
|
|
3926
3483
|
// The HTTP/S server was created internally. Close it, and rely on its
|
|
3927
3484
|
// `'close'` event.
|
|
3928
3485
|
//
|
|
3929
|
-
|
|
3930
3486
|
server.close(() => {
|
|
3931
3487
|
emitClose(this);
|
|
3932
3488
|
});
|
|
3933
3489
|
}
|
|
3934
3490
|
}
|
|
3491
|
+
|
|
3935
3492
|
/**
|
|
3936
3493
|
* See if a given request should be handled by this server instance.
|
|
3937
3494
|
*
|
|
@@ -3939,17 +3496,15 @@ class WebSocketServer extends EventEmitter {
|
|
|
3939
3496
|
* @return {Boolean} `true` if the request is valid, else `false`
|
|
3940
3497
|
* @public
|
|
3941
3498
|
*/
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
3499
|
shouldHandle(req) {
|
|
3945
3500
|
if (this.options.path) {
|
|
3946
3501
|
const index = req.url.indexOf('?');
|
|
3947
3502
|
const pathname = index !== -1 ? req.url.slice(0, index) : req.url;
|
|
3948
3503
|
if (pathname !== this.options.path) return false;
|
|
3949
3504
|
}
|
|
3950
|
-
|
|
3951
3505
|
return true;
|
|
3952
3506
|
}
|
|
3507
|
+
|
|
3953
3508
|
/**
|
|
3954
3509
|
* Handle a HTTP Upgrade request.
|
|
3955
3510
|
*
|
|
@@ -3960,45 +3515,36 @@ class WebSocketServer extends EventEmitter {
|
|
|
3960
3515
|
* @param {Function} cb Callback
|
|
3961
3516
|
* @public
|
|
3962
3517
|
*/
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
3518
|
handleUpgrade(req, socket, head, cb) {
|
|
3966
3519
|
socket.on('error', socketOnError);
|
|
3967
3520
|
const key = req.headers['sec-websocket-key'];
|
|
3968
3521
|
const version = +req.headers['sec-websocket-version'];
|
|
3969
|
-
|
|
3970
3522
|
if (req.method !== 'GET') {
|
|
3971
3523
|
const message = 'Invalid HTTP method';
|
|
3972
3524
|
abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);
|
|
3973
3525
|
return;
|
|
3974
3526
|
}
|
|
3975
|
-
|
|
3976
3527
|
if (req.headers.upgrade.toLowerCase() !== 'websocket') {
|
|
3977
3528
|
const message = 'Invalid Upgrade header';
|
|
3978
3529
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
|
|
3979
3530
|
return;
|
|
3980
3531
|
}
|
|
3981
|
-
|
|
3982
3532
|
if (!key || !keyRegex.test(key)) {
|
|
3983
3533
|
const message = 'Missing or invalid Sec-WebSocket-Key header';
|
|
3984
3534
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
|
|
3985
3535
|
return;
|
|
3986
3536
|
}
|
|
3987
|
-
|
|
3988
3537
|
if (version !== 8 && version !== 13) {
|
|
3989
3538
|
const message = 'Missing or invalid Sec-WebSocket-Version header';
|
|
3990
3539
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
|
|
3991
3540
|
return;
|
|
3992
3541
|
}
|
|
3993
|
-
|
|
3994
3542
|
if (!this.shouldHandle(req)) {
|
|
3995
3543
|
abortHandshake(socket, 400);
|
|
3996
3544
|
return;
|
|
3997
3545
|
}
|
|
3998
|
-
|
|
3999
3546
|
const secWebSocketProtocol = req.headers['sec-websocket-protocol'];
|
|
4000
3547
|
let protocols = new Set();
|
|
4001
|
-
|
|
4002
3548
|
if (secWebSocketProtocol !== undefined) {
|
|
4003
3549
|
try {
|
|
4004
3550
|
protocols = subprotocol.parse(secWebSocketProtocol);
|
|
@@ -4008,16 +3554,12 @@ class WebSocketServer extends EventEmitter {
|
|
|
4008
3554
|
return;
|
|
4009
3555
|
}
|
|
4010
3556
|
}
|
|
4011
|
-
|
|
4012
3557
|
const secWebSocketExtensions = req.headers['sec-websocket-extensions'];
|
|
4013
3558
|
const extensions = {};
|
|
4014
|
-
|
|
4015
3559
|
if (this.options.perMessageDeflate && secWebSocketExtensions !== undefined) {
|
|
4016
3560
|
const perMessageDeflate = new PerMessageDeflate(this.options.perMessageDeflate, true, this.options.maxPayload);
|
|
4017
|
-
|
|
4018
3561
|
try {
|
|
4019
3562
|
const offers = extension.parse(secWebSocketExtensions);
|
|
4020
|
-
|
|
4021
3563
|
if (offers[PerMessageDeflate.extensionName]) {
|
|
4022
3564
|
perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
|
|
4023
3565
|
extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
|
|
@@ -4027,34 +3569,31 @@ class WebSocketServer extends EventEmitter {
|
|
|
4027
3569
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
|
|
4028
3570
|
return;
|
|
4029
3571
|
}
|
|
4030
|
-
}
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
//
|
|
4031
3575
|
// Optionally call external client verification handler.
|
|
4032
3576
|
//
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
3577
|
if (this.options.verifyClient) {
|
|
4036
3578
|
const info = {
|
|
4037
3579
|
origin: req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
|
|
4038
3580
|
secure: !!(req.socket.authorized || req.socket.encrypted),
|
|
4039
3581
|
req
|
|
4040
3582
|
};
|
|
4041
|
-
|
|
4042
3583
|
if (this.options.verifyClient.length === 2) {
|
|
4043
3584
|
this.options.verifyClient(info, (verified, code, message, headers) => {
|
|
4044
3585
|
if (!verified) {
|
|
4045
3586
|
return abortHandshake(socket, code || 401, message, headers);
|
|
4046
3587
|
}
|
|
4047
|
-
|
|
4048
3588
|
this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
|
|
4049
3589
|
});
|
|
4050
3590
|
return;
|
|
4051
3591
|
}
|
|
4052
|
-
|
|
4053
3592
|
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
|
|
4054
3593
|
}
|
|
4055
|
-
|
|
4056
3594
|
this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
|
|
4057
3595
|
}
|
|
3596
|
+
|
|
4058
3597
|
/**
|
|
4059
3598
|
* Upgrade the connection to WebSocket.
|
|
4060
3599
|
*
|
|
@@ -4069,35 +3608,28 @@ class WebSocketServer extends EventEmitter {
|
|
|
4069
3608
|
* @throws {Error} If called more than once with the same socket
|
|
4070
3609
|
* @private
|
|
4071
3610
|
*/
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
3611
|
completeUpgrade(extensions, key, protocols, req, socket, head, cb) {
|
|
4075
3612
|
//
|
|
4076
3613
|
// Destroy the socket if the client has already sent a FIN packet.
|
|
4077
3614
|
//
|
|
4078
3615
|
if (!socket.readable || !socket.writable) return socket.destroy();
|
|
4079
|
-
|
|
4080
3616
|
if (socket[kWebSocket]) {
|
|
4081
3617
|
throw new Error('server.handleUpgrade() was called more than once with the same ' + 'socket, possibly due to a misconfiguration');
|
|
4082
3618
|
}
|
|
4083
|
-
|
|
4084
3619
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
4085
3620
|
const digest = createHash('sha1').update(key + GUID).digest('base64');
|
|
4086
3621
|
const headers = ['HTTP/1.1 101 Switching Protocols', 'Upgrade: websocket', 'Connection: Upgrade', `Sec-WebSocket-Accept: ${digest}`];
|
|
4087
3622
|
const ws = new this.options.WebSocket(null);
|
|
4088
|
-
|
|
4089
3623
|
if (protocols.size) {
|
|
4090
3624
|
//
|
|
4091
3625
|
// Optionally call external protocol selection handler.
|
|
4092
3626
|
//
|
|
4093
3627
|
const protocol = this.options.handleProtocols ? this.options.handleProtocols(protocols, req) : protocols.values().next().value;
|
|
4094
|
-
|
|
4095
3628
|
if (protocol) {
|
|
4096
3629
|
headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
|
|
4097
3630
|
ws._protocol = protocol;
|
|
4098
3631
|
}
|
|
4099
3632
|
}
|
|
4100
|
-
|
|
4101
3633
|
if (extensions[PerMessageDeflate.extensionName]) {
|
|
4102
3634
|
const params = extensions[PerMessageDeflate.extensionName].params;
|
|
4103
3635
|
const value = extension.format({
|
|
@@ -4105,11 +3637,11 @@ class WebSocketServer extends EventEmitter {
|
|
|
4105
3637
|
});
|
|
4106
3638
|
headers.push(`Sec-WebSocket-Extensions: ${value}`);
|
|
4107
3639
|
ws._extensions = extensions;
|
|
4108
|
-
}
|
|
3640
|
+
}
|
|
3641
|
+
|
|
3642
|
+
//
|
|
4109
3643
|
// Allow external modification/inspection of handshake headers.
|
|
4110
3644
|
//
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
3645
|
this.emit('headers', headers, req);
|
|
4114
3646
|
socket.write(headers.concat('\r\n').join('\r\n'));
|
|
4115
3647
|
socket.removeListener('error', socketOnError);
|
|
@@ -4117,24 +3649,20 @@ class WebSocketServer extends EventEmitter {
|
|
|
4117
3649
|
maxPayload: this.options.maxPayload,
|
|
4118
3650
|
skipUTF8Validation: this.options.skipUTF8Validation
|
|
4119
3651
|
});
|
|
4120
|
-
|
|
4121
3652
|
if (this.clients) {
|
|
4122
3653
|
this.clients.add(ws);
|
|
4123
3654
|
ws.on('close', () => {
|
|
4124
3655
|
this.clients.delete(ws);
|
|
4125
|
-
|
|
4126
3656
|
if (this._shouldEmitClose && !this.clients.size) {
|
|
4127
3657
|
process.nextTick(emitClose, this);
|
|
4128
3658
|
}
|
|
4129
3659
|
});
|
|
4130
3660
|
}
|
|
4131
|
-
|
|
4132
3661
|
cb(ws, req);
|
|
4133
3662
|
}
|
|
4134
|
-
|
|
4135
3663
|
}
|
|
4136
|
-
|
|
4137
3664
|
var websocketServer = WebSocketServer;
|
|
3665
|
+
|
|
4138
3666
|
/**
|
|
4139
3667
|
* Add event listeners on an `EventEmitter` using a map of <event, listener>
|
|
4140
3668
|
* pairs.
|
|
@@ -4145,38 +3673,35 @@ var websocketServer = WebSocketServer;
|
|
|
4145
3673
|
* called
|
|
4146
3674
|
* @private
|
|
4147
3675
|
*/
|
|
4148
|
-
|
|
4149
3676
|
function addListeners(server, map) {
|
|
4150
3677
|
for (const event of Object.keys(map)) server.on(event, map[event]);
|
|
4151
|
-
|
|
4152
3678
|
return function removeListeners() {
|
|
4153
3679
|
for (const event of Object.keys(map)) {
|
|
4154
3680
|
server.removeListener(event, map[event]);
|
|
4155
3681
|
}
|
|
4156
3682
|
};
|
|
4157
3683
|
}
|
|
3684
|
+
|
|
4158
3685
|
/**
|
|
4159
3686
|
* Emit a `'close'` event on an `EventEmitter`.
|
|
4160
3687
|
*
|
|
4161
3688
|
* @param {EventEmitter} server The event emitter
|
|
4162
3689
|
* @private
|
|
4163
3690
|
*/
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
3691
|
function emitClose(server) {
|
|
4167
3692
|
server._state = CLOSED;
|
|
4168
3693
|
server.emit('close');
|
|
4169
3694
|
}
|
|
3695
|
+
|
|
4170
3696
|
/**
|
|
4171
3697
|
* Handle socket errors.
|
|
4172
3698
|
*
|
|
4173
3699
|
* @private
|
|
4174
3700
|
*/
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
3701
|
function socketOnError() {
|
|
4178
3702
|
this.destroy();
|
|
4179
3703
|
}
|
|
3704
|
+
|
|
4180
3705
|
/**
|
|
4181
3706
|
* Close the connection when preconditions are not fulfilled.
|
|
4182
3707
|
*
|
|
@@ -4186,8 +3711,6 @@ function socketOnError() {
|
|
|
4186
3711
|
* @param {Object} [headers] Additional HTTP response headers
|
|
4187
3712
|
* @private
|
|
4188
3713
|
*/
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
3714
|
function abortHandshake(socket, code, message, headers) {
|
|
4192
3715
|
//
|
|
4193
3716
|
// The socket is writable unless the user destroyed or ended it before calling
|
|
@@ -4207,6 +3730,7 @@ function abortHandshake(socket, code, message, headers) {
|
|
|
4207
3730
|
socket.once('finish', socket.destroy);
|
|
4208
3731
|
socket.end(`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` + Object.keys(headers).map(h => `${h}: ${headers[h]}`).join('\r\n') + '\r\n\r\n' + message);
|
|
4209
3732
|
}
|
|
3733
|
+
|
|
4210
3734
|
/**
|
|
4211
3735
|
* Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least
|
|
4212
3736
|
* one listener for it, otherwise call `abortHandshake()`.
|
|
@@ -4218,8 +3742,6 @@ function abortHandshake(socket, code, message, headers) {
|
|
|
4218
3742
|
* @param {String} message The HTTP response body
|
|
4219
3743
|
* @private
|
|
4220
3744
|
*/
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
3745
|
function abortHandshakeOrEmitwsClientError(server, req, socket, code, message) {
|
|
4224
3746
|
if (server.listenerCount('wsClientError')) {
|
|
4225
3747
|
const err = new Error(message);
|