isomorfeus-transport 1.0.0.zeta23 → 2.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -21
  3. data/README.md +27 -36
  4. data/lib/isomorfeus/transport/client_processor.rb +35 -30
  5. data/lib/isomorfeus/transport/config.rb +182 -158
  6. data/lib/isomorfeus/transport/hamster_session_store.rb +96 -0
  7. data/lib/isomorfeus/transport/handler/authentication_handler.rb +70 -70
  8. data/lib/isomorfeus/transport/imports.rb +9 -0
  9. data/lib/isomorfeus/transport/middlewares.rb +13 -13
  10. data/lib/isomorfeus/transport/rack_middleware.rb +59 -55
  11. data/lib/isomorfeus/transport/request_agent.rb +34 -34
  12. data/lib/isomorfeus/transport/response_agent.rb +23 -23
  13. data/lib/isomorfeus/transport/server_processor.rb +129 -101
  14. data/lib/isomorfeus/transport/server_socket_processor.rb +54 -54
  15. data/lib/isomorfeus/transport/ssr_login.rb +28 -28
  16. data/lib/isomorfeus/transport/version.rb +5 -5
  17. data/lib/isomorfeus/transport/{websocket.rb → websocket_client.rb} +123 -123
  18. data/lib/isomorfeus/transport.rb +200 -213
  19. data/lib/isomorfeus-transport.rb +70 -62
  20. data/lib/lucid_authentication/mixin.rb +122 -124
  21. data/lib/lucid_channel/base.rb +8 -11
  22. data/lib/lucid_channel/mixin.rb +105 -50
  23. data/lib/lucid_handler/base.rb +8 -9
  24. data/lib/lucid_handler/mixin.rb +27 -27
  25. data/node_modules/.package-lock.json +27 -0
  26. data/node_modules/ws/LICENSE +19 -0
  27. data/node_modules/ws/README.md +496 -0
  28. data/node_modules/ws/browser.js +8 -0
  29. data/node_modules/ws/index.js +13 -0
  30. data/node_modules/ws/lib/buffer-util.js +126 -0
  31. data/node_modules/ws/lib/constants.js +12 -0
  32. data/node_modules/ws/lib/event-target.js +266 -0
  33. data/node_modules/ws/lib/extension.js +203 -0
  34. data/node_modules/ws/lib/limiter.js +55 -0
  35. data/node_modules/ws/lib/permessage-deflate.js +511 -0
  36. data/node_modules/ws/lib/receiver.js +612 -0
  37. data/node_modules/ws/lib/sender.js +414 -0
  38. data/node_modules/ws/lib/stream.js +180 -0
  39. data/node_modules/ws/lib/subprotocol.js +62 -0
  40. data/node_modules/ws/lib/validation.js +124 -0
  41. data/node_modules/ws/lib/websocket-server.js +485 -0
  42. data/node_modules/ws/lib/websocket.js +1144 -0
  43. data/node_modules/ws/package.json +61 -0
  44. data/node_modules/ws/wrapper.mjs +8 -0
  45. data/package.json +6 -0
  46. metadata +76 -54
  47. data/lib/isomorfeus/transport/dbm_session_store.rb +0 -51
@@ -0,0 +1,496 @@
1
+ # ws: a Node.js WebSocket library
2
+
3
+ [![Version npm](https://img.shields.io/npm/v/ws.svg?logo=npm)](https://www.npmjs.com/package/ws)
4
+ [![Build](https://img.shields.io/github/workflow/status/websockets/ws/CI/master?label=build&logo=github)](https://github.com/websockets/ws/actions?query=workflow%3ACI+branch%3Amaster)
5
+ [![Windows x86 Build](https://img.shields.io/appveyor/ci/lpinca/ws/master.svg?logo=appveyor)](https://ci.appveyor.com/project/lpinca/ws)
6
+ [![Coverage Status](https://img.shields.io/coveralls/websockets/ws/master.svg?logo=coveralls)](https://coveralls.io/github/websockets/ws)
7
+
8
+ ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and
9
+ server implementation.
10
+
11
+ Passes the quite extensive Autobahn test suite: [server][server-report],
12
+ [client][client-report].
13
+
14
+ **Note**: This module does not work in the browser. The client in the docs is a
15
+ reference to a back end with the role of a client in the WebSocket
16
+ communication. Browser clients must use the native
17
+ [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
18
+ object. To make the same code work seamlessly on Node.js and the browser, you
19
+ can use one of the many wrappers available on npm, like
20
+ [isomorphic-ws](https://github.com/heineiuo/isomorphic-ws).
21
+
22
+ ## Table of Contents
23
+
24
+ - [Protocol support](#protocol-support)
25
+ - [Installing](#installing)
26
+ - [Opt-in for performance](#opt-in-for-performance)
27
+ - [API docs](#api-docs)
28
+ - [WebSocket compression](#websocket-compression)
29
+ - [Usage examples](#usage-examples)
30
+ - [Sending and receiving text data](#sending-and-receiving-text-data)
31
+ - [Sending binary data](#sending-binary-data)
32
+ - [Simple server](#simple-server)
33
+ - [External HTTP/S server](#external-https-server)
34
+ - [Multiple servers sharing a single HTTP/S server](#multiple-servers-sharing-a-single-https-server)
35
+ - [Client authentication](#client-authentication)
36
+ - [Server broadcast](#server-broadcast)
37
+ - [echo.websocket.org demo](#echowebsocketorg-demo)
38
+ - [Use the Node.js streams API](#use-the-nodejs-streams-api)
39
+ - [Other examples](#other-examples)
40
+ - [FAQ](#faq)
41
+ - [How to get the IP address of the client?](#how-to-get-the-ip-address-of-the-client)
42
+ - [How to detect and close broken connections?](#how-to-detect-and-close-broken-connections)
43
+ - [How to connect via a proxy?](#how-to-connect-via-a-proxy)
44
+ - [Changelog](#changelog)
45
+ - [License](#license)
46
+
47
+ ## Protocol support
48
+
49
+ - **HyBi drafts 07-12** (Use the option `protocolVersion: 8`)
50
+ - **HyBi drafts 13-17** (Current default, alternatively option
51
+ `protocolVersion: 13`)
52
+
53
+ ## Installing
54
+
55
+ ```
56
+ npm install ws
57
+ ```
58
+
59
+ ### Opt-in for performance
60
+
61
+ There are 2 optional modules that can be installed along side with the ws
62
+ module. These modules are binary addons which improve certain operations.
63
+ Prebuilt binaries are available for the most popular platforms so you don't
64
+ necessarily need to have a C++ compiler installed on your machine.
65
+
66
+ - `npm install --save-optional bufferutil`: Allows to efficiently perform
67
+ operations such as masking and unmasking the data payload of the WebSocket
68
+ frames.
69
+ - `npm install --save-optional utf-8-validate`: Allows to efficiently check if a
70
+ message contains valid UTF-8.
71
+
72
+ ## API docs
73
+
74
+ See [`/doc/ws.md`](./doc/ws.md) for Node.js-like documentation of ws classes and
75
+ utility functions.
76
+
77
+ ## WebSocket compression
78
+
79
+ ws supports the [permessage-deflate extension][permessage-deflate] which enables
80
+ the client and server to negotiate a compression algorithm and its parameters,
81
+ and then selectively apply it to the data payloads of each WebSocket message.
82
+
83
+ The extension is disabled by default on the server and enabled by default on the
84
+ client. It adds a significant overhead in terms of performance and memory
85
+ consumption so we suggest to enable it only if it is really needed.
86
+
87
+ Note that Node.js has a variety of issues with high-performance compression,
88
+ where increased concurrency, especially on Linux, can lead to [catastrophic
89
+ memory fragmentation][node-zlib-bug] and slow performance. If you intend to use
90
+ permessage-deflate in production, it is worthwhile to set up a test
91
+ representative of your workload and ensure Node.js/zlib will handle it with
92
+ acceptable performance and memory usage.
93
+
94
+ Tuning of permessage-deflate can be done via the options defined below. You can
95
+ also use `zlibDeflateOptions` and `zlibInflateOptions`, which is passed directly
96
+ into the creation of [raw deflate/inflate streams][node-zlib-deflaterawdocs].
97
+
98
+ See [the docs][ws-server-options] for more options.
99
+
100
+ ```js
101
+ import WebSocket, { WebSocketServer } from 'ws';
102
+
103
+ const wss = new WebSocketServer({
104
+ port: 8080,
105
+ perMessageDeflate: {
106
+ zlibDeflateOptions: {
107
+ // See zlib defaults.
108
+ chunkSize: 1024,
109
+ memLevel: 7,
110
+ level: 3
111
+ },
112
+ zlibInflateOptions: {
113
+ chunkSize: 10 * 1024
114
+ },
115
+ // Other options settable:
116
+ clientNoContextTakeover: true, // Defaults to negotiated value.
117
+ serverNoContextTakeover: true, // Defaults to negotiated value.
118
+ serverMaxWindowBits: 10, // Defaults to negotiated value.
119
+ // Below options specified as default values.
120
+ concurrencyLimit: 10, // Limits zlib concurrency for perf.
121
+ threshold: 1024 // Size (in bytes) below which messages
122
+ // should not be compressed.
123
+ }
124
+ });
125
+ ```
126
+
127
+ The client will only use the extension if it is supported and enabled on the
128
+ server. To always disable the extension on the client set the
129
+ `perMessageDeflate` option to `false`.
130
+
131
+ ```js
132
+ import WebSocket from 'ws';
133
+
134
+ const ws = new WebSocket('ws://www.host.com/path', {
135
+ perMessageDeflate: false
136
+ });
137
+ ```
138
+
139
+ ## Usage examples
140
+
141
+ ### Sending and receiving text data
142
+
143
+ ```js
144
+ import WebSocket from 'ws';
145
+
146
+ const ws = new WebSocket('ws://www.host.com/path');
147
+
148
+ ws.on('open', function open() {
149
+ ws.send('something');
150
+ });
151
+
152
+ ws.on('message', function incoming(message) {
153
+ console.log('received: %s', message);
154
+ });
155
+ ```
156
+
157
+ ### Sending binary data
158
+
159
+ ```js
160
+ import WebSocket from 'ws';
161
+
162
+ const ws = new WebSocket('ws://www.host.com/path');
163
+
164
+ ws.on('open', function open() {
165
+ const array = new Float32Array(5);
166
+
167
+ for (var i = 0; i < array.length; ++i) {
168
+ array[i] = i / 2;
169
+ }
170
+
171
+ ws.send(array);
172
+ });
173
+ ```
174
+
175
+ ### Simple server
176
+
177
+ ```js
178
+ import { WebSocketServer } from 'ws';
179
+
180
+ const wss = new WebSocketServer({ port: 8080 });
181
+
182
+ wss.on('connection', function connection(ws) {
183
+ ws.on('message', function incoming(message) {
184
+ console.log('received: %s', message);
185
+ });
186
+
187
+ ws.send('something');
188
+ });
189
+ ```
190
+
191
+ ### External HTTP/S server
192
+
193
+ ```js
194
+ import { createServer } from 'https';
195
+ import { readFileSync } from 'fs';
196
+ import { WebSocketServer } from 'ws';
197
+
198
+ const server = createServer({
199
+ cert: readFileSync('/path/to/cert.pem'),
200
+ key: readFileSync('/path/to/key.pem')
201
+ });
202
+ const wss = new WebSocketServer({ server });
203
+
204
+ wss.on('connection', function connection(ws) {
205
+ ws.on('message', function incoming(message) {
206
+ console.log('received: %s', message);
207
+ });
208
+
209
+ ws.send('something');
210
+ });
211
+
212
+ server.listen(8080);
213
+ ```
214
+
215
+ ### Multiple servers sharing a single HTTP/S server
216
+
217
+ ```js
218
+ import { createServer } from 'http';
219
+ import { parse } from 'url';
220
+ import { WebSocketServer } from 'ws';
221
+
222
+ const server = createServer();
223
+ const wss1 = new WebSocketServer({ noServer: true });
224
+ const wss2 = new WebSocketServer({ noServer: true });
225
+
226
+ wss1.on('connection', function connection(ws) {
227
+ // ...
228
+ });
229
+
230
+ wss2.on('connection', function connection(ws) {
231
+ // ...
232
+ });
233
+
234
+ server.on('upgrade', function upgrade(request, socket, head) {
235
+ const { pathname } = parse(request.url);
236
+
237
+ if (pathname === '/foo') {
238
+ wss1.handleUpgrade(request, socket, head, function done(ws) {
239
+ wss1.emit('connection', ws, request);
240
+ });
241
+ } else if (pathname === '/bar') {
242
+ wss2.handleUpgrade(request, socket, head, function done(ws) {
243
+ wss2.emit('connection', ws, request);
244
+ });
245
+ } else {
246
+ socket.destroy();
247
+ }
248
+ });
249
+
250
+ server.listen(8080);
251
+ ```
252
+
253
+ ### Client authentication
254
+
255
+ ```js
256
+ import WebSocket from 'ws';
257
+ import { createServer } from 'http';
258
+
259
+ const server = createServer();
260
+ const wss = new WebSocketServer({ noServer: true });
261
+
262
+ wss.on('connection', function connection(ws, request, client) {
263
+ ws.on('message', function message(msg) {
264
+ console.log(`Received message ${msg} from user ${client}`);
265
+ });
266
+ });
267
+
268
+ server.on('upgrade', function upgrade(request, socket, head) {
269
+ // This function is not defined on purpose. Implement it with your own logic.
270
+ authenticate(request, (err, client) => {
271
+ if (err || !client) {
272
+ socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
273
+ socket.destroy();
274
+ return;
275
+ }
276
+
277
+ wss.handleUpgrade(request, socket, head, function done(ws) {
278
+ wss.emit('connection', ws, request, client);
279
+ });
280
+ });
281
+ });
282
+
283
+ server.listen(8080);
284
+ ```
285
+
286
+ Also see the provided [example][session-parse-example] using `express-session`.
287
+
288
+ ### Server broadcast
289
+
290
+ A client WebSocket broadcasting to all connected WebSocket clients, including
291
+ itself.
292
+
293
+ ```js
294
+ import WebSocket, { WebSocketServer } from 'ws';
295
+
296
+ const wss = new WebSocketServer({ port: 8080 });
297
+
298
+ wss.on('connection', function connection(ws) {
299
+ ws.on('message', function incoming(data, isBinary) {
300
+ wss.clients.forEach(function each(client) {
301
+ if (client.readyState === WebSocket.OPEN) {
302
+ client.send(data, { binary: isBinary });
303
+ }
304
+ });
305
+ });
306
+ });
307
+ ```
308
+
309
+ A client WebSocket broadcasting to every other connected WebSocket clients,
310
+ excluding itself.
311
+
312
+ ```js
313
+ import WebSocket, { WebSocketServer } from 'ws';
314
+
315
+ const wss = new WebSocketServer({ port: 8080 });
316
+
317
+ wss.on('connection', function connection(ws) {
318
+ ws.on('message', function incoming(data, isBinary) {
319
+ wss.clients.forEach(function each(client) {
320
+ if (client !== ws && client.readyState === WebSocket.OPEN) {
321
+ client.send(data, { binary: isBinary });
322
+ }
323
+ });
324
+ });
325
+ });
326
+ ```
327
+
328
+ ### echo.websocket.org demo
329
+
330
+ ```js
331
+ import WebSocket from 'ws';
332
+
333
+ const ws = new WebSocket('wss://echo.websocket.org/', {
334
+ origin: 'https://websocket.org'
335
+ });
336
+
337
+ ws.on('open', function open() {
338
+ console.log('connected');
339
+ ws.send(Date.now());
340
+ });
341
+
342
+ ws.on('close', function close() {
343
+ console.log('disconnected');
344
+ });
345
+
346
+ ws.on('message', function incoming(data) {
347
+ console.log(`Roundtrip time: ${Date.now() - data} ms`);
348
+
349
+ setTimeout(function timeout() {
350
+ ws.send(Date.now());
351
+ }, 500);
352
+ });
353
+ ```
354
+
355
+ ### Use the Node.js streams API
356
+
357
+ ```js
358
+ import WebSocket, { createWebSocketStream } from 'ws';
359
+
360
+ const ws = new WebSocket('wss://echo.websocket.org/', {
361
+ origin: 'https://websocket.org'
362
+ });
363
+
364
+ const duplex = createWebSocketStream(ws, { encoding: 'utf8' });
365
+
366
+ duplex.pipe(process.stdout);
367
+ process.stdin.pipe(duplex);
368
+ ```
369
+
370
+ ### Other examples
371
+
372
+ For a full example with a browser client communicating with a ws server, see the
373
+ examples folder.
374
+
375
+ Otherwise, see the test cases.
376
+
377
+ ## FAQ
378
+
379
+ ### How to get the IP address of the client?
380
+
381
+ The remote IP address can be obtained from the raw socket.
382
+
383
+ ```js
384
+ import { WebSocketServer } from 'ws';
385
+
386
+ const wss = new WebSocketServer({ port: 8080 });
387
+
388
+ wss.on('connection', function connection(ws, req) {
389
+ const ip = req.socket.remoteAddress;
390
+ });
391
+ ```
392
+
393
+ When the server runs behind a proxy like NGINX, the de-facto standard is to use
394
+ the `X-Forwarded-For` header.
395
+
396
+ ```js
397
+ wss.on('connection', function connection(ws, req) {
398
+ const ip = req.headers['x-forwarded-for'].split(',')[0].trim();
399
+ });
400
+ ```
401
+
402
+ ### How to detect and close broken connections?
403
+
404
+ Sometimes the link between the server and the client can be interrupted in a way
405
+ that keeps both the server and the client unaware of the broken state of the
406
+ connection (e.g. when pulling the cord).
407
+
408
+ In these cases ping messages can be used as a means to verify that the remote
409
+ endpoint is still responsive.
410
+
411
+ ```js
412
+ import { WebSocketServer } from 'ws';
413
+
414
+ function noop() {}
415
+
416
+ function heartbeat() {
417
+ this.isAlive = true;
418
+ }
419
+
420
+ const wss = new WebSocketServer({ port: 8080 });
421
+
422
+ wss.on('connection', function connection(ws) {
423
+ ws.isAlive = true;
424
+ ws.on('pong', heartbeat);
425
+ });
426
+
427
+ const interval = setInterval(function ping() {
428
+ wss.clients.forEach(function each(ws) {
429
+ if (ws.isAlive === false) return ws.terminate();
430
+
431
+ ws.isAlive = false;
432
+ ws.ping(noop);
433
+ });
434
+ }, 30000);
435
+
436
+ wss.on('close', function close() {
437
+ clearInterval(interval);
438
+ });
439
+ ```
440
+
441
+ Pong messages are automatically sent in response to ping messages as required by
442
+ the spec.
443
+
444
+ Just like the server example above your clients might as well lose connection
445
+ without knowing it. You might want to add a ping listener on your clients to
446
+ prevent that. A simple implementation would be:
447
+
448
+ ```js
449
+ import WebSocket from 'ws';
450
+
451
+ function heartbeat() {
452
+ clearTimeout(this.pingTimeout);
453
+
454
+ // Use `WebSocket#terminate()`, which immediately destroys the connection,
455
+ // instead of `WebSocket#close()`, which waits for the close timer.
456
+ // Delay should be equal to the interval at which your server
457
+ // sends out pings plus a conservative assumption of the latency.
458
+ this.pingTimeout = setTimeout(() => {
459
+ this.terminate();
460
+ }, 30000 + 1000);
461
+ }
462
+
463
+ const client = new WebSocket('wss://echo.websocket.org/');
464
+
465
+ client.on('open', heartbeat);
466
+ client.on('ping', heartbeat);
467
+ client.on('close', function clear() {
468
+ clearTimeout(this.pingTimeout);
469
+ });
470
+ ```
471
+
472
+ ### How to connect via a proxy?
473
+
474
+ Use a custom `http.Agent` implementation like [https-proxy-agent][] or
475
+ [socks-proxy-agent][].
476
+
477
+ ## Changelog
478
+
479
+ We're using the GitHub [releases][changelog] for changelog entries.
480
+
481
+ ## License
482
+
483
+ [MIT](LICENSE)
484
+
485
+ [changelog]: https://github.com/websockets/ws/releases
486
+ [client-report]: http://websockets.github.io/ws/autobahn/clients/
487
+ [https-proxy-agent]: https://github.com/TooTallNate/node-https-proxy-agent
488
+ [node-zlib-bug]: https://github.com/nodejs/node/issues/8871
489
+ [node-zlib-deflaterawdocs]:
490
+ https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options
491
+ [permessage-deflate]: https://tools.ietf.org/html/rfc7692
492
+ [server-report]: http://websockets.github.io/ws/autobahn/servers/
493
+ [session-parse-example]: ./examples/express-session-parse
494
+ [socks-proxy-agent]: https://github.com/TooTallNate/node-socks-proxy-agent
495
+ [ws-server-options]:
496
+ https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ module.exports = function () {
4
+ throw new Error(
5
+ 'ws does not work in the browser. Browser clients must use the native ' +
6
+ 'WebSocket object'
7
+ );
8
+ };
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const WebSocket = require('./lib/websocket');
4
+
5
+ WebSocket.createWebSocketStream = require('./lib/stream');
6
+ WebSocket.Server = require('./lib/websocket-server');
7
+ WebSocket.Receiver = require('./lib/receiver');
8
+ WebSocket.Sender = require('./lib/sender');
9
+
10
+ WebSocket.WebSocket = WebSocket;
11
+ WebSocket.WebSocketServer = WebSocket.Server;
12
+
13
+ module.exports = WebSocket;
@@ -0,0 +1,126 @@
1
+ 'use strict';
2
+
3
+ const { EMPTY_BUFFER } = require('./constants');
4
+
5
+ /**
6
+ * Merges an array of buffers into a new buffer.
7
+ *
8
+ * @param {Buffer[]} list The array of buffers to concat
9
+ * @param {Number} totalLength The total length of buffers in the list
10
+ * @return {Buffer} The resulting buffer
11
+ * @public
12
+ */
13
+ function concat(list, totalLength) {
14
+ if (list.length === 0) return EMPTY_BUFFER;
15
+ if (list.length === 1) return list[0];
16
+
17
+ const target = Buffer.allocUnsafe(totalLength);
18
+ let offset = 0;
19
+
20
+ for (let i = 0; i < list.length; i++) {
21
+ const buf = list[i];
22
+ target.set(buf, offset);
23
+ offset += buf.length;
24
+ }
25
+
26
+ if (offset < totalLength) return target.slice(0, offset);
27
+
28
+ return target;
29
+ }
30
+
31
+ /**
32
+ * Masks a buffer using the given mask.
33
+ *
34
+ * @param {Buffer} source The buffer to mask
35
+ * @param {Buffer} mask The mask to use
36
+ * @param {Buffer} output The buffer where to store the result
37
+ * @param {Number} offset The offset at which to start writing
38
+ * @param {Number} length The number of bytes to mask.
39
+ * @public
40
+ */
41
+ function _mask(source, mask, output, offset, length) {
42
+ for (let i = 0; i < length; i++) {
43
+ output[offset + i] = source[i] ^ mask[i & 3];
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Unmasks a buffer using the given mask.
49
+ *
50
+ * @param {Buffer} buffer The buffer to unmask
51
+ * @param {Buffer} mask The mask to use
52
+ * @public
53
+ */
54
+ function _unmask(buffer, mask) {
55
+ for (let i = 0; i < buffer.length; i++) {
56
+ buffer[i] ^= mask[i & 3];
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Converts a buffer to an `ArrayBuffer`.
62
+ *
63
+ * @param {Buffer} buf The buffer to convert
64
+ * @return {ArrayBuffer} Converted buffer
65
+ * @public
66
+ */
67
+ function toArrayBuffer(buf) {
68
+ if (buf.byteLength === buf.buffer.byteLength) {
69
+ return buf.buffer;
70
+ }
71
+
72
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
73
+ }
74
+
75
+ /**
76
+ * Converts `data` to a `Buffer`.
77
+ *
78
+ * @param {*} data The data to convert
79
+ * @return {Buffer} The buffer
80
+ * @throws {TypeError}
81
+ * @public
82
+ */
83
+ function toBuffer(data) {
84
+ toBuffer.readOnly = true;
85
+
86
+ if (Buffer.isBuffer(data)) return data;
87
+
88
+ let buf;
89
+
90
+ if (data instanceof ArrayBuffer) {
91
+ buf = Buffer.from(data);
92
+ } else if (ArrayBuffer.isView(data)) {
93
+ buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
94
+ } else {
95
+ buf = Buffer.from(data);
96
+ toBuffer.readOnly = false;
97
+ }
98
+
99
+ return buf;
100
+ }
101
+
102
+ try {
103
+ const bufferUtil = require('bufferutil');
104
+
105
+ module.exports = {
106
+ concat,
107
+ mask(source, mask, output, offset, length) {
108
+ if (length < 48) _mask(source, mask, output, offset, length);
109
+ else bufferUtil.mask(source, mask, output, offset, length);
110
+ },
111
+ toArrayBuffer,
112
+ toBuffer,
113
+ unmask(buffer, mask) {
114
+ if (buffer.length < 32) _unmask(buffer, mask);
115
+ else bufferUtil.unmask(buffer, mask);
116
+ }
117
+ };
118
+ } catch (e) /* istanbul ignore next */ {
119
+ module.exports = {
120
+ concat,
121
+ mask: _mask,
122
+ toArrayBuffer,
123
+ toBuffer,
124
+ unmask: _unmask
125
+ };
126
+ }
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ BINARY_TYPES: ['nodebuffer', 'arraybuffer', 'fragments'],
5
+ EMPTY_BUFFER: Buffer.alloc(0),
6
+ GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
7
+ kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),
8
+ kListener: Symbol('kListener'),
9
+ kStatusCode: Symbol('status-code'),
10
+ kWebSocket: Symbol('websocket'),
11
+ NOOP: () => {}
12
+ };