opal 1.6.1 → 1.7.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.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +17 -0
- data/CHANGELOG.md +35 -1
- data/Gemfile +1 -0
- data/HACKING.md +47 -26
- data/benchmark/benchmarks +415 -103
- data/benchmark/bm_call_overhead.yml +28 -0
- data/benchmark/run.rb +61 -40
- data/docs/cdp_common.json +3364 -0
- data/docs/cdp_common.md +18 -0
- data/docs/{headless_chrome.md → headless_browsers.md} +31 -12
- data/lib/opal/ast/builder.rb +1 -1
- data/lib/opal/builder.rb +6 -1
- data/lib/opal/builder_processors.rb +5 -3
- data/lib/opal/cache.rb +1 -7
- data/lib/opal/cli_options.rb +72 -58
- data/lib/opal/cli_runners/chrome.rb +47 -9
- data/lib/opal/cli_runners/chrome_cdp_interface.rb +238 -112
- data/lib/opal/cli_runners/compiler.rb +146 -13
- data/lib/opal/cli_runners/deno.rb +32 -0
- data/lib/opal/cli_runners/firefox.rb +350 -0
- data/lib/opal/cli_runners/firefox_cdp_interface.rb +212 -0
- data/lib/opal/cli_runners/node_modules/.bin/chrome-remote-interface.cmd +17 -0
- data/lib/opal/cli_runners/node_modules/.bin/chrome-remote-interface.ps1 +28 -0
- data/lib/opal/cli_runners/node_modules/.package-lock.json +41 -0
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/LICENSE +1 -1
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/README.md +322 -182
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/bin/client.js +99 -114
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/chrome-remote-interface.js +1 -11
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/index.js +16 -11
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/api.js +41 -33
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/chrome.js +224 -214
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/devtools.js +71 -191
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/external-request.js +26 -6
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/protocol.json +20788 -9049
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/websocket-wrapper.js +10 -3
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/package.json +59 -123
- data/lib/opal/cli_runners/node_modules/chrome-remote-interface/webpack.config.js +25 -32
- data/lib/opal/cli_runners/node_modules/commander/History.md +298 -0
- data/lib/opal/cli_runners/node_modules/commander/LICENSE +22 -0
- data/lib/opal/cli_runners/node_modules/commander/Readme.md +217 -61
- data/lib/opal/cli_runners/node_modules/commander/index.js +431 -145
- data/lib/opal/cli_runners/node_modules/commander/package.json +16 -79
- data/lib/opal/cli_runners/node_modules/ws/README.md +334 -98
- data/lib/opal/cli_runners/node_modules/ws/browser.js +8 -0
- data/lib/opal/cli_runners/node_modules/ws/index.js +5 -10
- data/lib/opal/cli_runners/node_modules/ws/lib/buffer-util.js +129 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/constants.js +10 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/event-target.js +184 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/extension.js +223 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/limiter.js +55 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/permessage-deflate.js +518 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/receiver.js +607 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/sender.js +409 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/stream.js +180 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/validation.js +104 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/websocket-server.js +447 -0
- data/lib/opal/cli_runners/node_modules/ws/lib/websocket.js +1195 -0
- data/lib/opal/cli_runners/node_modules/ws/package.json +40 -106
- data/lib/opal/cli_runners/package-lock.json +62 -0
- data/lib/opal/cli_runners/package.json +1 -1
- data/lib/opal/cli_runners.rb +26 -4
- data/lib/opal/nodes/args/prepare_post_args.rb +2 -2
- data/lib/opal/nodes/def.rb +8 -8
- data/lib/opal/nodes/iter.rb +12 -12
- data/lib/opal/nodes/logic.rb +1 -1
- data/lib/opal/nodes/masgn.rb +2 -2
- data/lib/opal/parser/with_ruby_lexer.rb +1 -1
- data/lib/opal/paths.rb +14 -0
- data/lib/opal/rewriter.rb +2 -0
- data/lib/opal/rewriters/forward_args.rb +52 -4
- data/lib/opal/rewriters/targeted_patches.rb +94 -0
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/basic_object.rb +1 -1
- data/opal/corelib/boolean.rb +2 -2
- data/opal/corelib/class.rb +11 -0
- data/opal/corelib/constants.rb +3 -3
- data/opal/corelib/enumerable.rb +4 -0
- data/opal/corelib/enumerator.rb +1 -1
- data/opal/corelib/hash.rb +2 -2
- data/opal/corelib/helpers.rb +1 -1
- data/opal/corelib/kernel.rb +3 -3
- data/opal/corelib/method.rb +1 -1
- data/opal/corelib/module.rb +29 -8
- data/opal/corelib/proc.rb +7 -5
- data/opal/corelib/runtime.js +141 -78
- data/opal/corelib/set.rb +252 -0
- data/opal/corelib/string.rb +2 -1
- data/opal/corelib/time.rb +2 -2
- data/opal/opal.rb +1 -0
- data/opal.gemspec +1 -0
- data/spec/filters/bugs/array.rb +22 -13
- data/spec/filters/bugs/base64.rb +5 -5
- data/spec/filters/bugs/basicobject.rb +16 -8
- data/spec/filters/bugs/bigdecimal.rb +161 -160
- data/spec/filters/bugs/binding.rb +10 -10
- data/spec/filters/bugs/class.rb +8 -8
- data/spec/filters/bugs/complex.rb +2 -1
- data/spec/filters/bugs/date.rb +79 -81
- data/spec/filters/bugs/datetime.rb +29 -29
- data/spec/filters/bugs/delegate.rb +1 -3
- data/spec/filters/bugs/encoding.rb +69 -69
- data/spec/filters/bugs/enumerable.rb +22 -20
- data/spec/filters/bugs/enumerator.rb +88 -85
- data/spec/filters/bugs/exception.rb +46 -40
- data/spec/filters/bugs/file.rb +32 -32
- data/spec/filters/bugs/float.rb +26 -21
- data/spec/filters/bugs/freeze.rb +88 -0
- data/spec/filters/bugs/hash.rb +39 -38
- data/spec/filters/bugs/integer.rb +57 -44
- data/spec/filters/bugs/io.rb +1 -1
- data/spec/filters/bugs/kernel.rb +349 -269
- data/spec/filters/bugs/language.rb +220 -188
- data/spec/filters/bugs/main.rb +5 -3
- data/spec/filters/bugs/marshal.rb +38 -38
- data/spec/filters/bugs/math.rb +2 -1
- data/spec/filters/bugs/method.rb +73 -62
- data/spec/filters/bugs/module.rb +163 -143
- data/spec/filters/bugs/numeric.rb +6 -6
- data/spec/filters/bugs/objectspace.rb +16 -16
- data/spec/filters/bugs/openstruct.rb +1 -1
- data/spec/filters/bugs/pack_unpack.rb +51 -51
- data/spec/filters/bugs/pathname.rb +7 -7
- data/spec/filters/bugs/proc.rb +63 -63
- data/spec/filters/bugs/random.rb +7 -6
- data/spec/filters/bugs/range.rb +12 -9
- data/spec/filters/bugs/rational.rb +8 -7
- data/spec/filters/bugs/regexp.rb +49 -48
- data/spec/filters/bugs/ruby-32.rb +56 -0
- data/spec/filters/bugs/set.rb +30 -30
- data/spec/filters/bugs/singleton.rb +4 -4
- data/spec/filters/bugs/string.rb +187 -99
- data/spec/filters/bugs/stringio.rb +7 -0
- data/spec/filters/bugs/stringscanner.rb +68 -68
- data/spec/filters/bugs/struct.rb +11 -9
- data/spec/filters/bugs/symbol.rb +1 -1
- data/spec/filters/bugs/time.rb +78 -63
- data/spec/filters/bugs/trace_point.rb +4 -4
- data/spec/filters/bugs/unboundmethod.rb +32 -17
- data/spec/filters/bugs/warnings.rb +8 -12
- data/spec/filters/unsupported/array.rb +24 -107
- data/spec/filters/unsupported/basicobject.rb +12 -12
- data/spec/filters/unsupported/bignum.rb +27 -52
- data/spec/filters/unsupported/class.rb +1 -2
- data/spec/filters/unsupported/delegator.rb +3 -3
- data/spec/filters/unsupported/enumerable.rb +2 -9
- data/spec/filters/unsupported/enumerator.rb +2 -11
- data/spec/filters/unsupported/file.rb +1 -1
- data/spec/filters/unsupported/float.rb +28 -47
- data/spec/filters/unsupported/hash.rb +8 -14
- data/spec/filters/unsupported/integer.rb +75 -91
- data/spec/filters/unsupported/kernel.rb +17 -35
- data/spec/filters/unsupported/language.rb +11 -19
- data/spec/filters/unsupported/marshal.rb +22 -41
- data/spec/filters/unsupported/matchdata.rb +28 -52
- data/spec/filters/unsupported/math.rb +1 -1
- data/spec/filters/unsupported/privacy.rb +229 -285
- data/spec/filters/unsupported/range.rb +1 -5
- data/spec/filters/unsupported/regexp.rb +40 -66
- data/spec/filters/unsupported/set.rb +2 -2
- data/spec/filters/unsupported/singleton.rb +4 -4
- data/spec/filters/unsupported/string.rb +305 -508
- data/spec/filters/unsupported/struct.rb +3 -4
- data/spec/filters/unsupported/symbol.rb +15 -18
- data/spec/filters/unsupported/thread.rb +1 -7
- data/spec/filters/unsupported/time.rb +159 -202
- data/spec/filters/unsupported/usage_of_files.rb +170 -259
- data/spec/lib/builder_spec.rb +4 -4
- data/spec/lib/rewriters/forward_args_spec.rb +32 -12
- data/spec/mspec-opal/runner.rb +2 -0
- data/spec/ruby_specs +4 -0
- data/stdlib/deno/base.rb +28 -0
- data/stdlib/deno/file.rb +340 -0
- data/stdlib/{headless_chrome.rb → headless_browser/base.rb} +1 -1
- data/stdlib/headless_browser/file.rb +15 -0
- data/stdlib/headless_browser.rb +4 -0
- data/stdlib/native.rb +1 -1
- data/stdlib/nodejs/file.rb +5 -0
- data/stdlib/opal/platform.rb +8 -6
- data/stdlib/opal-platform.rb +14 -8
- data/stdlib/set.rb +1 -258
- data/tasks/benchmarking.rake +62 -19
- data/tasks/performance.rake +1 -1
- data/tasks/testing.rake +5 -3
- data/test/nodejs/test_file.rb +29 -10
- data/test/opal/http_server.rb +28 -11
- data/test/opal/unsupported_and_bugs.rb +2 -1
- metadata +89 -50
- data/lib/opal/cli_runners/node_modules/ultron/LICENSE +0 -22
- data/lib/opal/cli_runners/node_modules/ultron/index.js +0 -138
- data/lib/opal/cli_runners/node_modules/ultron/package.json +0 -112
- data/lib/opal/cli_runners/node_modules/ws/SECURITY.md +0 -33
- data/lib/opal/cli_runners/node_modules/ws/lib/BufferUtil.fallback.js +0 -56
- data/lib/opal/cli_runners/node_modules/ws/lib/BufferUtil.js +0 -15
- data/lib/opal/cli_runners/node_modules/ws/lib/ErrorCodes.js +0 -28
- data/lib/opal/cli_runners/node_modules/ws/lib/EventTarget.js +0 -158
- data/lib/opal/cli_runners/node_modules/ws/lib/Extensions.js +0 -69
- data/lib/opal/cli_runners/node_modules/ws/lib/PerMessageDeflate.js +0 -339
- data/lib/opal/cli_runners/node_modules/ws/lib/Receiver.js +0 -520
- data/lib/opal/cli_runners/node_modules/ws/lib/Sender.js +0 -438
- data/lib/opal/cli_runners/node_modules/ws/lib/Validation.fallback.js +0 -9
- data/lib/opal/cli_runners/node_modules/ws/lib/Validation.js +0 -17
- data/lib/opal/cli_runners/node_modules/ws/lib/WebSocket.js +0 -705
- data/lib/opal/cli_runners/node_modules/ws/lib/WebSocketServer.js +0 -336
- data/spec/filters/bugs/boolean.rb +0 -3
- data/spec/filters/bugs/matrix.rb +0 -3
- data/spec/filters/unsupported/fixnum.rb +0 -15
- data/spec/filters/unsupported/freeze.rb +0 -102
- data/spec/filters/unsupported/pathname.rb +0 -4
- data/spec/filters/unsupported/proc.rb +0 -4
- data/spec/filters/unsupported/random.rb +0 -5
- data/spec/filters/unsupported/taint.rb +0 -162
@@ -1,56 +0,0 @@
|
|
1
|
-
/*!
|
2
|
-
* ws: a node.js websocket client
|
3
|
-
* Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
|
4
|
-
* MIT Licensed
|
5
|
-
*/
|
6
|
-
|
7
|
-
'use strict';
|
8
|
-
|
9
|
-
/**
|
10
|
-
* Merges an array of buffers into a target buffer.
|
11
|
-
*
|
12
|
-
* @param {Buffer} target The target buffer
|
13
|
-
* @param {Buffer[]} buffers The array of buffers to merge
|
14
|
-
* @public
|
15
|
-
*/
|
16
|
-
const merge = (target, buffers) => {
|
17
|
-
var offset = 0;
|
18
|
-
for (var i = 0; i < buffers.length; i++) {
|
19
|
-
const buf = buffers[i];
|
20
|
-
buf.copy(target, offset);
|
21
|
-
offset += buf.length;
|
22
|
-
}
|
23
|
-
};
|
24
|
-
|
25
|
-
/**
|
26
|
-
* Masks a buffer using the given mask.
|
27
|
-
*
|
28
|
-
* @param {Buffer} source The buffer to mask
|
29
|
-
* @param {Buffer} mask The mask to use
|
30
|
-
* @param {Buffer} output The buffer where to store the result
|
31
|
-
* @param {Number} offset The offset at which to start writing
|
32
|
-
* @param {Number} length The number of bytes to mask.
|
33
|
-
* @public
|
34
|
-
*/
|
35
|
-
const mask = (source, mask, output, offset, length) => {
|
36
|
-
for (var i = 0; i < length; i++) {
|
37
|
-
output[offset + i] = source[i] ^ mask[i & 3];
|
38
|
-
}
|
39
|
-
};
|
40
|
-
|
41
|
-
/**
|
42
|
-
* Unmasks a buffer using the given mask.
|
43
|
-
*
|
44
|
-
* @param {Buffer} buffer The buffer to unmask
|
45
|
-
* @param {Buffer} mask The mask to use
|
46
|
-
* @public
|
47
|
-
*/
|
48
|
-
const unmask = (buffer, mask) => {
|
49
|
-
// Required until https://github.com/nodejs/node/issues/9006 is resolved.
|
50
|
-
const length = buffer.length;
|
51
|
-
for (var i = 0; i < length; i++) {
|
52
|
-
buffer[i] ^= mask[i & 3];
|
53
|
-
}
|
54
|
-
};
|
55
|
-
|
56
|
-
module.exports = { merge, mask, unmask };
|
@@ -1,15 +0,0 @@
|
|
1
|
-
'use strict';
|
2
|
-
|
3
|
-
/*!
|
4
|
-
* ws: a node.js websocket client
|
5
|
-
* Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
|
6
|
-
* MIT Licensed
|
7
|
-
*/
|
8
|
-
|
9
|
-
try {
|
10
|
-
const bufferUtil = require('bufferutil');
|
11
|
-
|
12
|
-
module.exports = bufferUtil.BufferUtil || bufferUtil;
|
13
|
-
} catch (e) {
|
14
|
-
module.exports = require('./BufferUtil.fallback');
|
15
|
-
}
|
@@ -1,28 +0,0 @@
|
|
1
|
-
/*!
|
2
|
-
* ws: a node.js websocket client
|
3
|
-
* Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
|
4
|
-
* MIT Licensed
|
5
|
-
*/
|
6
|
-
|
7
|
-
'use strict';
|
8
|
-
|
9
|
-
module.exports = {
|
10
|
-
isValidErrorCode: function (code) {
|
11
|
-
return (code >= 1000 && code <= 1013 && code !== 1004 && code !== 1005 && code !== 1006) ||
|
12
|
-
(code >= 3000 && code <= 4999);
|
13
|
-
},
|
14
|
-
1000: 'normal',
|
15
|
-
1001: 'going away',
|
16
|
-
1002: 'protocol error',
|
17
|
-
1003: 'unsupported data',
|
18
|
-
1004: 'reserved',
|
19
|
-
1005: 'reserved for extensions',
|
20
|
-
1006: 'reserved for extensions',
|
21
|
-
1007: 'inconsistent or invalid data',
|
22
|
-
1008: 'policy violation',
|
23
|
-
1009: 'message too big',
|
24
|
-
1010: 'extension handshake missing',
|
25
|
-
1011: 'an unexpected condition prevented the request from being fulfilled',
|
26
|
-
1012: 'service restart',
|
27
|
-
1013: 'try again later'
|
28
|
-
};
|
@@ -1,158 +0,0 @@
|
|
1
|
-
'use strict';
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Class representing an event.
|
5
|
-
*
|
6
|
-
* @private
|
7
|
-
*/
|
8
|
-
class Event {
|
9
|
-
/**
|
10
|
-
* Create a new `Event`.
|
11
|
-
*
|
12
|
-
* @param {String} type The name of the event
|
13
|
-
* @param {Object} target A reference to the target to which the event was dispatched
|
14
|
-
*/
|
15
|
-
constructor (type, target) {
|
16
|
-
this.target = target;
|
17
|
-
this.type = type;
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
/**
|
22
|
-
* Class representing a message event.
|
23
|
-
*
|
24
|
-
* @extends Event
|
25
|
-
* @private
|
26
|
-
*/
|
27
|
-
class MessageEvent extends Event {
|
28
|
-
/**
|
29
|
-
* Create a new `MessageEvent`.
|
30
|
-
*
|
31
|
-
* @param {(String|Buffer|ArrayBuffer)} data The received data
|
32
|
-
* @param {Boolean} isBinary Specifies if `data` is binary
|
33
|
-
* @param {WebSocket} target A reference to the target to which the event was dispatched
|
34
|
-
*/
|
35
|
-
constructor (data, isBinary, target) {
|
36
|
-
super('message', target);
|
37
|
-
|
38
|
-
this.binary = isBinary; // non-standard.
|
39
|
-
this.data = data;
|
40
|
-
}
|
41
|
-
}
|
42
|
-
|
43
|
-
/**
|
44
|
-
* Class representing a close event.
|
45
|
-
*
|
46
|
-
* @extends Event
|
47
|
-
* @private
|
48
|
-
*/
|
49
|
-
class CloseEvent extends Event {
|
50
|
-
/**
|
51
|
-
* Create a new `CloseEvent`.
|
52
|
-
*
|
53
|
-
* @param {Number} code The status code explaining why the connection is being closed
|
54
|
-
* @param {String} reason A human-readable string explaining why the connection is closing
|
55
|
-
* @param {WebSocket} target A reference to the target to which the event was dispatched
|
56
|
-
*/
|
57
|
-
constructor (code, reason, target) {
|
58
|
-
super('close', target);
|
59
|
-
|
60
|
-
this.wasClean = code === undefined || code === 1000;
|
61
|
-
this.reason = reason;
|
62
|
-
this.target = target;
|
63
|
-
this.type = 'close';
|
64
|
-
this.code = code;
|
65
|
-
}
|
66
|
-
}
|
67
|
-
|
68
|
-
/**
|
69
|
-
* Class representing an open event.
|
70
|
-
*
|
71
|
-
* @extends Event
|
72
|
-
* @private
|
73
|
-
*/
|
74
|
-
class OpenEvent extends Event {
|
75
|
-
/**
|
76
|
-
* Create a new `OpenEvent`.
|
77
|
-
*
|
78
|
-
* @param {WebSocket} target A reference to the target to which the event was dispatched
|
79
|
-
*/
|
80
|
-
constructor (target) {
|
81
|
-
super('open', target);
|
82
|
-
}
|
83
|
-
}
|
84
|
-
|
85
|
-
/**
|
86
|
-
* This provides methods for emulating the `EventTarget` interface. It's not
|
87
|
-
* meant to be used directly.
|
88
|
-
*
|
89
|
-
* @mixin
|
90
|
-
*/
|
91
|
-
const EventTarget = {
|
92
|
-
/**
|
93
|
-
* Register an event listener.
|
94
|
-
*
|
95
|
-
* @param {String} method A string representing the event type to listen for
|
96
|
-
* @param {Function} listener The listener to add
|
97
|
-
* @public
|
98
|
-
*/
|
99
|
-
addEventListener (method, listener) {
|
100
|
-
if (typeof listener !== 'function') return;
|
101
|
-
|
102
|
-
function onMessage (data, flags) {
|
103
|
-
if (flags.binary && this.binaryType === 'arraybuffer') {
|
104
|
-
data = new Uint8Array(data).buffer;
|
105
|
-
}
|
106
|
-
listener.call(this, new MessageEvent(data, !!flags.binary, this));
|
107
|
-
}
|
108
|
-
|
109
|
-
function onClose (code, message) {
|
110
|
-
listener.call(this, new CloseEvent(code, message, this));
|
111
|
-
}
|
112
|
-
|
113
|
-
function onError (event) {
|
114
|
-
event.type = 'error';
|
115
|
-
event.target = this;
|
116
|
-
listener.call(this, event);
|
117
|
-
}
|
118
|
-
|
119
|
-
function onOpen () {
|
120
|
-
listener.call(this, new OpenEvent(this));
|
121
|
-
}
|
122
|
-
|
123
|
-
if (method === 'message') {
|
124
|
-
onMessage._listener = listener;
|
125
|
-
this.on(method, onMessage);
|
126
|
-
} else if (method === 'close') {
|
127
|
-
onClose._listener = listener;
|
128
|
-
this.on(method, onClose);
|
129
|
-
} else if (method === 'error') {
|
130
|
-
onError._listener = listener;
|
131
|
-
this.on(method, onError);
|
132
|
-
} else if (method === 'open') {
|
133
|
-
onOpen._listener = listener;
|
134
|
-
this.on(method, onOpen);
|
135
|
-
} else {
|
136
|
-
this.on(method, listener);
|
137
|
-
}
|
138
|
-
},
|
139
|
-
|
140
|
-
/**
|
141
|
-
* Remove an event listener.
|
142
|
-
*
|
143
|
-
* @param {String} method A string representing the event type to remove
|
144
|
-
* @param {Function} listener The listener to remove
|
145
|
-
* @public
|
146
|
-
*/
|
147
|
-
removeEventListener (method, listener) {
|
148
|
-
const listeners = this.listeners(method);
|
149
|
-
|
150
|
-
for (var i = 0; i < listeners.length; i++) {
|
151
|
-
if (listeners[i] === listener || listeners[i]._listener === listener) {
|
152
|
-
this.removeListener(method, listeners[i]);
|
153
|
-
}
|
154
|
-
}
|
155
|
-
}
|
156
|
-
};
|
157
|
-
|
158
|
-
module.exports = EventTarget;
|
@@ -1,69 +0,0 @@
|
|
1
|
-
'use strict';
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Module exports.
|
5
|
-
*/
|
6
|
-
|
7
|
-
exports.parse = parse;
|
8
|
-
exports.format = format;
|
9
|
-
|
10
|
-
/**
|
11
|
-
* Parse extensions header value
|
12
|
-
*/
|
13
|
-
|
14
|
-
function parse (value) {
|
15
|
-
value = value || '';
|
16
|
-
|
17
|
-
var extensions = {};
|
18
|
-
|
19
|
-
value.split(',').forEach(function (v) {
|
20
|
-
var params = v.split(';');
|
21
|
-
var token = params.shift().trim();
|
22
|
-
var paramsList = extensions[token] = extensions[token] || [];
|
23
|
-
var parsedParams = {};
|
24
|
-
|
25
|
-
params.forEach(function (param) {
|
26
|
-
var parts = param.trim().split('=');
|
27
|
-
var key = parts[0];
|
28
|
-
var value = parts[1];
|
29
|
-
if (value === undefined) {
|
30
|
-
value = true;
|
31
|
-
} else {
|
32
|
-
// unquote value
|
33
|
-
if (value[0] === '"') {
|
34
|
-
value = value.slice(1);
|
35
|
-
}
|
36
|
-
if (value[value.length - 1] === '"') {
|
37
|
-
value = value.slice(0, value.length - 1);
|
38
|
-
}
|
39
|
-
}
|
40
|
-
(parsedParams[key] = parsedParams[key] || []).push(value);
|
41
|
-
});
|
42
|
-
|
43
|
-
paramsList.push(parsedParams);
|
44
|
-
});
|
45
|
-
|
46
|
-
return extensions;
|
47
|
-
}
|
48
|
-
|
49
|
-
/**
|
50
|
-
* Format extensions header value
|
51
|
-
*/
|
52
|
-
|
53
|
-
function format (value) {
|
54
|
-
return Object.keys(value).map(function (token) {
|
55
|
-
var paramsList = value[token];
|
56
|
-
if (!Array.isArray(paramsList)) {
|
57
|
-
paramsList = [paramsList];
|
58
|
-
}
|
59
|
-
return paramsList.map(function (params) {
|
60
|
-
return [token].concat(Object.keys(params).map(function (k) {
|
61
|
-
var p = params[k];
|
62
|
-
if (!Array.isArray(p)) p = [p];
|
63
|
-
return p.map(function (v) {
|
64
|
-
return v === true ? k : k + '=' + v;
|
65
|
-
}).join('; ');
|
66
|
-
})).join('; ');
|
67
|
-
}).join(', ');
|
68
|
-
}).join(', ');
|
69
|
-
}
|
@@ -1,339 +0,0 @@
|
|
1
|
-
'use strict';
|
2
|
-
|
3
|
-
const zlib = require('zlib');
|
4
|
-
|
5
|
-
const AVAILABLE_WINDOW_BITS = [8, 9, 10, 11, 12, 13, 14, 15];
|
6
|
-
const DEFAULT_WINDOW_BITS = 15;
|
7
|
-
const DEFAULT_MEM_LEVEL = 8;
|
8
|
-
const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
|
9
|
-
const EMPTY_BLOCK = Buffer.from([0x00]);
|
10
|
-
|
11
|
-
/**
|
12
|
-
* Per-message Compression Extensions implementation
|
13
|
-
*/
|
14
|
-
class PerMessageDeflate {
|
15
|
-
constructor (options, isServer, maxPayload) {
|
16
|
-
this._options = options || {};
|
17
|
-
this._isServer = !!isServer;
|
18
|
-
this._inflate = null;
|
19
|
-
this._deflate = null;
|
20
|
-
this.params = null;
|
21
|
-
this._maxPayload = maxPayload || 0;
|
22
|
-
this.threshold = this._options.threshold === undefined ? 1024 : this._options.threshold;
|
23
|
-
}
|
24
|
-
|
25
|
-
/**
|
26
|
-
* Create extension parameters offer
|
27
|
-
*
|
28
|
-
* @api public
|
29
|
-
*/
|
30
|
-
|
31
|
-
offer () {
|
32
|
-
var params = {};
|
33
|
-
if (this._options.serverNoContextTakeover) {
|
34
|
-
params.server_no_context_takeover = true;
|
35
|
-
}
|
36
|
-
if (this._options.clientNoContextTakeover) {
|
37
|
-
params.client_no_context_takeover = true;
|
38
|
-
}
|
39
|
-
if (this._options.serverMaxWindowBits) {
|
40
|
-
params.server_max_window_bits = this._options.serverMaxWindowBits;
|
41
|
-
}
|
42
|
-
if (this._options.clientMaxWindowBits) {
|
43
|
-
params.client_max_window_bits = this._options.clientMaxWindowBits;
|
44
|
-
} else if (this._options.clientMaxWindowBits == null) {
|
45
|
-
params.client_max_window_bits = true;
|
46
|
-
}
|
47
|
-
return params;
|
48
|
-
}
|
49
|
-
|
50
|
-
/**
|
51
|
-
* Accept extension offer
|
52
|
-
*
|
53
|
-
* @api public
|
54
|
-
*/
|
55
|
-
accept (paramsList) {
|
56
|
-
paramsList = this.normalizeParams(paramsList);
|
57
|
-
|
58
|
-
var params;
|
59
|
-
if (this._isServer) {
|
60
|
-
params = this.acceptAsServer(paramsList);
|
61
|
-
} else {
|
62
|
-
params = this.acceptAsClient(paramsList);
|
63
|
-
}
|
64
|
-
|
65
|
-
this.params = params;
|
66
|
-
return params;
|
67
|
-
}
|
68
|
-
|
69
|
-
/**
|
70
|
-
* Releases all resources used by the extension
|
71
|
-
*
|
72
|
-
* @api public
|
73
|
-
*/
|
74
|
-
cleanup () {
|
75
|
-
if (this._inflate) {
|
76
|
-
if (this._inflate.writeInProgress) {
|
77
|
-
this._inflate.pendingClose = true;
|
78
|
-
} else {
|
79
|
-
this._inflate.close();
|
80
|
-
this._inflate = null;
|
81
|
-
}
|
82
|
-
}
|
83
|
-
if (this._deflate) {
|
84
|
-
if (this._deflate.writeInProgress) {
|
85
|
-
this._deflate.pendingClose = true;
|
86
|
-
} else {
|
87
|
-
this._deflate.close();
|
88
|
-
this._deflate = null;
|
89
|
-
}
|
90
|
-
}
|
91
|
-
}
|
92
|
-
|
93
|
-
/**
|
94
|
-
* Accept extension offer from client
|
95
|
-
*
|
96
|
-
* @api private
|
97
|
-
*/
|
98
|
-
|
99
|
-
acceptAsServer (paramsList) {
|
100
|
-
var accepted = {};
|
101
|
-
var result = paramsList.some((params) => {
|
102
|
-
accepted = {};
|
103
|
-
if (this._options.serverNoContextTakeover === false && params.server_no_context_takeover) {
|
104
|
-
return;
|
105
|
-
}
|
106
|
-
if (this._options.serverMaxWindowBits === false && params.server_max_window_bits) {
|
107
|
-
return;
|
108
|
-
}
|
109
|
-
if (typeof this._options.serverMaxWindowBits === 'number' &&
|
110
|
-
typeof params.server_max_window_bits === 'number' &&
|
111
|
-
this._options.serverMaxWindowBits > params.server_max_window_bits) {
|
112
|
-
return;
|
113
|
-
}
|
114
|
-
if (typeof this._options.clientMaxWindowBits === 'number' && !params.client_max_window_bits) {
|
115
|
-
return;
|
116
|
-
}
|
117
|
-
|
118
|
-
if (this._options.serverNoContextTakeover || params.server_no_context_takeover) {
|
119
|
-
accepted.server_no_context_takeover = true;
|
120
|
-
}
|
121
|
-
if (this._options.clientNoContextTakeover) {
|
122
|
-
accepted.client_no_context_takeover = true;
|
123
|
-
}
|
124
|
-
if (this._options.clientNoContextTakeover !== false && params.client_no_context_takeover) {
|
125
|
-
accepted.client_no_context_takeover = true;
|
126
|
-
}
|
127
|
-
if (typeof this._options.serverMaxWindowBits === 'number') {
|
128
|
-
accepted.server_max_window_bits = this._options.serverMaxWindowBits;
|
129
|
-
} else if (typeof params.server_max_window_bits === 'number') {
|
130
|
-
accepted.server_max_window_bits = params.server_max_window_bits;
|
131
|
-
}
|
132
|
-
if (typeof this._options.clientMaxWindowBits === 'number') {
|
133
|
-
accepted.client_max_window_bits = this._options.clientMaxWindowBits;
|
134
|
-
} else if (this._options.clientMaxWindowBits !== false && typeof params.client_max_window_bits === 'number') {
|
135
|
-
accepted.client_max_window_bits = params.client_max_window_bits;
|
136
|
-
}
|
137
|
-
return true;
|
138
|
-
});
|
139
|
-
|
140
|
-
if (!result) {
|
141
|
-
throw new Error(`Doesn't support the offered configuration`);
|
142
|
-
}
|
143
|
-
|
144
|
-
return accepted;
|
145
|
-
}
|
146
|
-
|
147
|
-
/**
|
148
|
-
* Accept extension response from server
|
149
|
-
*
|
150
|
-
* @api privaye
|
151
|
-
*/
|
152
|
-
|
153
|
-
acceptAsClient (paramsList) {
|
154
|
-
var params = paramsList[0];
|
155
|
-
if (this._options.clientNoContextTakeover != null) {
|
156
|
-
if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) {
|
157
|
-
throw new Error('Invalid value for "client_no_context_takeover"');
|
158
|
-
}
|
159
|
-
}
|
160
|
-
if (this._options.clientMaxWindowBits != null) {
|
161
|
-
if (this._options.clientMaxWindowBits === false && params.client_max_window_bits) {
|
162
|
-
throw new Error('Invalid value for "client_max_window_bits"');
|
163
|
-
}
|
164
|
-
if (typeof this._options.clientMaxWindowBits === 'number' &&
|
165
|
-
(!params.client_max_window_bits || params.client_max_window_bits > this._options.clientMaxWindowBits)) {
|
166
|
-
throw new Error('Invalid value for "client_max_window_bits"');
|
167
|
-
}
|
168
|
-
}
|
169
|
-
return params;
|
170
|
-
}
|
171
|
-
|
172
|
-
/**
|
173
|
-
* Normalize extensions parameters
|
174
|
-
*
|
175
|
-
* @api private
|
176
|
-
*/
|
177
|
-
|
178
|
-
normalizeParams (paramsList) {
|
179
|
-
return paramsList.map((params) => {
|
180
|
-
Object.keys(params).forEach((key) => {
|
181
|
-
var value = params[key];
|
182
|
-
if (value.length > 1) {
|
183
|
-
throw new Error('Multiple extension parameters for ' + key);
|
184
|
-
}
|
185
|
-
|
186
|
-
value = value[0];
|
187
|
-
|
188
|
-
switch (key) {
|
189
|
-
case 'server_no_context_takeover':
|
190
|
-
case 'client_no_context_takeover':
|
191
|
-
if (value !== true) {
|
192
|
-
throw new Error(`invalid extension parameter value for ${key} (${value})`);
|
193
|
-
}
|
194
|
-
params[key] = true;
|
195
|
-
break;
|
196
|
-
case 'server_max_window_bits':
|
197
|
-
case 'client_max_window_bits':
|
198
|
-
if (typeof value === 'string') {
|
199
|
-
value = parseInt(value, 10);
|
200
|
-
if (!~AVAILABLE_WINDOW_BITS.indexOf(value)) {
|
201
|
-
throw new Error(`invalid extension parameter value for ${key} (${value})`);
|
202
|
-
}
|
203
|
-
}
|
204
|
-
if (!this._isServer && value === true) {
|
205
|
-
throw new Error(`Missing extension parameter value for ${key}`);
|
206
|
-
}
|
207
|
-
params[key] = value;
|
208
|
-
break;
|
209
|
-
default:
|
210
|
-
throw new Error(`Not defined extension parameter (${key})`);
|
211
|
-
}
|
212
|
-
});
|
213
|
-
return params;
|
214
|
-
});
|
215
|
-
}
|
216
|
-
|
217
|
-
/**
|
218
|
-
* Decompress data.
|
219
|
-
*
|
220
|
-
* @param {Buffer} data Compressed data
|
221
|
-
* @param {Boolean} fin Specifies whether or not this is the last fragment
|
222
|
-
* @param {Function} callback Callback
|
223
|
-
* @public
|
224
|
-
*/
|
225
|
-
decompress (data, fin, callback) {
|
226
|
-
const endpoint = this._isServer ? 'client' : 'server';
|
227
|
-
|
228
|
-
if (!this._inflate) {
|
229
|
-
const maxWindowBits = this.params[`${endpoint}_max_window_bits`];
|
230
|
-
this._inflate = zlib.createInflateRaw({
|
231
|
-
windowBits: typeof maxWindowBits === 'number' ? maxWindowBits : DEFAULT_WINDOW_BITS
|
232
|
-
});
|
233
|
-
}
|
234
|
-
this._inflate.writeInProgress = true;
|
235
|
-
|
236
|
-
var totalLength = 0;
|
237
|
-
const buffers = [];
|
238
|
-
var err;
|
239
|
-
|
240
|
-
const onData = (data) => {
|
241
|
-
totalLength += data.length;
|
242
|
-
if (this._maxPayload < 1 || totalLength <= this._maxPayload) {
|
243
|
-
return buffers.push(data);
|
244
|
-
}
|
245
|
-
|
246
|
-
err = new Error('max payload size exceeded');
|
247
|
-
err.closeCode = 1009;
|
248
|
-
this._inflate.reset();
|
249
|
-
};
|
250
|
-
|
251
|
-
const onError = (err) => {
|
252
|
-
cleanup();
|
253
|
-
callback(err);
|
254
|
-
};
|
255
|
-
|
256
|
-
const cleanup = () => {
|
257
|
-
if (!this._inflate) return;
|
258
|
-
|
259
|
-
this._inflate.removeListener('error', onError);
|
260
|
-
this._inflate.removeListener('data', onData);
|
261
|
-
this._inflate.writeInProgress = false;
|
262
|
-
|
263
|
-
if (
|
264
|
-
fin && this.params[`${endpoint}_no_context_takeover`] ||
|
265
|
-
this._inflate.pendingClose
|
266
|
-
) {
|
267
|
-
this._inflate.close();
|
268
|
-
this._inflate = null;
|
269
|
-
}
|
270
|
-
};
|
271
|
-
|
272
|
-
this._inflate.on('error', onError).on('data', onData);
|
273
|
-
this._inflate.write(data);
|
274
|
-
if (fin) this._inflate.write(TRAILER);
|
275
|
-
|
276
|
-
this._inflate.flush(() => {
|
277
|
-
cleanup();
|
278
|
-
if (err) callback(err);
|
279
|
-
else callback(null, Buffer.concat(buffers, totalLength));
|
280
|
-
});
|
281
|
-
}
|
282
|
-
|
283
|
-
/**
|
284
|
-
* Compress message
|
285
|
-
*
|
286
|
-
* @api public
|
287
|
-
*/
|
288
|
-
|
289
|
-
compress (data, fin, callback) {
|
290
|
-
if (!data || data.length === 0) {
|
291
|
-
return callback(null, EMPTY_BLOCK);
|
292
|
-
}
|
293
|
-
|
294
|
-
var endpoint = this._isServer ? 'server' : 'client';
|
295
|
-
|
296
|
-
if (!this._deflate) {
|
297
|
-
var maxWindowBits = this.params[endpoint + '_max_window_bits'];
|
298
|
-
this._deflate = zlib.createDeflateRaw({
|
299
|
-
flush: zlib.Z_SYNC_FLUSH,
|
300
|
-
windowBits: typeof maxWindowBits === 'number' ? maxWindowBits : DEFAULT_WINDOW_BITS,
|
301
|
-
memLevel: this._options.memLevel || DEFAULT_MEM_LEVEL
|
302
|
-
});
|
303
|
-
}
|
304
|
-
this._deflate.writeInProgress = true;
|
305
|
-
|
306
|
-
const buffers = [];
|
307
|
-
|
308
|
-
const onData = (data) => buffers.push(data);
|
309
|
-
const onError = (err) => {
|
310
|
-
cleanup();
|
311
|
-
callback(err);
|
312
|
-
};
|
313
|
-
const cleanup = () => {
|
314
|
-
if (!this._deflate) return;
|
315
|
-
this._deflate.removeListener('error', onError);
|
316
|
-
this._deflate.removeListener('data', onData);
|
317
|
-
this._deflate.writeInProgress = false;
|
318
|
-
if ((fin && this.params[endpoint + '_no_context_takeover']) || this._deflate.pendingClose) {
|
319
|
-
this._deflate.close();
|
320
|
-
this._deflate = null;
|
321
|
-
}
|
322
|
-
};
|
323
|
-
|
324
|
-
this._deflate.on('error', onError).on('data', onData);
|
325
|
-
this._deflate.write(data);
|
326
|
-
this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
|
327
|
-
cleanup();
|
328
|
-
var data = Buffer.concat(buffers);
|
329
|
-
if (fin) {
|
330
|
-
data = data.slice(0, data.length - 4);
|
331
|
-
}
|
332
|
-
callback(null, data);
|
333
|
-
});
|
334
|
-
}
|
335
|
-
}
|
336
|
-
|
337
|
-
PerMessageDeflate.extensionName = 'permessage-deflate';
|
338
|
-
|
339
|
-
module.exports = PerMessageDeflate;
|