dragonfly_chrome_headless 0.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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +12 -0
- data/Gemfile +4 -0
- data/README.md +53 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/dragonfly_chrome_headless.gemspec +27 -0
- data/lib/dragonfly_chrome_headless.rb +9 -0
- data/lib/dragonfly_chrome_headless/plugin.rb +17 -0
- data/lib/dragonfly_chrome_headless/processors/rasterize.rb +33 -0
- data/lib/dragonfly_chrome_headless/version.rb +3 -0
- data/node_modules/.bin/chrome-remote-interface +1 -0
- data/node_modules/.bin/mkdirp +1 -0
- data/node_modules/.bin/rimraf +1 -0
- data/node_modules/@types/core-js/LICENSE +21 -0
- data/node_modules/@types/core-js/README.md +16 -0
- data/node_modules/@types/core-js/index.d.ts +2452 -0
- data/node_modules/@types/core-js/package.json +85 -0
- data/node_modules/@types/mkdirp/README.md +18 -0
- data/node_modules/@types/mkdirp/index.d.ts +14 -0
- data/node_modules/@types/mkdirp/package.json +77 -0
- data/node_modules/@types/mkdirp/types-metadata.json +25 -0
- data/node_modules/@types/node/README.md +16 -0
- data/node_modules/@types/node/index.d.ts +4132 -0
- data/node_modules/@types/node/package.json +84 -0
- data/node_modules/balanced-match/.npmignore +5 -0
- data/node_modules/balanced-match/LICENSE.md +21 -0
- data/node_modules/balanced-match/README.md +91 -0
- data/node_modules/balanced-match/index.js +59 -0
- data/node_modules/balanced-match/package.json +112 -0
- data/node_modules/brace-expansion/README.md +123 -0
- data/node_modules/brace-expansion/index.js +201 -0
- data/node_modules/brace-expansion/package.json +114 -0
- data/node_modules/chrome-launcher/.clang-format +6 -0
- data/node_modules/chrome-launcher/.npmignore +11 -0
- data/node_modules/chrome-launcher/README.md +123 -0
- data/node_modules/chrome-launcher/ask.js +32 -0
- data/node_modules/chrome-launcher/ask.ts +35 -0
- data/node_modules/chrome-launcher/chrome-finder.js +157 -0
- data/node_modules/chrome-launcher/chrome-finder.ts +186 -0
- data/node_modules/chrome-launcher/chrome-launcher.js +245 -0
- data/node_modules/chrome-launcher/chrome-launcher.ts +312 -0
- data/node_modules/chrome-launcher/compiled-check.js +14 -0
- data/node_modules/chrome-launcher/flags.js +27 -0
- data/node_modules/chrome-launcher/flags.ts +26 -0
- data/node_modules/chrome-launcher/index.js +7 -0
- data/node_modules/chrome-launcher/index.ts +1 -0
- data/node_modules/chrome-launcher/manual-chrome-launcher.js +30 -0
- data/node_modules/chrome-launcher/package.json +116 -0
- data/node_modules/chrome-launcher/random-port.js +24 -0
- data/node_modules/chrome-launcher/random-port.ts +23 -0
- data/node_modules/chrome-launcher/tsconfig.json +19 -0
- data/node_modules/chrome-launcher/utils.js +52 -0
- data/node_modules/chrome-launcher/utils.ts +44 -0
- data/node_modules/chrome-launcher/yarn.lock +1486 -0
- data/node_modules/chrome-remote-interface/LICENSE +18 -0
- data/node_modules/chrome-remote-interface/README.md +849 -0
- data/node_modules/chrome-remote-interface/bin/client.js +337 -0
- data/node_modules/chrome-remote-interface/chrome-remote-interface.js +11 -0
- data/node_modules/chrome-remote-interface/index.js +39 -0
- data/node_modules/chrome-remote-interface/lib/api.js +84 -0
- data/node_modules/chrome-remote-interface/lib/chrome.js +307 -0
- data/node_modules/chrome-remote-interface/lib/defaults.js +4 -0
- data/node_modules/chrome-remote-interface/lib/devtools.js +245 -0
- data/node_modules/chrome-remote-interface/lib/external-request.js +28 -0
- data/node_modules/chrome-remote-interface/lib/protocol.json +13780 -0
- data/node_modules/chrome-remote-interface/lib/websocket-wrapper.js +32 -0
- data/node_modules/chrome-remote-interface/package.json +128 -0
- data/node_modules/chrome-remote-interface/webpack.config.js +55 -0
- data/node_modules/commander/Readme.md +195 -0
- data/node_modules/commander/index.js +851 -0
- data/node_modules/commander/package.json +92 -0
- data/node_modules/concat-map/.travis.yml +4 -0
- data/node_modules/concat-map/LICENSE +18 -0
- data/node_modules/concat-map/README.markdown +62 -0
- data/node_modules/concat-map/example/map.js +6 -0
- data/node_modules/concat-map/index.js +13 -0
- data/node_modules/concat-map/package.json +117 -0
- data/node_modules/concat-map/test/map.js +39 -0
- data/node_modules/debug/.coveralls.yml +1 -0
- data/node_modules/debug/.eslintrc +11 -0
- data/node_modules/debug/.npmignore +9 -0
- data/node_modules/debug/.travis.yml +14 -0
- data/node_modules/debug/CHANGELOG.md +357 -0
- data/node_modules/debug/LICENSE +19 -0
- data/node_modules/debug/Makefile +50 -0
- data/node_modules/debug/Readme.md +312 -0
- data/node_modules/debug/component.json +19 -0
- data/node_modules/debug/karma.conf.js +70 -0
- data/node_modules/debug/node.js +1 -0
- data/node_modules/debug/package.json +124 -0
- data/node_modules/debug/src/browser.js +185 -0
- data/node_modules/debug/src/debug.js +202 -0
- data/node_modules/debug/src/index.js +10 -0
- data/node_modules/debug/src/node.js +246 -0
- data/node_modules/fs.realpath/LICENSE +43 -0
- data/node_modules/fs.realpath/README.md +33 -0
- data/node_modules/fs.realpath/index.js +66 -0
- data/node_modules/fs.realpath/old.js +303 -0
- data/node_modules/fs.realpath/package.json +94 -0
- data/node_modules/glob/LICENSE +15 -0
- data/node_modules/glob/README.md +368 -0
- data/node_modules/glob/changelog.md +67 -0
- data/node_modules/glob/common.js +240 -0
- data/node_modules/glob/glob.js +790 -0
- data/node_modules/glob/package.json +112 -0
- data/node_modules/glob/sync.js +486 -0
- data/node_modules/html-pdf-chrome/.npmignore +9 -0
- data/node_modules/html-pdf-chrome/LICENSE +21 -0
- data/node_modules/html-pdf-chrome/README.md +165 -0
- data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.d.ts +87 -0
- data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.js +4 -0
- data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.js.map +1 -0
- data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.d.ts +120 -0
- data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.js +206 -0
- data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.js.map +1 -0
- data/node_modules/html-pdf-chrome/lib/src/CreateResult.d.ts +70 -0
- data/node_modules/html-pdf-chrome/lib/src/CreateResult.js +98 -0
- data/node_modules/html-pdf-chrome/lib/src/CreateResult.js.map +1 -0
- data/node_modules/html-pdf-chrome/lib/src/index.d.ts +72 -0
- data/node_modules/html-pdf-chrome/lib/src/index.js +123 -0
- data/node_modules/html-pdf-chrome/lib/src/index.js.map +1 -0
- data/node_modules/html-pdf-chrome/package.json +133 -0
- data/node_modules/html-pdf-chrome/src/ChromePrintOptions.ts +99 -0
- data/node_modules/html-pdf-chrome/src/CompletionTrigger.ts +201 -0
- data/node_modules/html-pdf-chrome/src/CreateResult.ts +100 -0
- data/node_modules/html-pdf-chrome/src/index.ts +179 -0
- data/node_modules/inflight/LICENSE +15 -0
- data/node_modules/inflight/README.md +37 -0
- data/node_modules/inflight/inflight.js +54 -0
- data/node_modules/inflight/package.json +105 -0
- data/node_modules/inherits/LICENSE +16 -0
- data/node_modules/inherits/README.md +42 -0
- data/node_modules/inherits/inherits.js +7 -0
- data/node_modules/inherits/inherits_browser.js +23 -0
- data/node_modules/inherits/package.json +97 -0
- data/node_modules/lighthouse-logger/README.md +4 -0
- data/node_modules/lighthouse-logger/index.js +212 -0
- data/node_modules/lighthouse-logger/package.json +69 -0
- data/node_modules/lighthouse-logger/yarn.lock +13 -0
- data/node_modules/minimatch/LICENSE +15 -0
- data/node_modules/minimatch/README.md +209 -0
- data/node_modules/minimatch/minimatch.js +923 -0
- data/node_modules/minimatch/package.json +99 -0
- data/node_modules/minimist/.travis.yml +4 -0
- data/node_modules/minimist/LICENSE +18 -0
- data/node_modules/minimist/example/parse.js +2 -0
- data/node_modules/minimist/index.js +187 -0
- data/node_modules/minimist/package.json +101 -0
- data/node_modules/minimist/readme.markdown +73 -0
- data/node_modules/minimist/test/dash.js +24 -0
- data/node_modules/minimist/test/default_bool.js +20 -0
- data/node_modules/minimist/test/dotted.js +16 -0
- data/node_modules/minimist/test/long.js +31 -0
- data/node_modules/minimist/test/parse.js +318 -0
- data/node_modules/minimist/test/parse_modified.js +9 -0
- data/node_modules/minimist/test/short.js +67 -0
- data/node_modules/minimist/test/whitespace.js +8 -0
- data/node_modules/mkdirp/.travis.yml +8 -0
- data/node_modules/mkdirp/LICENSE +21 -0
- data/node_modules/mkdirp/bin/cmd.js +33 -0
- data/node_modules/mkdirp/bin/usage.txt +12 -0
- data/node_modules/mkdirp/examples/pow.js +6 -0
- data/node_modules/mkdirp/index.js +98 -0
- data/node_modules/mkdirp/package.json +93 -0
- data/node_modules/mkdirp/readme.markdown +100 -0
- data/node_modules/mkdirp/test/chmod.js +41 -0
- data/node_modules/mkdirp/test/clobber.js +38 -0
- data/node_modules/mkdirp/test/mkdirp.js +28 -0
- data/node_modules/mkdirp/test/opts_fs.js +29 -0
- data/node_modules/mkdirp/test/opts_fs_sync.js +27 -0
- data/node_modules/mkdirp/test/perm.js +32 -0
- data/node_modules/mkdirp/test/perm_sync.js +36 -0
- data/node_modules/mkdirp/test/race.js +37 -0
- data/node_modules/mkdirp/test/rel.js +32 -0
- data/node_modules/mkdirp/test/return.js +25 -0
- data/node_modules/mkdirp/test/return_sync.js +24 -0
- data/node_modules/mkdirp/test/root.js +19 -0
- data/node_modules/mkdirp/test/sync.js +32 -0
- data/node_modules/mkdirp/test/umask.js +28 -0
- data/node_modules/mkdirp/test/umask_sync.js +32 -0
- data/node_modules/ms/README.md +51 -0
- data/node_modules/ms/index.js +152 -0
- data/node_modules/ms/license.md +21 -0
- data/node_modules/ms/package.json +109 -0
- data/node_modules/once/LICENSE +15 -0
- data/node_modules/once/README.md +79 -0
- data/node_modules/once/once.js +42 -0
- data/node_modules/once/package.json +101 -0
- data/node_modules/path-is-absolute/index.js +20 -0
- data/node_modules/path-is-absolute/license +21 -0
- data/node_modules/path-is-absolute/package.json +111 -0
- data/node_modules/path-is-absolute/readme.md +59 -0
- data/node_modules/rimraf/LICENSE +15 -0
- data/node_modules/rimraf/README.md +101 -0
- data/node_modules/rimraf/bin.js +50 -0
- data/node_modules/rimraf/package.json +99 -0
- data/node_modules/rimraf/rimraf.js +363 -0
- data/node_modules/ultron/LICENSE +22 -0
- data/node_modules/ultron/index.js +138 -0
- data/node_modules/ultron/package.json +112 -0
- data/node_modules/wrappy/LICENSE +15 -0
- data/node_modules/wrappy/README.md +36 -0
- data/node_modules/wrappy/package.json +97 -0
- data/node_modules/wrappy/wrappy.js +33 -0
- data/node_modules/ws/LICENSE +21 -0
- data/node_modules/ws/README.md +259 -0
- data/node_modules/ws/SECURITY.md +33 -0
- data/node_modules/ws/index.js +15 -0
- data/node_modules/ws/lib/BufferUtil.fallback.js +56 -0
- data/node_modules/ws/lib/BufferUtil.js +15 -0
- data/node_modules/ws/lib/ErrorCodes.js +28 -0
- data/node_modules/ws/lib/EventTarget.js +158 -0
- data/node_modules/ws/lib/Extensions.js +69 -0
- data/node_modules/ws/lib/PerMessageDeflate.js +339 -0
- data/node_modules/ws/lib/Receiver.js +520 -0
- data/node_modules/ws/lib/Sender.js +438 -0
- data/node_modules/ws/lib/Validation.fallback.js +9 -0
- data/node_modules/ws/lib/Validation.js +17 -0
- data/node_modules/ws/lib/WebSocket.js +705 -0
- data/node_modules/ws/lib/WebSocketServer.js +336 -0
- data/node_modules/ws/package.json +122 -0
- data/package.json +26 -0
- data/samples/sample.html +13 -0
- data/script/rasterize.js +18 -0
- metadata +325 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Security Guidelines
|
|
2
|
+
|
|
3
|
+
Please contact us directly at **security@3rd-Eden.com** for any bug that might
|
|
4
|
+
impact the security of this project. Please prefix the subject of your email
|
|
5
|
+
with `[security]` in lowercase and square brackets. Our email filters will
|
|
6
|
+
automatically prevent these messages from being moved to our spam box.
|
|
7
|
+
|
|
8
|
+
You will receive an acknowledgement of your report within **24 hours**.
|
|
9
|
+
|
|
10
|
+
All emails that do not include security vulnerabilities will be removed and
|
|
11
|
+
blocked instantly.
|
|
12
|
+
|
|
13
|
+
## Exceptions
|
|
14
|
+
|
|
15
|
+
If you do not receive an acknowledgement within the said time frame please give
|
|
16
|
+
us the benefit of the doubt as it's possible that we haven't seen it yet. In
|
|
17
|
+
this case please send us a message **without details** using one of the
|
|
18
|
+
following methods:
|
|
19
|
+
|
|
20
|
+
- Contact the lead developers of this project on their personal e-mails. You
|
|
21
|
+
can find the e-mails in the git logs, for example using the following command:
|
|
22
|
+
`git --no-pager show -s --format='%an <%ae>' <gitsha>` where `<gitsha>` is the
|
|
23
|
+
SHA1 of their latest commit in the project.
|
|
24
|
+
- Create a GitHub issue stating contact details and the severity of the issue.
|
|
25
|
+
|
|
26
|
+
Once we have acknowledged receipt of your report and confirmed the bug
|
|
27
|
+
ourselves we will work with you to fix the vulnerability and publicly acknowledge
|
|
28
|
+
your responsible disclosure, if you wish. In addition to that we will report
|
|
29
|
+
all vulnerabilities to the [Node Security Project](https://nodesecurity.io/).
|
|
30
|
+
|
|
31
|
+
## History
|
|
32
|
+
|
|
33
|
+
04 Jan 2016: [Buffer vulnerablity](https://github.com/websockets/ws/releases/tag/1.0.1)
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
const WebSocket = require('./lib/WebSocket');
|
|
10
|
+
|
|
11
|
+
WebSocket.Server = require('./lib/WebSocketServer');
|
|
12
|
+
WebSocket.Receiver = require('./lib/Receiver');
|
|
13
|
+
WebSocket.Sender = require('./lib/Sender');
|
|
14
|
+
|
|
15
|
+
module.exports = WebSocket;
|
|
@@ -0,0 +1,56 @@
|
|
|
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 };
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
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;
|
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
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;
|