isomorfeus-transport 2.5.5 → 22.9.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/isomorfeus/core_ext/hash/deep_merge.rb +34 -0
  3. data/lib/isomorfeus/core_ext/kernel.rb +56 -0
  4. data/lib/isomorfeus/core_ext/object/deep_dup.rb +53 -0
  5. data/lib/isomorfeus/core_ext/object/duplicable.rb +60 -0
  6. data/lib/isomorfeus/transport/compressor_rack.rb +1 -1
  7. data/lib/isomorfeus/transport/config.rb +37 -0
  8. data/lib/isomorfeus/transport/rack_middleware.rb +16 -9
  9. data/lib/isomorfeus/transport/request_agent.rb +1 -0
  10. data/lib/isomorfeus/transport/server_socket_processor.rb +13 -1
  11. data/lib/isomorfeus/transport/version.rb +1 -1
  12. data/lib/isomorfeus/transport.rb +45 -38
  13. data/lib/isomorfeus-transport.rb +25 -16
  14. data/lib/lucid_channel.rb +103 -0
  15. data/lib/lucid_handler.rb +25 -0
  16. metadata +40 -90
  17. data/lib/isomorfeus/transport/handler/authentication_handler.rb +0 -55
  18. data/lib/isomorfeus/transport/imports.rb +0 -10
  19. data/lib/isomorfeus/transport/ssr_login.rb +0 -30
  20. data/lib/lucid_channel/base.rb +0 -8
  21. data/lib/lucid_channel/mixin.rb +0 -105
  22. data/lib/lucid_handler/base.rb +0 -8
  23. data/lib/lucid_handler/mixin.rb +0 -27
  24. data/node_modules/.package-lock.json +0 -27
  25. data/node_modules/ws/LICENSE +0 -19
  26. data/node_modules/ws/README.md +0 -489
  27. data/node_modules/ws/browser.js +0 -8
  28. data/node_modules/ws/index.js +0 -13
  29. data/node_modules/ws/lib/buffer-util.js +0 -126
  30. data/node_modules/ws/lib/constants.js +0 -12
  31. data/node_modules/ws/lib/event-target.js +0 -266
  32. data/node_modules/ws/lib/extension.js +0 -203
  33. data/node_modules/ws/lib/limiter.js +0 -55
  34. data/node_modules/ws/lib/permessage-deflate.js +0 -511
  35. data/node_modules/ws/lib/receiver.js +0 -618
  36. data/node_modules/ws/lib/sender.js +0 -478
  37. data/node_modules/ws/lib/stream.js +0 -159
  38. data/node_modules/ws/lib/subprotocol.js +0 -62
  39. data/node_modules/ws/lib/validation.js +0 -124
  40. data/node_modules/ws/lib/websocket-server.js +0 -488
  41. data/node_modules/ws/lib/websocket.js +0 -1264
  42. data/node_modules/ws/package.json +0 -61
  43. data/node_modules/ws/wrapper.mjs +0 -8
  44. data/package.json +0 -6
@@ -1,511 +0,0 @@
1
- 'use strict';
2
-
3
- const zlib = require('zlib');
4
-
5
- const bufferUtil = require('./buffer-util');
6
- const Limiter = require('./limiter');
7
- const { kStatusCode } = require('./constants');
8
-
9
- const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
10
- const kPerMessageDeflate = Symbol('permessage-deflate');
11
- const kTotalLength = Symbol('total-length');
12
- const kCallback = Symbol('callback');
13
- const kBuffers = Symbol('buffers');
14
- const kError = Symbol('error');
15
-
16
- //
17
- // We limit zlib concurrency, which prevents severe memory fragmentation
18
- // as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913
19
- // and https://github.com/websockets/ws/issues/1202
20
- //
21
- // Intentionally global; it's the global thread pool that's an issue.
22
- //
23
- let zlibLimiter;
24
-
25
- /**
26
- * permessage-deflate implementation.
27
- */
28
- class PerMessageDeflate {
29
- /**
30
- * Creates a PerMessageDeflate instance.
31
- *
32
- * @param {Object} [options] Configuration options
33
- * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support
34
- * for, or request, a custom client window size
35
- * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/
36
- * acknowledge disabling of client context takeover
37
- * @param {Number} [options.concurrencyLimit=10] The number of concurrent
38
- * calls to zlib
39
- * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
40
- * use of a custom server window size
41
- * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
42
- * disabling of server context takeover
43
- * @param {Number} [options.threshold=1024] Size (in bytes) below which
44
- * messages should not be compressed if context takeover is disabled
45
- * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on
46
- * deflate
47
- * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
48
- * inflate
49
- * @param {Boolean} [isServer=false] Create the instance in either server or
50
- * client mode
51
- * @param {Number} [maxPayload=0] The maximum allowed message length
52
- */
53
- constructor(options, isServer, maxPayload) {
54
- this._maxPayload = maxPayload | 0;
55
- this._options = options || {};
56
- this._threshold =
57
- this._options.threshold !== undefined ? this._options.threshold : 1024;
58
- this._isServer = !!isServer;
59
- this._deflate = null;
60
- this._inflate = null;
61
-
62
- this.params = null;
63
-
64
- if (!zlibLimiter) {
65
- const concurrency =
66
- this._options.concurrencyLimit !== undefined
67
- ? this._options.concurrencyLimit
68
- : 10;
69
- zlibLimiter = new Limiter(concurrency);
70
- }
71
- }
72
-
73
- /**
74
- * @type {String}
75
- */
76
- static get extensionName() {
77
- return 'permessage-deflate';
78
- }
79
-
80
- /**
81
- * Create an extension negotiation offer.
82
- *
83
- * @return {Object} Extension parameters
84
- * @public
85
- */
86
- offer() {
87
- const params = {};
88
-
89
- if (this._options.serverNoContextTakeover) {
90
- params.server_no_context_takeover = true;
91
- }
92
- if (this._options.clientNoContextTakeover) {
93
- params.client_no_context_takeover = true;
94
- }
95
- if (this._options.serverMaxWindowBits) {
96
- params.server_max_window_bits = this._options.serverMaxWindowBits;
97
- }
98
- if (this._options.clientMaxWindowBits) {
99
- params.client_max_window_bits = this._options.clientMaxWindowBits;
100
- } else if (this._options.clientMaxWindowBits == null) {
101
- params.client_max_window_bits = true;
102
- }
103
-
104
- return params;
105
- }
106
-
107
- /**
108
- * Accept an extension negotiation offer/response.
109
- *
110
- * @param {Array} configurations The extension negotiation offers/reponse
111
- * @return {Object} Accepted configuration
112
- * @public
113
- */
114
- accept(configurations) {
115
- configurations = this.normalizeParams(configurations);
116
-
117
- this.params = this._isServer
118
- ? this.acceptAsServer(configurations)
119
- : this.acceptAsClient(configurations);
120
-
121
- return this.params;
122
- }
123
-
124
- /**
125
- * Releases all resources used by the extension.
126
- *
127
- * @public
128
- */
129
- cleanup() {
130
- if (this._inflate) {
131
- this._inflate.close();
132
- this._inflate = null;
133
- }
134
-
135
- if (this._deflate) {
136
- const callback = this._deflate[kCallback];
137
-
138
- this._deflate.close();
139
- this._deflate = null;
140
-
141
- if (callback) {
142
- callback(
143
- new Error(
144
- 'The deflate stream was closed while data was being processed'
145
- )
146
- );
147
- }
148
- }
149
- }
150
-
151
- /**
152
- * Accept an extension negotiation offer.
153
- *
154
- * @param {Array} offers The extension negotiation offers
155
- * @return {Object} Accepted configuration
156
- * @private
157
- */
158
- acceptAsServer(offers) {
159
- const opts = this._options;
160
- const accepted = offers.find((params) => {
161
- if (
162
- (opts.serverNoContextTakeover === false &&
163
- params.server_no_context_takeover) ||
164
- (params.server_max_window_bits &&
165
- (opts.serverMaxWindowBits === false ||
166
- (typeof opts.serverMaxWindowBits === 'number' &&
167
- opts.serverMaxWindowBits > params.server_max_window_bits))) ||
168
- (typeof opts.clientMaxWindowBits === 'number' &&
169
- !params.client_max_window_bits)
170
- ) {
171
- return false;
172
- }
173
-
174
- return true;
175
- });
176
-
177
- if (!accepted) {
178
- throw new Error('None of the extension offers can be accepted');
179
- }
180
-
181
- if (opts.serverNoContextTakeover) {
182
- accepted.server_no_context_takeover = true;
183
- }
184
- if (opts.clientNoContextTakeover) {
185
- accepted.client_no_context_takeover = true;
186
- }
187
- if (typeof opts.serverMaxWindowBits === 'number') {
188
- accepted.server_max_window_bits = opts.serverMaxWindowBits;
189
- }
190
- if (typeof opts.clientMaxWindowBits === 'number') {
191
- accepted.client_max_window_bits = opts.clientMaxWindowBits;
192
- } else if (
193
- accepted.client_max_window_bits === true ||
194
- opts.clientMaxWindowBits === false
195
- ) {
196
- delete accepted.client_max_window_bits;
197
- }
198
-
199
- return accepted;
200
- }
201
-
202
- /**
203
- * Accept the extension negotiation response.
204
- *
205
- * @param {Array} response The extension negotiation response
206
- * @return {Object} Accepted configuration
207
- * @private
208
- */
209
- acceptAsClient(response) {
210
- const params = response[0];
211
-
212
- if (
213
- this._options.clientNoContextTakeover === false &&
214
- params.client_no_context_takeover
215
- ) {
216
- throw new Error('Unexpected parameter "client_no_context_takeover"');
217
- }
218
-
219
- if (!params.client_max_window_bits) {
220
- if (typeof this._options.clientMaxWindowBits === 'number') {
221
- params.client_max_window_bits = this._options.clientMaxWindowBits;
222
- }
223
- } else if (
224
- this._options.clientMaxWindowBits === false ||
225
- (typeof this._options.clientMaxWindowBits === 'number' &&
226
- params.client_max_window_bits > this._options.clientMaxWindowBits)
227
- ) {
228
- throw new Error(
229
- 'Unexpected or invalid parameter "client_max_window_bits"'
230
- );
231
- }
232
-
233
- return params;
234
- }
235
-
236
- /**
237
- * Normalize parameters.
238
- *
239
- * @param {Array} configurations The extension negotiation offers/reponse
240
- * @return {Array} The offers/response with normalized parameters
241
- * @private
242
- */
243
- normalizeParams(configurations) {
244
- configurations.forEach((params) => {
245
- Object.keys(params).forEach((key) => {
246
- let value = params[key];
247
-
248
- if (value.length > 1) {
249
- throw new Error(`Parameter "${key}" must have only a single value`);
250
- }
251
-
252
- value = value[0];
253
-
254
- if (key === 'client_max_window_bits') {
255
- if (value !== true) {
256
- const num = +value;
257
- if (!Number.isInteger(num) || num < 8 || num > 15) {
258
- throw new TypeError(
259
- `Invalid value for parameter "${key}": ${value}`
260
- );
261
- }
262
- value = num;
263
- } else if (!this._isServer) {
264
- throw new TypeError(
265
- `Invalid value for parameter "${key}": ${value}`
266
- );
267
- }
268
- } else if (key === 'server_max_window_bits') {
269
- const num = +value;
270
- if (!Number.isInteger(num) || num < 8 || num > 15) {
271
- throw new TypeError(
272
- `Invalid value for parameter "${key}": ${value}`
273
- );
274
- }
275
- value = num;
276
- } else if (
277
- key === 'client_no_context_takeover' ||
278
- key === 'server_no_context_takeover'
279
- ) {
280
- if (value !== true) {
281
- throw new TypeError(
282
- `Invalid value for parameter "${key}": ${value}`
283
- );
284
- }
285
- } else {
286
- throw new Error(`Unknown parameter "${key}"`);
287
- }
288
-
289
- params[key] = value;
290
- });
291
- });
292
-
293
- return configurations;
294
- }
295
-
296
- /**
297
- * Decompress data. Concurrency limited.
298
- *
299
- * @param {Buffer} data Compressed data
300
- * @param {Boolean} fin Specifies whether or not this is the last fragment
301
- * @param {Function} callback Callback
302
- * @public
303
- */
304
- decompress(data, fin, callback) {
305
- zlibLimiter.add((done) => {
306
- this._decompress(data, fin, (err, result) => {
307
- done();
308
- callback(err, result);
309
- });
310
- });
311
- }
312
-
313
- /**
314
- * Compress data. Concurrency limited.
315
- *
316
- * @param {(Buffer|String)} data Data to compress
317
- * @param {Boolean} fin Specifies whether or not this is the last fragment
318
- * @param {Function} callback Callback
319
- * @public
320
- */
321
- compress(data, fin, callback) {
322
- zlibLimiter.add((done) => {
323
- this._compress(data, fin, (err, result) => {
324
- done();
325
- callback(err, result);
326
- });
327
- });
328
- }
329
-
330
- /**
331
- * Decompress data.
332
- *
333
- * @param {Buffer} data Compressed data
334
- * @param {Boolean} fin Specifies whether or not this is the last fragment
335
- * @param {Function} callback Callback
336
- * @private
337
- */
338
- _decompress(data, fin, callback) {
339
- const endpoint = this._isServer ? 'client' : 'server';
340
-
341
- if (!this._inflate) {
342
- const key = `${endpoint}_max_window_bits`;
343
- const windowBits =
344
- typeof this.params[key] !== 'number'
345
- ? zlib.Z_DEFAULT_WINDOWBITS
346
- : this.params[key];
347
-
348
- this._inflate = zlib.createInflateRaw({
349
- ...this._options.zlibInflateOptions,
350
- windowBits
351
- });
352
- this._inflate[kPerMessageDeflate] = this;
353
- this._inflate[kTotalLength] = 0;
354
- this._inflate[kBuffers] = [];
355
- this._inflate.on('error', inflateOnError);
356
- this._inflate.on('data', inflateOnData);
357
- }
358
-
359
- this._inflate[kCallback] = callback;
360
-
361
- this._inflate.write(data);
362
- if (fin) this._inflate.write(TRAILER);
363
-
364
- this._inflate.flush(() => {
365
- const err = this._inflate[kError];
366
-
367
- if (err) {
368
- this._inflate.close();
369
- this._inflate = null;
370
- callback(err);
371
- return;
372
- }
373
-
374
- const data = bufferUtil.concat(
375
- this._inflate[kBuffers],
376
- this._inflate[kTotalLength]
377
- );
378
-
379
- if (this._inflate._readableState.endEmitted) {
380
- this._inflate.close();
381
- this._inflate = null;
382
- } else {
383
- this._inflate[kTotalLength] = 0;
384
- this._inflate[kBuffers] = [];
385
-
386
- if (fin && this.params[`${endpoint}_no_context_takeover`]) {
387
- this._inflate.reset();
388
- }
389
- }
390
-
391
- callback(null, data);
392
- });
393
- }
394
-
395
- /**
396
- * Compress data.
397
- *
398
- * @param {(Buffer|String)} data Data to compress
399
- * @param {Boolean} fin Specifies whether or not this is the last fragment
400
- * @param {Function} callback Callback
401
- * @private
402
- */
403
- _compress(data, fin, callback) {
404
- const endpoint = this._isServer ? 'server' : 'client';
405
-
406
- if (!this._deflate) {
407
- const key = `${endpoint}_max_window_bits`;
408
- const windowBits =
409
- typeof this.params[key] !== 'number'
410
- ? zlib.Z_DEFAULT_WINDOWBITS
411
- : this.params[key];
412
-
413
- this._deflate = zlib.createDeflateRaw({
414
- ...this._options.zlibDeflateOptions,
415
- windowBits
416
- });
417
-
418
- this._deflate[kTotalLength] = 0;
419
- this._deflate[kBuffers] = [];
420
-
421
- this._deflate.on('data', deflateOnData);
422
- }
423
-
424
- this._deflate[kCallback] = callback;
425
-
426
- this._deflate.write(data);
427
- this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
428
- if (!this._deflate) {
429
- //
430
- // The deflate stream was closed while data was being processed.
431
- //
432
- return;
433
- }
434
-
435
- let data = bufferUtil.concat(
436
- this._deflate[kBuffers],
437
- this._deflate[kTotalLength]
438
- );
439
-
440
- if (fin) data = data.slice(0, data.length - 4);
441
-
442
- //
443
- // Ensure that the callback will not be called again in
444
- // `PerMessageDeflate#cleanup()`.
445
- //
446
- this._deflate[kCallback] = null;
447
-
448
- this._deflate[kTotalLength] = 0;
449
- this._deflate[kBuffers] = [];
450
-
451
- if (fin && this.params[`${endpoint}_no_context_takeover`]) {
452
- this._deflate.reset();
453
- }
454
-
455
- callback(null, data);
456
- });
457
- }
458
- }
459
-
460
- module.exports = PerMessageDeflate;
461
-
462
- /**
463
- * The listener of the `zlib.DeflateRaw` stream `'data'` event.
464
- *
465
- * @param {Buffer} chunk A chunk of data
466
- * @private
467
- */
468
- function deflateOnData(chunk) {
469
- this[kBuffers].push(chunk);
470
- this[kTotalLength] += chunk.length;
471
- }
472
-
473
- /**
474
- * The listener of the `zlib.InflateRaw` stream `'data'` event.
475
- *
476
- * @param {Buffer} chunk A chunk of data
477
- * @private
478
- */
479
- function inflateOnData(chunk) {
480
- this[kTotalLength] += chunk.length;
481
-
482
- if (
483
- this[kPerMessageDeflate]._maxPayload < 1 ||
484
- this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload
485
- ) {
486
- this[kBuffers].push(chunk);
487
- return;
488
- }
489
-
490
- this[kError] = new RangeError('Max payload size exceeded');
491
- this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';
492
- this[kError][kStatusCode] = 1009;
493
- this.removeListener('data', inflateOnData);
494
- this.reset();
495
- }
496
-
497
- /**
498
- * The listener of the `zlib.InflateRaw` stream `'error'` event.
499
- *
500
- * @param {Error} err The emitted error
501
- * @private
502
- */
503
- function inflateOnError(err) {
504
- //
505
- // There is no need to call `Zlib#close()` as the handle is automatically
506
- // closed when an error is emitted.
507
- //
508
- this[kPerMessageDeflate]._inflate = null;
509
- err[kStatusCode] = 1007;
510
- this[kCallback](err);
511
- }