update node

This commit is contained in:
olevole
2021-10-17 01:15:13 +03:00
parent 35782af048
commit a268022aca
27 changed files with 795 additions and 1428 deletions

2
node/node_modules/async-limiter/.eslintignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
coverage
.nyc_output

10
node/node_modules/async-limiter/.nycrc generated vendored Normal file
View File

@@ -0,0 +1,10 @@
{
"check-coverage": false,
"lines": 99,
"statements": 99,
"functions": 99,
"branches": 99,
"include": [
"index.js"
]
}

View File

@@ -1,6 +1,8 @@
language: node_js
node_js:
- "6"
- "8"
- "10"
- "node"
script: npm run travis
cache:

View File

@@ -1 +0,0 @@
{"/Users/samuelreed/git/forks/async-throttle/index.js":{"path":"/Users/samuelreed/git/forks/async-throttle/index.js","s":{"1":1,"2":7,"3":1,"4":6,"5":6,"6":6,"7":6,"8":6,"9":6,"10":1,"11":1,"12":3,"13":13,"14":13,"15":13,"16":1,"17":19,"18":1,"19":45,"20":6,"21":39,"22":13,"23":13,"24":13,"25":13,"26":39,"27":18,"28":6,"29":6,"30":1,"31":6,"32":6,"33":6,"34":1,"35":13,"36":13,"37":1},"b":{"1":[1,6],"2":[6,5],"3":[6,5],"4":[6,39],"5":[13,26],"6":[18,21],"7":[6,0]},"f":{"1":7,"2":3,"3":13,"4":19,"5":45,"6":6,"7":13},"fnMap":{"1":{"name":"Queue","line":3,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":24}}},"2":{"name":"(anonymous_2)","line":22,"loc":{"start":{"line":22,"column":24},"end":{"line":22,"column":41}}},"3":{"name":"(anonymous_3)","line":23,"loc":{"start":{"line":23,"column":28},"end":{"line":23,"column":39}}},"4":{"name":"(anonymous_4)","line":31,"loc":{"start":{"line":31,"column":7},"end":{"line":31,"column":18}}},"5":{"name":"(anonymous_5)","line":36,"loc":{"start":{"line":36,"column":23},"end":{"line":36,"column":34}}},"6":{"name":"(anonymous_6)","line":55,"loc":{"start":{"line":55,"column":25},"end":{"line":55,"column":38}}},"7":{"name":"done","line":62,"loc":{"start":{"line":62,"column":0},"end":{"line":62,"column":16}}}},"statementMap":{"1":{"start":{"line":3,"column":0},"end":{"line":14,"column":1}},"2":{"start":{"line":4,"column":2},"end":{"line":6,"column":3}},"3":{"start":{"line":5,"column":4},"end":{"line":5,"column":30}},"4":{"start":{"line":8,"column":2},"end":{"line":8,"column":26}},"5":{"start":{"line":9,"column":2},"end":{"line":9,"column":53}},"6":{"start":{"line":10,"column":2},"end":{"line":10,"column":19}},"7":{"start":{"line":11,"column":2},"end":{"line":11,"column":17}},"8":{"start":{"line":12,"column":2},"end":{"line":12,"column":16}},"9":{"start":{"line":13,"column":2},"end":{"line":13,"column":31}},"10":{"start":{"line":16,"column":0},"end":{"line":20,"column":2}},"11":{"start":{"line":22,"column":0},"end":{"line":28,"column":3}},"12":{"start":{"line":23,"column":2},"end":{"line":27,"column":4}},"13":{"start":{"line":24,"column":4},"end":{"line":24,"column":75}},"14":{"start":{"line":25,"column":4},"end":{"line":25,"column":16}},"15":{"start":{"line":26,"column":4},"end":{"line":26,"column":24}},"16":{"start":{"line":30,"column":0},"end":{"line":34,"column":3}},"17":{"start":{"line":32,"column":4},"end":{"line":32,"column":43}},"18":{"start":{"line":36,"column":0},"end":{"line":53,"column":2}},"19":{"start":{"line":37,"column":2},"end":{"line":39,"column":3}},"20":{"start":{"line":38,"column":4},"end":{"line":38,"column":11}},"21":{"start":{"line":40,"column":2},"end":{"line":45,"column":3}},"22":{"start":{"line":41,"column":4},"end":{"line":41,"column":32}},"23":{"start":{"line":42,"column":4},"end":{"line":42,"column":19}},"24":{"start":{"line":43,"column":4},"end":{"line":43,"column":20}},"25":{"start":{"line":44,"column":4},"end":{"line":44,"column":16}},"26":{"start":{"line":47,"column":2},"end":{"line":52,"column":3}},"27":{"start":{"line":48,"column":4},"end":{"line":51,"column":5}},"28":{"start":{"line":49,"column":6},"end":{"line":49,"column":30}},"29":{"start":{"line":50,"column":6},"end":{"line":50,"column":27}},"30":{"start":{"line":55,"column":0},"end":{"line":60,"column":2}},"31":{"start":{"line":56,"column":2},"end":{"line":59,"column":3}},"32":{"start":{"line":57,"column":4},"end":{"line":57,"column":22}},"33":{"start":{"line":58,"column":4},"end":{"line":58,"column":16}},"34":{"start":{"line":62,"column":0},"end":{"line":65,"column":1}},"35":{"start":{"line":63,"column":2},"end":{"line":63,"column":17}},"36":{"start":{"line":64,"column":2},"end":{"line":64,"column":14}},"37":{"start":{"line":67,"column":0},"end":{"line":67,"column":23}}},"branchMap":{"1":{"line":4,"type":"if","locations":[{"start":{"line":4,"column":2},"end":{"line":4,"column":2}},{"start":{"line":4,"column":2},"end":{"line":4,"column":2}}]},"2":{"line":8,"type":"binary-expr","locations":[{"start":{"line":8,"column":12},"end":{"line":8,"column":19}},{"start":{"line":8,"column":23},"end":{"line":8,"column":25}}]},"3":{"line":9,"type":"binary-expr","locations":[{"start":{"line":9,"column":21},"end":{"line":9,"column":40}},{"start":{"line":9,"column":44},"end":{"line":9,"column":52}}]},"4":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":37,"column":2}},{"start":{"line":37,"column":2},"end":{"line":37,"column":2}}]},"5":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":40,"column":2}},{"start":{"line":40,"column":2},"end":{"line":40,"column":2}}]},"6":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":2},"end":{"line":47,"column":2}},{"start":{"line":47,"column":2},"end":{"line":47,"column":2}}]},"7":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":56,"column":2}},{"start":{"line":56,"column":2},"end":{"line":56,"column":2}}]}}}}

View File

@@ -1,73 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for async-throttle/</title>
<meta charset="utf-8">
<link rel="stylesheet" href="../prettify.css">
<link rel="stylesheet" href="../base.css">
<style type='text/css'>
div.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class="header high">
<h1>Code coverage report for <span class="entity">async-throttle/</span></h1>
<h2>
Statements: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Branches: <span class="metric">92.86% <small>(13 / 14)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Functions: <span class="metric">100% <small>(7 / 7)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Lines: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Ignored: <span class="metric"><span class="ignore-none">none</span></span> &nbsp;&nbsp;&nbsp;&nbsp;
</h2>
<div class="path"><a href="../index.html">All files</a> &#187; async-throttle/</div>
</div>
<div class="body">
<div class="coverage-summary">
<table>
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody><tr>
<td class="file high" data-value="index.js"><a href="index.js.html">index.js</a></td>
<td data-value="100" class="pic high"><span class="cover-fill cover-full" style="width: 100px;"></span><span class="cover-empty" style="width:0px;"></span></td>
<td data-value="100" class="pct high">100%</td>
<td data-value="37" class="abs high">(37&nbsp;/&nbsp;37)</td>
<td data-value="92.86" class="pct high">92.86%</td>
<td data-value="14" class="abs high">(13&nbsp;/&nbsp;14)</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="7" class="abs high">(7&nbsp;/&nbsp;7)</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="37" class="abs high">(37&nbsp;/&nbsp;37)</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="footer">
<div class="meta">Generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Mon Sep 11 2017 11:14:14 GMT-0500 (CDT)</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>

View File

@@ -1,246 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for async-throttle/index.js</title>
<meta charset="utf-8">
<link rel="stylesheet" href="../prettify.css">
<link rel="stylesheet" href="../base.css">
<style type='text/css'>
div.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class="header high">
<h1>Code coverage report for <span class="entity">async-throttle/index.js</span></h1>
<h2>
Statements: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Branches: <span class="metric">92.86% <small>(13 / 14)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Functions: <span class="metric">100% <small>(7 / 7)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Lines: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Ignored: <span class="metric"><span class="ignore-none">none</span></span> &nbsp;&nbsp;&nbsp;&nbsp;
</h2>
<div class="path"><a href="../index.html">All files</a> &#187; <a href="index.html">async-throttle/</a> &#187; index.js</div>
</div>
<div class="body">
<pre><table class="coverage">
<tr><td class="line-count">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68</td><td class="line-coverage"><span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">7</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">3</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">19</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">45</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">39</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">39</span>
<span class="cline-any cline-yes">18</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">'use strict';
&nbsp;
function Queue(options) {
if (!(this instanceof Queue)) {
return new Queue(options);
}
&nbsp;
options = options || {};
this.concurrency = options.concurrency || Infinity;
this.pending = 0;
this.jobs = [];
this.cbs = [];
this._done = done.bind(this);
}
&nbsp;
var arrayAddMethods = [
'push',
'unshift',
'splice'
];
&nbsp;
arrayAddMethods.forEach(function(method) {
Queue.prototype[method] = function() {
var methodResult = Array.prototype[method].apply(this.jobs, arguments);
this._run();
return methodResult;
};
});
&nbsp;
Object.defineProperty(Queue.prototype, 'length', {
get: function() {
return this.pending + this.jobs.length;
}
});
&nbsp;
Queue.prototype._run = function() {
if (this.pending === this.concurrency) {
return;
}
if (this.jobs.length) {
var job = this.jobs.shift();
this.pending++;
job(this._done);
this._run();
}
&nbsp;
if (this.pending === 0) {
while (this.cbs.length !== 0) {
var cb = this.cbs.pop();
process.nextTick(cb);
}
}
};
&nbsp;
Queue.prototype.onDone = function(cb) {
<span class="missing-if-branch" title="else path not taken" >E</span>if (typeof cb === 'function') {
this.cbs.push(cb);
this._run();
}
};
&nbsp;
function done() {
this.pending--;
this._run();
}
&nbsp;
module.exports = Queue;
&nbsp;</pre></td></tr>
</table></pre>
</div>
<div class="footer">
<div class="meta">Generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Mon Sep 11 2017 11:14:14 GMT-0500 (CDT)</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>

View File

@@ -1,182 +0,0 @@
body, html {
margin:0; padding: 0;
}
body {
font-family: Helvetica Neue, Helvetica,Arial;
font-size: 10pt;
}
div.header, div.footer {
background: #eee;
padding: 1em;
}
div.header {
z-index: 100;
position: fixed;
top: 0;
border-bottom: 1px solid #666;
width: 100%;
}
div.footer {
border-top: 1px solid #666;
}
div.body {
margin-top: 10em;
}
div.meta {
font-size: 90%;
text-align: center;
}
h1, h2, h3 {
font-weight: normal;
}
h1 {
font-size: 12pt;
}
h2 {
font-size: 10pt;
}
pre {
font-family: Consolas, Menlo, Monaco, monospace;
margin: 0;
padding: 0;
line-height: 1.3;
font-size: 14px;
-moz-tab-size: 2;
-o-tab-size: 2;
tab-size: 2;
}
div.path { font-size: 110%; }
div.path a:link, div.path a:visited { color: #000; }
table.coverage { border-collapse: collapse; margin:0; padding: 0 }
table.coverage td {
margin: 0;
padding: 0;
color: #111;
vertical-align: top;
}
table.coverage td.line-count {
width: 50px;
text-align: right;
padding-right: 5px;
}
table.coverage td.line-coverage {
color: #777 !important;
text-align: right;
border-left: 1px solid #666;
border-right: 1px solid #666;
}
table.coverage td.text {
}
table.coverage td span.cline-any {
display: inline-block;
padding: 0 5px;
width: 40px;
}
table.coverage td span.cline-neutral {
background: #eee;
}
table.coverage td span.cline-yes {
background: #b5d592;
color: #999;
}
table.coverage td span.cline-no {
background: #fc8c84;
}
.cstat-yes { color: #111; }
.cstat-no { background: #fc8c84; color: #111; }
.fstat-no { background: #ffc520; color: #111 !important; }
.cbranch-no { background: yellow !important; color: #111; }
.cstat-skip { background: #ddd; color: #111; }
.fstat-skip { background: #ddd; color: #111 !important; }
.cbranch-skip { background: #ddd !important; color: #111; }
.missing-if-branch {
display: inline-block;
margin-right: 10px;
position: relative;
padding: 0 4px;
background: black;
color: yellow;
}
.skip-if-branch {
display: none;
margin-right: 10px;
position: relative;
padding: 0 4px;
background: #ccc;
color: white;
}
.missing-if-branch .typ, .skip-if-branch .typ {
color: inherit !important;
}
.entity, .metric { font-weight: bold; }
.metric { display: inline-block; border: 1px solid #333; padding: 0.3em; background: white; }
.metric small { font-size: 80%; font-weight: normal; color: #666; }
div.coverage-summary table { border-collapse: collapse; margin: 3em; font-size: 110%; }
div.coverage-summary td, div.coverage-summary table th { margin: 0; padding: 0.25em 1em; border-top: 1px solid #666; border-bottom: 1px solid #666; }
div.coverage-summary th { text-align: left; border: 1px solid #666; background: #eee; font-weight: normal; }
div.coverage-summary th.file { border-right: none !important; }
div.coverage-summary th.pic { border-left: none !important; text-align: right; }
div.coverage-summary th.pct { border-right: none !important; }
div.coverage-summary th.abs { border-left: none !important; text-align: right; }
div.coverage-summary td.pct { text-align: right; border-left: 1px solid #666; }
div.coverage-summary td.abs { text-align: right; font-size: 90%; color: #444; border-right: 1px solid #666; }
div.coverage-summary td.file { border-left: 1px solid #666; white-space: nowrap; }
div.coverage-summary td.pic { min-width: 120px !important; }
div.coverage-summary a:link { text-decoration: none; color: #000; }
div.coverage-summary a:visited { text-decoration: none; color: #777; }
div.coverage-summary a:hover { text-decoration: underline; }
div.coverage-summary tfoot td { border-top: 1px solid #666; }
div.coverage-summary .sorter {
height: 10px;
width: 7px;
display: inline-block;
margin-left: 0.5em;
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
}
div.coverage-summary .sorted .sorter {
background-position: 0 -20px;
}
div.coverage-summary .sorted-desc .sorter {
background-position: 0 -10px;
}
.high { background: #b5d592 !important; }
.medium { background: #ffe87c !important; }
.low { background: #fc8c84 !important; }
span.cover-fill, span.cover-empty {
display:inline-block;
border:1px solid #444;
background: white;
height: 12px;
}
span.cover-fill {
background: #ccc;
border-right: 1px solid #444;
}
span.cover-empty {
background: white;
border-left: none;
}
span.cover-full {
border-right: none !important;
}
pre.prettyprint {
border: none !important;
padding: 0 !important;
margin: 0 !important;
}
.com { color: #999 !important; }
.ignore-none { color: #999; font-weight: normal; }

View File

@@ -1,73 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for All files</title>
<meta charset="utf-8">
<link rel="stylesheet" href="prettify.css">
<link rel="stylesheet" href="base.css">
<style type='text/css'>
div.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class="header high">
<h1>Code coverage report for <span class="entity">All files</span></h1>
<h2>
Statements: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Branches: <span class="metric">92.86% <small>(13 / 14)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Functions: <span class="metric">100% <small>(7 / 7)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Lines: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Ignored: <span class="metric"><span class="ignore-none">none</span></span> &nbsp;&nbsp;&nbsp;&nbsp;
</h2>
<div class="path"></div>
</div>
<div class="body">
<div class="coverage-summary">
<table>
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody><tr>
<td class="file high" data-value="async-throttle/"><a href="async-throttle/index.html">async-throttle/</a></td>
<td data-value="100" class="pic high"><span class="cover-fill cover-full" style="width: 100px;"></span><span class="cover-empty" style="width:0px;"></span></td>
<td data-value="100" class="pct high">100%</td>
<td data-value="37" class="abs high">(37&nbsp;/&nbsp;37)</td>
<td data-value="92.86" class="pct high">92.86%</td>
<td data-value="14" class="abs high">(13&nbsp;/&nbsp;14)</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="7" class="abs high">(7&nbsp;/&nbsp;7)</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="37" class="abs high">(37&nbsp;/&nbsp;37)</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="footer">
<div class="meta">Generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Mon Sep 11 2017 11:14:14 GMT-0500 (CDT)</div>
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="sorter.js"></script>
</body>
</html>

View File

@@ -1 +0,0 @@
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

View File

@@ -1,156 +0,0 @@
var addSorting = (function () {
"use strict";
var cols,
currentSort = {
index: 0,
desc: false
};
// returns the summary table element
function getTable() { return document.querySelector('.coverage-summary table'); }
// returns the thead element of the summary table
function getTableHeader() { return getTable().querySelector('thead tr'); }
// returns the tbody element of the summary table
function getTableBody() { return getTable().querySelector('tbody'); }
// returns the th element for nth column
function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
// loads all columns
function loadColumns() {
var colNodes = getTableHeader().querySelectorAll('th'),
colNode,
cols = [],
col,
i;
for (i = 0; i < colNodes.length; i += 1) {
colNode = colNodes[i];
col = {
key: colNode.getAttribute('data-col'),
sortable: !colNode.getAttribute('data-nosort'),
type: colNode.getAttribute('data-type') || 'string'
};
cols.push(col);
if (col.sortable) {
col.defaultDescSort = col.type === 'number';
colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
}
}
return cols;
}
// attaches a data attribute to every tr element with an object
// of data values keyed by column name
function loadRowData(tableRow) {
var tableCols = tableRow.querySelectorAll('td'),
colNode,
col,
data = {},
i,
val;
for (i = 0; i < tableCols.length; i += 1) {
colNode = tableCols[i];
col = cols[i];
val = colNode.getAttribute('data-value');
if (col.type === 'number') {
val = Number(val);
}
data[col.key] = val;
}
return data;
}
// loads all row data
function loadData() {
var rows = getTableBody().querySelectorAll('tr'),
i;
for (i = 0; i < rows.length; i += 1) {
rows[i].data = loadRowData(rows[i]);
}
}
// sorts the table using the data for the ith column
function sortByIndex(index, desc) {
var key = cols[index].key,
sorter = function (a, b) {
a = a.data[key];
b = b.data[key];
return a < b ? -1 : a > b ? 1 : 0;
},
finalSorter = sorter,
tableBody = document.querySelector('.coverage-summary tbody'),
rowNodes = tableBody.querySelectorAll('tr'),
rows = [],
i;
if (desc) {
finalSorter = function (a, b) {
return -1 * sorter(a, b);
};
}
for (i = 0; i < rowNodes.length; i += 1) {
rows.push(rowNodes[i]);
tableBody.removeChild(rowNodes[i]);
}
rows.sort(finalSorter);
for (i = 0; i < rows.length; i += 1) {
tableBody.appendChild(rows[i]);
}
}
// removes sort indicators for current column being sorted
function removeSortIndicators() {
var col = getNthColumn(currentSort.index),
cls = col.className;
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
col.className = cls;
}
// adds sort indicators for current column being sorted
function addSortIndicators() {
getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
}
// adds event listeners for all sorter widgets
function enableUI() {
var i,
el,
ithSorter = function ithSorter(i) {
var col = cols[i];
return function () {
var desc = col.defaultDescSort;
if (currentSort.index === i) {
desc = !currentSort.desc;
}
sortByIndex(i, desc);
removeSortIndicators();
currentSort.index = i;
currentSort.desc = desc;
addSortIndicators();
};
};
for (i =0 ; i < cols.length; i += 1) {
if (cols[i].sortable) {
el = getNthColumn(i).querySelector('.sorter');
if (el.addEventListener) {
el.addEventListener('click', ithSorter(i));
} else {
el.attachEvent('onclick', ithSorter(i));
}
}
}
}
// adds sorting functionality to the UI
return function () {
if (!getTable()) {
return;
}
cols = loadColumns();
loadData(cols);
addSortIndicators();
enableUI();
};
})();
window.addEventListener('load', addSorting);

View File

@@ -1,74 +0,0 @@
TN:
SF:/Users/samuelreed/git/forks/async-throttle/index.js
FN:3,Queue
FN:22,(anonymous_2)
FN:23,(anonymous_3)
FN:31,(anonymous_4)
FN:36,(anonymous_5)
FN:55,(anonymous_6)
FN:62,done
FNF:7
FNH:7
FNDA:7,Queue
FNDA:3,(anonymous_2)
FNDA:13,(anonymous_3)
FNDA:19,(anonymous_4)
FNDA:45,(anonymous_5)
FNDA:6,(anonymous_6)
FNDA:13,done
DA:3,1
DA:4,7
DA:5,1
DA:8,6
DA:9,6
DA:10,6
DA:11,6
DA:12,6
DA:13,6
DA:16,1
DA:22,1
DA:23,3
DA:24,13
DA:25,13
DA:26,13
DA:30,1
DA:32,19
DA:36,1
DA:37,45
DA:38,6
DA:40,39
DA:41,13
DA:42,13
DA:43,13
DA:44,13
DA:47,39
DA:48,18
DA:49,6
DA:50,6
DA:55,1
DA:56,6
DA:57,6
DA:58,6
DA:62,1
DA:63,13
DA:64,13
DA:67,1
LF:37
LH:37
BRDA:4,1,0,1
BRDA:4,1,1,6
BRDA:8,2,0,6
BRDA:8,2,1,5
BRDA:9,3,0,6
BRDA:9,3,1,5
BRDA:37,4,0,6
BRDA:37,4,1,39
BRDA:40,5,0,13
BRDA:40,5,1,26
BRDA:47,6,0,18
BRDA:47,6,1,21
BRDA:56,7,0,6
BRDA:56,7,1,0
BRF:14
BRH:13
end_of_record

View File

@@ -1,45 +1,48 @@
{
"_from": "async-limiter@~1.0.0",
"_id": "async-limiter@1.0.0",
"_args": [
[
"async-limiter@1.0.1",
"/usr/local/www/clonos/node"
]
],
"_from": "async-limiter@1.0.1",
"_id": "async-limiter@1.0.1",
"_inBundle": false,
"_integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
"_integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
"_location": "/async-limiter",
"_phantomChildren": {},
"_requested": {
"type": "range",
"type": "version",
"registry": true,
"raw": "async-limiter@~1.0.0",
"raw": "async-limiter@1.0.1",
"name": "async-limiter",
"escapedName": "async-limiter",
"rawSpec": "~1.0.0",
"rawSpec": "1.0.1",
"saveSpec": null,
"fetchSpec": "~1.0.0"
"fetchSpec": "1.0.1"
},
"_requiredBy": [
"/ws"
],
"_resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"_shasum": "78faed8c3d074ab81f22b4e985d79e8738f720f8",
"_spec": "async-limiter@~1.0.0",
"_where": "/usr/home/web/cp/clonos/node/node_modules/ws",
"_resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"_spec": "1.0.1",
"_where": "/usr/local/www/clonos/node",
"author": {
"name": "Samuel Reed"
},
"bugs": {
"url": "https://github.com/strml/async-limiter/issues"
},
"bundleDependencies": false,
"dependencies": {},
"deprecated": false,
"description": "asynchronous function queue with adjustable concurrency",
"devDependencies": {
"coveralls": "^2.11.2",
"eslint": "^4.6.1",
"eslint-plugin-mocha": "^4.11.0",
"coveralls": "^3.0.3",
"eslint": "^5.16.0",
"eslint-plugin-mocha": "^5.3.0",
"intelli-espower-loader": "^1.0.1",
"istanbul": "^0.3.2",
"mocha": "^3.5.2",
"power-assert": "^1.4.4"
"mocha": "^6.1.4",
"nyc": "^14.1.1",
"power-assert": "^1.6.1"
},
"homepage": "https://github.com/strml/async-limiter#readme",
"keywords": [
@@ -59,11 +62,11 @@
"url": "git+https://github.com/strml/async-limiter.git"
},
"scripts": {
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls",
"coverage": "nyc npm test && nyc report --reporter=text-lcov | coveralls",
"example": "node example",
"lint": "eslint .",
"test": "mocha --R intelli-espower-loader test/",
"travis": "npm run lint && npm run coverage"
"test": "mocha --require intelli-espower-loader test/",
"travis": "npm run lint && npm run test"
},
"version": "1.0.0"
"version": "1.0.1"
}

View File

@@ -93,7 +93,7 @@ console.time('deflate');
for(let i = 0; i < 30000; ++i) {
deflate(payload, function (err, buffer) {});
}
q.onDone(function() {
t.onDone(function() {
console.timeEnd('deflate');
});
```
@@ -110,23 +110,23 @@ q.onDone(function() {
### `var t = new Limiter([opts])`
Constructor. `opts` may contain inital values for:
* `q.concurrency`
* `t.concurrency`
## Instance methods
### `q.onDone(fn)`
### `t.onDone(fn)`
`fn` will be called once and only once, when the queue is empty.
## Instance methods mixed in from `Array`
Mozilla has docs on how these methods work [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).
### `q.push(element1, ..., elementN)`
### `q.unshift(element1, ..., elementN)`
### `q.splice(index , howMany[, element1[, ...[, elementN]]])`
### `t.push(element1, ..., elementN)`
### `t.unshift(element1, ..., elementN)`
### `t.splice(index , howMany[, element1[, ...[, elementN]]])`
## Properties
### `q.concurrency`
### `t.concurrency`
Max number of jobs the queue should process concurrently, defaults to `Infinity`.
### `q.length`
### `t.length`
Jobs pending + jobs to process (readonly).

158
node/node_modules/ws/README.md generated vendored
View File

@@ -1,12 +1,12 @@
# ws: a Node.js WebSocket library
[![Version npm](https://img.shields.io/npm/v/ws.svg)](https://www.npmjs.com/package/ws)
[![Linux Build](https://img.shields.io/travis/websockets/ws/master.svg)](https://travis-ci.org/websockets/ws)
[![Windows Build](https://ci.appveyor.com/api/projects/status/github/websockets/ws?branch=master&svg=true)](https://ci.appveyor.com/project/lpinca/ws)
[![Coverage Status](https://img.shields.io/coveralls/websockets/ws/master.svg)](https://coveralls.io/r/websockets/ws?branch=master)
[![Version npm](https://img.shields.io/npm/v/ws.svg?logo=npm)](https://www.npmjs.com/package/ws)
[![Linux Build](https://img.shields.io/travis/websockets/ws/master.svg?logo=travis)](https://travis-ci.org/websockets/ws)
[![Windows Build](https://img.shields.io/appveyor/ci/lpinca/ws/master.svg?logo=appveyor)](https://ci.appveyor.com/project/lpinca/ws)
[![Coverage Status](https://img.shields.io/coveralls/websockets/ws/master.svg)](https://coveralls.io/github/websockets/ws)
ws is a simple to use, blazing fast, and thoroughly tested WebSocket client
and server implementation.
ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and
server implementation.
Passes the quite extensive Autobahn test suite: [server][server-report],
[client][client-report].
@@ -14,44 +14,45 @@ Passes the quite extensive Autobahn test suite: [server][server-report],
**Note**: This module does not work in the browser. The client in the docs is a
reference to a back end with the role of a client in the WebSocket
communication. Browser clients must use the native
[`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object.
To make the same code work seamlessly on Node.js and the browser, you can use
one of the many wrappers available on npm, like
[`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
object. To make the same code work seamlessly on Node.js and the browser, you
can use one of the many wrappers available on npm, like
[isomorphic-ws](https://github.com/heineiuo/isomorphic-ws).
## Table of Contents
* [Protocol support](#protocol-support)
* [Installing](#installing)
+ [Opt-in for performance and spec compliance](#opt-in-for-performance-and-spec-compliance)
* [API docs](#api-docs)
* [WebSocket compression](#websocket-compression)
* [Usage examples](#usage-examples)
+ [Sending and receiving text data](#sending-and-receiving-text-data)
+ [Sending binary data](#sending-binary-data)
+ [Simple server](#simple-server)
+ [External HTTP/S server](#external-https-server)
+ [Multiple servers sharing a single HTTP/S server](#multiple-servers-sharing-a-single-https-server)
+ [Server broadcast](#server-broadcast)
+ [echo.websocket.org demo](#echowebsocketorg-demo)
+ [Other examples](#other-examples)
* [Error handling best practices](#error-handling-best-practices)
* [FAQ](#faq)
+ [How to get the IP address of the client?](#how-to-get-the-ip-address-of-the-client)
+ [How to detect and close broken connections?](#how-to-detect-and-close-broken-connections)
+ [How to connect via a proxy?](#how-to-connect-via-a-proxy)
* [Changelog](#changelog)
* [License](#license)
- [Protocol support](#protocol-support)
- [Installing](#installing)
- [Opt-in for performance and spec compliance](#opt-in-for-performance-and-spec-compliance)
- [API docs](#api-docs)
- [WebSocket compression](#websocket-compression)
- [Usage examples](#usage-examples)
- [Sending and receiving text data](#sending-and-receiving-text-data)
- [Sending binary data](#sending-binary-data)
- [Simple server](#simple-server)
- [External HTTP/S server](#external-https-server)
- [Multiple servers sharing a single HTTP/S server](#multiple-servers-sharing-a-single-https-server)
- [Server broadcast](#server-broadcast)
- [echo.websocket.org demo](#echowebsocketorg-demo)
- [Other examples](#other-examples)
- [Error handling best practices](#error-handling-best-practices)
- [FAQ](#faq)
- [How to get the IP address of the client?](#how-to-get-the-ip-address-of-the-client)
- [How to detect and close broken connections?](#how-to-detect-and-close-broken-connections)
- [How to connect via a proxy?](#how-to-connect-via-a-proxy)
- [Changelog](#changelog)
- [License](#license)
## Protocol support
* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`)
* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`)
- **HyBi drafts 07-12** (Use the option `protocolVersion: 8`)
- **HyBi drafts 13-17** (Current default, alternatively option
`protocolVersion: 13`)
## Installing
```
npm install --save ws
npm install ws
```
### Opt-in for performance and spec compliance
@@ -64,8 +65,8 @@ necessarily need to have a C++ compiler installed on your machine.
- `npm install --save-optional bufferutil`: Allows to efficiently perform
operations such as masking and unmasking the data payload of the WebSocket
frames.
- `npm install --save-optional utf-8-validate`: Allows to efficiently check
if a message contains valid UTF-8 as required by the spec.
- `npm install --save-optional utf-8-validate`: Allows to efficiently check if a
message contains valid UTF-8 as required by the spec.
## API docs
@@ -73,21 +74,20 @@ See [`/doc/ws.md`](./doc/ws.md) for Node.js-like docs for the ws classes.
## WebSocket compression
ws supports the [permessage-deflate extension][permessage-deflate] which
enables the client and server to negotiate a compression algorithm and its
parameters, and then selectively apply it to the data payloads of each
WebSocket message.
ws supports the [permessage-deflate extension][permessage-deflate] which enables
the client and server to negotiate a compression algorithm and its parameters,
and then selectively apply it to the data payloads of each WebSocket message.
The extension is disabled by default on the server and enabled by default on
the client. It adds a significant overhead in terms of performance and memory
The extension is disabled by default on the server and enabled by default on the
client. It adds a significant overhead in terms of performance and memory
consumption so we suggest to enable it only if it is really needed.
Note that Node.js has a variety of issues with high-performance compression,
where increased concurrency, especially on Linux, can lead to
[catastrophic memory fragmentation][node-zlib-bug] and slow performance.
If you intend to use permessage-deflate in production, it is worthwhile to set
up a test representative of your workload and ensure Node.js/zlib will handle
it with acceptable performance and memory usage.
where increased concurrency, especially on Linux, can lead to [catastrophic
memory fragmentation][node-zlib-bug] and slow performance. If you intend to use
permessage-deflate in production, it is worthwhile to set up a test
representative of your workload and ensure Node.js/zlib will handle it with
acceptable performance and memory usage.
Tuning of permessage-deflate can be done via the options defined below. You can
also use `zlibDeflateOptions` and `zlibInflateOptions`, which is passed directly
@@ -101,10 +101,11 @@ const WebSocket = require('ws');
const wss = new WebSocket.Server({
port: 8080,
perMessageDeflate: {
zlibDeflateOptions: { // See zlib defaults.
zlibDeflateOptions: {
// See zlib defaults.
chunkSize: 1024,
memLevel: 7,
level: 3,
level: 3
},
zlibInflateOptions: {
chunkSize: 10 * 1024
@@ -112,12 +113,11 @@ const wss = new WebSocket.Server({
// Other options settable:
clientNoContextTakeover: true, // Defaults to negotiated value.
serverNoContextTakeover: true, // Defaults to negotiated value.
clientMaxWindowBits: 10, // Defaults to negotiated value.
serverMaxWindowBits: 10, // Defaults to negotiated value.
serverMaxWindowBits: 10, // Defaults to negotiated value.
// Below options specified as default values.
concurrencyLimit: 10, // Limits zlib concurrency for perf.
threshold: 1024, // Size (in bytes) below which messages
// should not be compressed.
concurrencyLimit: 10, // Limits zlib concurrency for perf.
threshold: 1024 // Size (in bytes) below which messages
// should not be compressed.
}
});
```
@@ -326,8 +326,11 @@ ws.send('something', function ack(error) {
// Immediate errors can also be handled with `try...catch`, but **note** that
// since sends are inherently asynchronous, socket write failures will *not* be
// captured when this technique is used.
try { ws.send('something'); }
catch (e) { /* handle error */ }
try {
ws.send('something');
} catch (e) {
/* handle error */
}
```
## FAQ
@@ -357,8 +360,8 @@ wss.on('connection', function connection(ws, req) {
### How to detect and close broken connections?
Sometimes the link between the server and the client can be interrupted in a
way that keeps both the server and the client unaware of the broken state of the
Sometimes the link between the server and the client can be interrupted in a way
that keeps both the server and the client unaware of the broken state of the
connection (e.g. when pulling the cord).
In these cases ping messages can be used as a means to verify that the remote
@@ -367,14 +370,14 @@ endpoint is still responsive.
```js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
function noop() {}
function heartbeat() {
this.isAlive = true;
}
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.isAlive = true;
ws.on('pong', heartbeat);
@@ -390,8 +393,35 @@ const interval = setInterval(function ping() {
}, 30000);
```
Pong messages are automatically sent in response to ping messages as required
by the spec.
Pong messages are automatically sent in response to ping messages as required by
the spec.
Just like the server example above your clients might as well lose connection
without knowing it. You might want to add a ping listener on your clients to
prevent that. A simple implementation would be:
```js
const WebSocket = require('ws');
function heartbeat() {
clearTimeout(this.pingTimeout);
// Use `WebSocket#terminate()` and not `WebSocket#close()`. Delay should be
// equal to the interval at which your server sends out pings plus a
// conservative assumption of the latency.
this.pingTimeout = setTimeout(() => {
this.terminate();
}, 30000 + 1000);
}
const client = new WebSocket('wss://echo.websocket.org/');
client.on('open', heartbeat);
client.on('ping', heartbeat);
client.on('close', function clear() {
clearTimeout(this.pingTimeout);
});
```
### How to connect via a proxy?
@@ -413,5 +443,7 @@ We're using the GitHub [releases][changelog] for changelog entries.
[permessage-deflate]: https://tools.ietf.org/html/rfc7692
[changelog]: https://github.com/websockets/ws/releases
[node-zlib-bug]: https://github.com/nodejs/node/issues/8871
[node-zlib-deflaterawdocs]: https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options
[ws-server-options]: https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback
[node-zlib-deflaterawdocs]:
https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options
[ws-server-options]:
https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback

2
node/node_modules/ws/browser.js generated vendored
View File

@@ -1,6 +1,6 @@
'use strict';
module.exports = function () {
module.exports = function() {
throw new Error(
'ws does not work in the browser. Browser clients must use the native ' +
'WebSocket object'

View File

@@ -1,5 +1,7 @@
'use strict';
const { EMPTY_BUFFER } = require('./constants');
/**
* Merges an array of buffers into a new buffer.
*
@@ -8,7 +10,10 @@
* @return {Buffer} The resulting buffer
* @public
*/
function concat (list, totalLength) {
function concat(list, totalLength) {
if (list.length === 0) return EMPTY_BUFFER;
if (list.length === 1) return list[0];
const target = Buffer.allocUnsafe(totalLength);
var offset = 0;
@@ -31,7 +36,7 @@ function concat (list, totalLength) {
* @param {Number} length The number of bytes to mask.
* @public
*/
function _mask (source, mask, output, offset, length) {
function _mask(source, mask, output, offset, length) {
for (var i = 0; i < length; i++) {
output[offset + i] = source[i] ^ mask[i & 3];
}
@@ -44,7 +49,7 @@ function _mask (source, mask, output, offset, length) {
* @param {Buffer} mask The mask to use
* @public
*/
function _unmask (buffer, mask) {
function _unmask(buffer, mask) {
// Required until https://github.com/nodejs/node/issues/9006 is resolved.
const length = buffer.length;
for (var i = 0; i < length; i++) {
@@ -52,21 +57,88 @@ function _unmask (buffer, mask) {
}
}
/**
* Converts a buffer to an `ArrayBuffer`.
*
* @param {Buffer} buf The buffer to convert
* @return {ArrayBuffer} Converted buffer
* @public
*/
function toArrayBuffer(buf) {
if (buf.byteLength === buf.buffer.byteLength) {
return buf.buffer;
}
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
}
/**
* Converts `data` to a `Buffer`.
*
* @param {*} data The data to convert
* @return {Buffer} The buffer
* @throws {TypeError}
* @public
*/
function toBuffer(data) {
toBuffer.readOnly = true;
if (Buffer.isBuffer(data)) return data;
var buf;
if (data instanceof ArrayBuffer) {
buf = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
buf = viewToBuffer(data);
} else {
buf = Buffer.from(data);
toBuffer.readOnly = false;
}
return buf;
}
/**
* Converts an `ArrayBuffer` view into a buffer.
*
* @param {(DataView|TypedArray)} view The view to convert
* @return {Buffer} Converted view
* @private
*/
function viewToBuffer(view) {
const buf = Buffer.from(view.buffer);
if (view.byteLength !== view.buffer.byteLength) {
return buf.slice(view.byteOffset, view.byteOffset + view.byteLength);
}
return buf;
}
try {
const bufferUtil = require('bufferutil');
const bu = bufferUtil.BufferUtil || bufferUtil;
module.exports = {
mask (source, mask, output, offset, length) {
concat,
mask(source, mask, output, offset, length) {
if (length < 48) _mask(source, mask, output, offset, length);
else bu.mask(source, mask, output, offset, length);
},
unmask (buffer, mask) {
toArrayBuffer,
toBuffer,
unmask(buffer, mask) {
if (buffer.length < 32) _unmask(buffer, mask);
else bu.unmask(buffer, mask);
},
concat
}
};
} catch (e) /* istanbul ignore next */ {
module.exports = { concat, mask: _mask, unmask: _unmask };
module.exports = {
concat,
mask: _mask,
toArrayBuffer,
toBuffer,
unmask: _unmask
};
}

View File

@@ -12,7 +12,7 @@ class Event {
* @param {String} type The name of the event
* @param {Object} target A reference to the target to which the event was dispatched
*/
constructor (type, target) {
constructor(type, target) {
this.target = target;
this.type = type;
}
@@ -31,7 +31,7 @@ class MessageEvent extends Event {
* @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data
* @param {WebSocket} target A reference to the target to which the event was dispatched
*/
constructor (data, target) {
constructor(data, target) {
super('message', target);
this.data = data;
@@ -52,7 +52,7 @@ class CloseEvent extends Event {
* @param {String} reason A human-readable string explaining why the connection is closing
* @param {WebSocket} target A reference to the target to which the event was dispatched
*/
constructor (code, reason, target) {
constructor(code, reason, target) {
super('close', target);
this.wasClean = target._closeFrameReceived && target._closeFrameSent;
@@ -73,7 +73,7 @@ class OpenEvent extends Event {
*
* @param {WebSocket} target A reference to the target to which the event was dispatched
*/
constructor (target) {
constructor(target) {
super('open', target);
}
}
@@ -91,7 +91,7 @@ class ErrorEvent extends Event {
* @param {Object} error The error that generated this event
* @param {WebSocket} target A reference to the target to which the event was dispatched
*/
constructor (error, target) {
constructor(error, target) {
super('error', target);
this.message = error.message;
@@ -113,22 +113,22 @@ const EventTarget = {
* @param {Function} listener The listener to add
* @public
*/
addEventListener (method, listener) {
addEventListener(method, listener) {
if (typeof listener !== 'function') return;
function onMessage (data) {
function onMessage(data) {
listener.call(this, new MessageEvent(data, this));
}
function onClose (code, message) {
function onClose(code, message) {
listener.call(this, new CloseEvent(code, message, this));
}
function onError (error) {
function onError(error) {
listener.call(this, new ErrorEvent(error, this));
}
function onOpen () {
function onOpen() {
listener.call(this, new OpenEvent(this));
}
@@ -156,7 +156,7 @@ const EventTarget = {
* @param {Function} listener The listener to remove
* @public
*/
removeEventListener (method, listener) {
removeEventListener(method, listener) {
const listeners = this.listeners(method);
for (var i = 0; i < listeners.length; i++) {

View File

@@ -11,6 +11,7 @@
// tokenChars[34] === 0 // '"'
// ...
//
// prettier-ignore
const tokenChars = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
@@ -32,7 +33,7 @@ const tokenChars = [
* parameter value
* @private
*/
function push (dest, name, elem) {
function push(dest, name, elem) {
if (Object.prototype.hasOwnProperty.call(dest, name)) dest[name].push(elem);
else dest[name] = [elem];
}
@@ -44,7 +45,7 @@ function push (dest, name, elem) {
* @return {Object} The parsed object
* @public
*/
function parse (header) {
function parse(header) {
const offers = {};
if (header === undefined || header === '') return offers;
@@ -64,9 +65,9 @@ function parse (header) {
if (extensionName === undefined) {
if (end === -1 && tokenChars[code] === 1) {
if (start === -1) start = i;
} else if (code === 0x20/* ' ' */|| code === 0x09/* '\t' */) {
} else if (code === 0x20 /* ' ' */ || code === 0x09 /* '\t' */) {
if (end === -1 && start !== -1) end = i;
} else if (code === 0x3b/* ';' */ || code === 0x2c/* ',' */) {
} else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {
if (start === -1) {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
@@ -103,7 +104,7 @@ function parse (header) {
}
start = end = -1;
} else if (code === 0x3d/* '=' */&& start !== -1 && end === -1) {
} else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {
paramName = header.slice(start, i);
start = end = -1;
} else {
@@ -125,10 +126,10 @@ function parse (header) {
} else if (inQuotes) {
if (tokenChars[code] === 1) {
if (start === -1) start = i;
} else if (code === 0x22/* '"' */ && start !== -1) {
} else if (code === 0x22 /* '"' */ && start !== -1) {
inQuotes = false;
end = i;
} else if (code === 0x5c/* '\' */) {
} else if (code === 0x5c /* '\' */) {
isEscaping = true;
} else {
throw new SyntaxError(`Unexpected character at index ${i}`);
@@ -194,18 +195,28 @@ function parse (header) {
* @return {String} A string representing the given object
* @public
*/
function format (extensions) {
return Object.keys(extensions).map((extension) => {
var configurations = extensions[extension];
if (!Array.isArray(configurations)) configurations = [configurations];
return configurations.map((params) => {
return [extension].concat(Object.keys(params).map((k) => {
var values = params[k];
if (!Array.isArray(values)) values = [values];
return values.map((v) => v === true ? k : `${k}=${v}`).join('; ');
})).join('; ');
}).join(', ');
}).join(', ');
function format(extensions) {
return Object.keys(extensions)
.map((extension) => {
var configurations = extensions[extension];
if (!Array.isArray(configurations)) configurations = [configurations];
return configurations
.map((params) => {
return [extension]
.concat(
Object.keys(params).map((k) => {
var values = params[k];
if (!Array.isArray(values)) values = [values];
return values
.map((v) => (v === true ? k : `${k}=${v}`))
.join('; ');
})
)
.join('; ');
})
.join(', ');
})
.join(', ');
}
module.exports = { format, parse };

View File

@@ -4,14 +4,12 @@ const Limiter = require('async-limiter');
const zlib = require('zlib');
const bufferUtil = require('./buffer-util');
const constants = require('./constants');
const { kStatusCode, NOOP } = require('./constants');
const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
const EMPTY_BLOCK = Buffer.from([0x00]);
const kPerMessageDeflate = Symbol('permessage-deflate');
const kWriteInProgress = Symbol('write-in-progress');
const kPendingClose = Symbol('pending-close');
const kTotalLength = Symbol('total-length');
const kCallback = Symbol('callback');
const kBuffers = Symbol('buffers');
@@ -52,12 +50,11 @@ class PerMessageDeflate {
* mode
* @param {Number} maxPayload The maximum allowed message length
*/
constructor (options, isServer, maxPayload) {
constructor(options, isServer, maxPayload) {
this._maxPayload = maxPayload | 0;
this._options = options || {};
this._threshold = this._options.threshold !== undefined
? this._options.threshold
: 1024;
this._threshold =
this._options.threshold !== undefined ? this._options.threshold : 1024;
this._isServer = !!isServer;
this._deflate = null;
this._inflate = null;
@@ -65,9 +62,10 @@ class PerMessageDeflate {
this.params = null;
if (!zlibLimiter) {
const concurrency = this._options.concurrencyLimit !== undefined
? this._options.concurrencyLimit
: 10;
const concurrency =
this._options.concurrencyLimit !== undefined
? this._options.concurrencyLimit
: 10;
zlibLimiter = new Limiter({ concurrency });
}
}
@@ -75,7 +73,7 @@ class PerMessageDeflate {
/**
* @type {String}
*/
static get extensionName () {
static get extensionName() {
return 'permessage-deflate';
}
@@ -85,7 +83,7 @@ class PerMessageDeflate {
* @return {Object} Extension parameters
* @public
*/
offer () {
offer() {
const params = {};
if (this._options.serverNoContextTakeover) {
@@ -113,7 +111,7 @@ class PerMessageDeflate {
* @return {Object} Accepted configuration
* @public
*/
accept (configurations) {
accept(configurations) {
configurations = this.normalizeParams(configurations);
this.params = this._isServer
@@ -128,22 +126,15 @@ class PerMessageDeflate {
*
* @public
*/
cleanup () {
cleanup() {
if (this._inflate) {
if (this._inflate[kWriteInProgress]) {
this._inflate[kPendingClose] = true;
} else {
this._inflate.close();
this._inflate = null;
}
this._inflate.close();
this._inflate = null;
}
if (this._deflate) {
if (this._deflate[kWriteInProgress]) {
this._deflate[kPendingClose] = true;
} else {
this._deflate.close();
this._deflate = null;
}
this._deflate.close();
this._deflate = null;
}
}
@@ -154,7 +145,7 @@ class PerMessageDeflate {
* @return {Object} Accepted configuration
* @private
*/
acceptAsServer (offers) {
acceptAsServer(offers) {
const opts = this._options;
const accepted = offers.find((params) => {
if (
@@ -205,7 +196,7 @@ class PerMessageDeflate {
* @return {Object} Accepted configuration
* @private
*/
acceptAsClient (response) {
acceptAsClient(response) {
const params = response[0];
if (
@@ -239,7 +230,7 @@ class PerMessageDeflate {
* @return {Array} The offers/response with normalized parameters
* @private
*/
normalizeParams (configurations) {
normalizeParams(configurations) {
configurations.forEach((params) => {
Object.keys(params).forEach((key) => {
var value = params[key];
@@ -300,7 +291,7 @@ class PerMessageDeflate {
* @param {Function} callback Callback
* @public
*/
decompress (data, fin, callback) {
decompress(data, fin, callback) {
zlibLimiter.push((done) => {
this._decompress(data, fin, (err, result) => {
done();
@@ -317,7 +308,7 @@ class PerMessageDeflate {
* @param {Function} callback Callback
* @public
*/
compress (data, fin, callback) {
compress(data, fin, callback) {
zlibLimiter.push((done) => {
this._compress(data, fin, (err, result) => {
done();
@@ -334,14 +325,15 @@ class PerMessageDeflate {
* @param {Function} callback Callback
* @private
*/
_decompress (data, fin, callback) {
_decompress(data, fin, callback) {
const endpoint = this._isServer ? 'client' : 'server';
if (!this._inflate) {
const key = `${endpoint}_max_window_bits`;
const windowBits = typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
const windowBits =
typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
this._inflate = zlib.createInflateRaw(
Object.assign({}, this._options.zlibInflateOptions, { windowBits })
@@ -354,7 +346,6 @@ class PerMessageDeflate {
}
this._inflate[kCallback] = callback;
this._inflate[kWriteInProgress] = true;
this._inflate.write(data);
if (fin) this._inflate.write(TRAILER);
@@ -374,14 +365,10 @@ class PerMessageDeflate {
this._inflate[kTotalLength]
);
if (
(fin && this.params[`${endpoint}_no_context_takeover`]) ||
this._inflate[kPendingClose]
) {
if (fin && this.params[`${endpoint}_no_context_takeover`]) {
this._inflate.close();
this._inflate = null;
} else {
this._inflate[kWriteInProgress] = false;
this._inflate[kTotalLength] = 0;
this._inflate[kBuffers] = [];
}
@@ -398,7 +385,7 @@ class PerMessageDeflate {
* @param {Function} callback Callback
* @private
*/
_compress (data, fin, callback) {
_compress(data, fin, callback) {
if (!data || data.length === 0) {
process.nextTick(callback, null, EMPTY_BLOCK);
return;
@@ -408,9 +395,10 @@ class PerMessageDeflate {
if (!this._deflate) {
const key = `${endpoint}_max_window_bits`;
const windowBits = typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
const windowBits =
typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
this._deflate = zlib.createDeflateRaw(
Object.assign({}, this._options.zlibDeflateOptions, { windowBits })
@@ -420,17 +408,27 @@ class PerMessageDeflate {
this._deflate[kBuffers] = [];
//
// `zlib.DeflateRaw` emits an `'error'` event only when an attempt to use
// it is made after it has already been closed. This cannot happen here,
// so we only add a listener for the `'data'` event.
// An `'error'` event is emitted, only on Node.js < 10.0.0, if the
// `zlib.DeflateRaw` instance is closed while data is being processed.
// This can happen if `PerMessageDeflate#cleanup()` is called at the wrong
// time due to an abnormal WebSocket closure.
//
this._deflate.on('error', NOOP);
this._deflate.on('data', deflateOnData);
}
this._deflate[kWriteInProgress] = true;
this._deflate.write(data);
this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
if (!this._deflate) {
//
// This `if` statement is only needed for Node.js < 10.0.0 because as of
// commit https://github.com/nodejs/node/commit/5e3f5164, the flush
// callback is no longer called if the deflate stream is closed while
// data is being processed.
//
return;
}
var data = bufferUtil.concat(
this._deflate[kBuffers],
this._deflate[kTotalLength]
@@ -438,14 +436,10 @@ class PerMessageDeflate {
if (fin) data = data.slice(0, data.length - 4);
if (
(fin && this.params[`${endpoint}_no_context_takeover`]) ||
this._deflate[kPendingClose]
) {
if (fin && this.params[`${endpoint}_no_context_takeover`]) {
this._deflate.close();
this._deflate = null;
} else {
this._deflate[kWriteInProgress] = false;
this._deflate[kTotalLength] = 0;
this._deflate[kBuffers] = [];
}
@@ -463,7 +457,7 @@ module.exports = PerMessageDeflate;
* @param {Buffer} chunk A chunk of data
* @private
*/
function deflateOnData (chunk) {
function deflateOnData(chunk) {
this[kBuffers].push(chunk);
this[kTotalLength] += chunk.length;
}
@@ -474,7 +468,7 @@ function deflateOnData (chunk) {
* @param {Buffer} chunk A chunk of data
* @private
*/
function inflateOnData (chunk) {
function inflateOnData(chunk) {
this[kTotalLength] += chunk.length;
if (
@@ -486,7 +480,7 @@ function inflateOnData (chunk) {
}
this[kError] = new RangeError('Max payload size exceeded');
this[kError][constants.kStatusCode] = 1009;
this[kError][kStatusCode] = 1009;
this.removeListener('data', inflateOnData);
this.reset();
}
@@ -497,12 +491,12 @@ function inflateOnData (chunk) {
* @param {Error} err The emitted error
* @private
*/
function inflateOnError (err) {
function inflateOnError(err) {
//
// There is no need to call `Zlib#close()` as the handle is automatically
// closed when an error is emitted.
//
this[kPerMessageDeflate]._inflate = null;
err[constants.kStatusCode] = 1007;
err[kStatusCode] = 1007;
this[kCallback](err);
}

111
node/node_modules/ws/lib/receiver.js generated vendored
View File

@@ -1,11 +1,16 @@
'use strict';
const stream = require('stream');
const { Writable } = require('stream');
const PerMessageDeflate = require('./permessage-deflate');
const bufferUtil = require('./buffer-util');
const validation = require('./validation');
const constants = require('./constants');
const {
BINARY_TYPES,
EMPTY_BUFFER,
kStatusCode,
kWebSocket
} = require('./constants');
const { concat, toArrayBuffer, unmask } = require('./buffer-util');
const { isValidStatusCode, isValidUTF8 } = require('./validation');
const GET_INFO = 0;
const GET_PAYLOAD_LENGTH_16 = 1;
@@ -19,7 +24,7 @@ const INFLATING = 5;
*
* @extends stream.Writable
*/
class Receiver extends stream.Writable {
class Receiver extends Writable {
/**
* Creates a Receiver instance.
*
@@ -27,11 +32,11 @@ class Receiver extends stream.Writable {
* @param {Object} extensions An object containing the negotiated extensions
* @param {Number} maxPayload The maximum allowed message length
*/
constructor (binaryType, extensions, maxPayload) {
constructor(binaryType, extensions, maxPayload) {
super();
this._binaryType = binaryType || constants.BINARY_TYPES[0];
this[constants.kWebSocket] = undefined;
this._binaryType = binaryType || BINARY_TYPES[0];
this[kWebSocket] = undefined;
this._extensions = extensions || {};
this._maxPayload = maxPayload | 0;
@@ -61,8 +66,8 @@ class Receiver extends stream.Writable {
* @param {String} encoding The character encoding of `chunk`
* @param {Function} cb Callback
*/
_write (chunk, encoding, cb) {
if (this._opcode === 0x08) return cb();
_write(chunk, encoding, cb) {
if (this._opcode === 0x08 && this._state == GET_INFO) return cb();
this._bufferedBytes += chunk.length;
this._buffers.push(chunk);
@@ -76,7 +81,7 @@ class Receiver extends stream.Writable {
* @return {Buffer} The consumed bytes
* @private
*/
consume (n) {
consume(n) {
this._bufferedBytes -= n;
if (n === this._buffers[0].length) return this._buffers.shift();
@@ -111,7 +116,7 @@ class Receiver extends stream.Writable {
* @param {Function} cb Callback
* @private
*/
startLoop (cb) {
startLoop(cb) {
var err;
this._loop = true;
@@ -132,7 +137,8 @@ class Receiver extends stream.Writable {
case GET_DATA:
err = this.getData(cb);
break;
default: // `INFLATING`
default:
// `INFLATING`
this._loop = false;
return;
}
@@ -147,7 +153,7 @@ class Receiver extends stream.Writable {
* @return {(RangeError|undefined)} A possible error
* @private
*/
getInfo () {
getInfo() {
if (this._bufferedBytes < 2) {
this._loop = false;
return;
@@ -229,7 +235,7 @@ class Receiver extends stream.Writable {
* @return {(RangeError|undefined)} A possible error
* @private
*/
getPayloadLength16 () {
getPayloadLength16() {
if (this._bufferedBytes < 2) {
this._loop = false;
return;
@@ -245,7 +251,7 @@ class Receiver extends stream.Writable {
* @return {(RangeError|undefined)} A possible error
* @private
*/
getPayloadLength64 () {
getPayloadLength64() {
if (this._bufferedBytes < 8) {
this._loop = false;
return;
@@ -278,7 +284,7 @@ class Receiver extends stream.Writable {
* @return {(RangeError|undefined)} A possible error
* @private
*/
haveLength () {
haveLength() {
if (this._payloadLength && this._opcode < 0x08) {
this._totalPayloadLength += this._payloadLength;
if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
@@ -296,7 +302,7 @@ class Receiver extends stream.Writable {
*
* @private
*/
getMask () {
getMask() {
if (this._bufferedBytes < 4) {
this._loop = false;
return;
@@ -313,8 +319,8 @@ class Receiver extends stream.Writable {
* @return {(Error|RangeError|undefined)} A possible error
* @private
*/
getData (cb) {
var data = constants.EMPTY_BUFFER;
getData(cb) {
var data = EMPTY_BUFFER;
if (this._payloadLength) {
if (this._bufferedBytes < this._payloadLength) {
@@ -323,7 +329,7 @@ class Receiver extends stream.Writable {
}
data = this.consume(this._payloadLength);
if (this._masked) bufferUtil.unmask(data, this._mask);
if (this._masked) unmask(data, this._mask);
}
if (this._opcode > 0x07) return this.controlMessage(data);
@@ -353,7 +359,7 @@ class Receiver extends stream.Writable {
* @param {Function} cb Callback
* @private
*/
decompress (data, cb) {
decompress(data, cb) {
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
perMessageDeflate.decompress(data, this._fin, (err, buf) => {
@@ -362,7 +368,9 @@ class Receiver extends stream.Writable {
if (buf.length) {
this._messageLength += buf.length;
if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
return cb(error(RangeError, 'Max payload size exceeded', false, 1009));
return cb(
error(RangeError, 'Max payload size exceeded', false, 1009)
);
}
this._fragments.push(buf);
@@ -381,7 +389,7 @@ class Receiver extends stream.Writable {
* @return {(Error|undefined)} A possible error
* @private
*/
dataMessage () {
dataMessage() {
if (this._fin) {
const messageLength = this._messageLength;
const fragments = this._fragments;
@@ -395,18 +403,18 @@ class Receiver extends stream.Writable {
var data;
if (this._binaryType === 'nodebuffer') {
data = toBuffer(fragments, messageLength);
data = concat(fragments, messageLength);
} else if (this._binaryType === 'arraybuffer') {
data = toArrayBuffer(toBuffer(fragments, messageLength));
data = toArrayBuffer(concat(fragments, messageLength));
} else {
data = fragments;
}
this.emit('message', data);
} else {
const buf = toBuffer(fragments, messageLength);
const buf = concat(fragments, messageLength);
if (!validation.isValidUTF8(buf)) {
if (!isValidUTF8(buf)) {
this._loop = false;
return error(Error, 'invalid UTF-8 sequence', true, 1007);
}
@@ -425,7 +433,7 @@ class Receiver extends stream.Writable {
* @return {(Error|RangeError|undefined)} A possible error
* @private
*/
controlMessage (data) {
controlMessage(data) {
if (this._opcode === 0x08) {
this._loop = false;
@@ -437,26 +445,25 @@ class Receiver extends stream.Writable {
} else {
const code = data.readUInt16BE(0);
if (!validation.isValidStatusCode(code)) {
if (!isValidStatusCode(code)) {
return error(RangeError, `invalid status code ${code}`, true, 1002);
}
const buf = data.slice(2);
if (!validation.isValidUTF8(buf)) {
if (!isValidUTF8(buf)) {
return error(Error, 'invalid UTF-8 sequence', true, 1007);
}
this.emit('conclude', code, buf.toString());
this.end();
}
return;
} else if (this._opcode === 0x09) {
this.emit('ping', data);
} else {
this.emit('pong', data);
}
if (this._opcode === 0x09) this.emit('ping', data);
else this.emit('pong', data);
this._state = GET_INFO;
}
}
@@ -474,40 +481,12 @@ module.exports = Receiver;
* @return {(Error|RangeError)} The error
* @private
*/
function error (ErrorCtor, message, prefix, statusCode) {
function error(ErrorCtor, message, prefix, statusCode) {
const err = new ErrorCtor(
prefix ? `Invalid WebSocket frame: ${message}` : message
);
Error.captureStackTrace(err, error);
err[constants.kStatusCode] = statusCode;
err[kStatusCode] = statusCode;
return err;
}
/**
* Makes a buffer from a list of fragments.
*
* @param {Buffer[]} fragments The list of fragments composing the message
* @param {Number} messageLength The length of the message
* @return {Buffer}
* @private
*/
function toBuffer (fragments, messageLength) {
if (fragments.length === 1) return fragments[0];
if (fragments.length > 1) return bufferUtil.concat(fragments, messageLength);
return constants.EMPTY_BUFFER;
}
/**
* Converts a buffer to an `ArrayBuffer`.
*
* @param {Buffer} The buffer to convert
* @return {ArrayBuffer} Converted buffer
*/
function toArrayBuffer (buf) {
if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
return buf.buffer;
}
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
}

207
node/node_modules/ws/lib/sender.js generated vendored
View File

@@ -1,11 +1,11 @@
'use strict';
const crypto = require('crypto');
const { randomBytes } = require('crypto');
const PerMessageDeflate = require('./permessage-deflate');
const bufferUtil = require('./buffer-util');
const validation = require('./validation');
const constants = require('./constants');
const { EMPTY_BUFFER } = require('./constants');
const { isValidStatusCode } = require('./validation');
const { mask: applyMask, toBuffer } = require('./buffer-util');
/**
* HyBi Sender implementation.
@@ -17,7 +17,7 @@ class Sender {
* @param {net.Socket} socket The connection socket
* @param {Object} extensions An object containing the negotiated extensions
*/
constructor (socket, extensions) {
constructor(socket, extensions) {
this._extensions = extensions || {};
this._socket = socket;
@@ -42,8 +42,8 @@ class Sender {
* @return {Buffer[]} The framed data as a list of `Buffer` instances
* @public
*/
static frame (data, options) {
const merge = data.length < 1024 || (options.mask && options.readOnly);
static frame(data, options) {
const merge = options.mask && options.readOnly;
var offset = options.mask ? 6 : 2;
var payloadLength = data.length;
@@ -60,6 +60,8 @@ class Sender {
target[0] = options.fin ? options.opcode | 0x80 : options.opcode;
if (options.rsv1) target[0] |= 0x40;
target[1] = payloadLength;
if (payloadLength === 126) {
target.writeUInt16BE(data.length, 2);
} else if (payloadLength === 127) {
@@ -67,30 +69,22 @@ class Sender {
target.writeUInt32BE(data.length, 6);
}
if (!options.mask) {
target[1] = payloadLength;
if (merge) {
data.copy(target, offset);
return [target];
}
if (!options.mask) return [target, data];
return [target, data];
}
const mask = randomBytes(4);
const mask = crypto.randomBytes(4);
target[1] = payloadLength | 0x80;
target[1] |= 0x80;
target[offset - 4] = mask[0];
target[offset - 3] = mask[1];
target[offset - 2] = mask[2];
target[offset - 1] = mask[3];
if (merge) {
bufferUtil.mask(data, mask, target, offset, data.length);
applyMask(data, mask, target, offset, data.length);
return [target];
}
bufferUtil.mask(data, mask, data, 0, data.length);
applyMask(data, mask, data, 0, data.length);
return [target, data];
}
@@ -103,12 +97,12 @@ class Sender {
* @param {Function} cb Callback
* @public
*/
close (code, data, mask, cb) {
close(code, data, mask, cb) {
var buf;
if (code === undefined) {
buf = constants.EMPTY_BUFFER;
} else if (typeof code !== 'number' || !validation.isValidStatusCode(code)) {
buf = EMPTY_BUFFER;
} else if (typeof code !== 'number' || !isValidStatusCode(code)) {
throw new TypeError('First argument must be a valid error code number');
} else if (data === undefined || data === '') {
buf = Buffer.allocUnsafe(2);
@@ -134,14 +128,17 @@ class Sender {
* @param {Function} cb Callback
* @private
*/
doClose (data, mask, cb) {
this.sendFrame(Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x08,
mask,
readOnly: false
}), cb);
doClose(data, mask, cb) {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x08,
mask,
readOnly: false
}),
cb
);
}
/**
@@ -152,24 +149,13 @@ class Sender {
* @param {Function} cb Callback
* @public
*/
ping (data, mask, cb) {
var readOnly = true;
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
ping(data, mask, cb) {
const buf = toBuffer(data);
if (this._deflating) {
this.enqueue([this.doPing, data, mask, readOnly, cb]);
this.enqueue([this.doPing, buf, mask, toBuffer.readOnly, cb]);
} else {
this.doPing(data, mask, readOnly, cb);
this.doPing(buf, mask, toBuffer.readOnly, cb);
}
}
@@ -182,14 +168,17 @@ class Sender {
* @param {Function} cb Callback
* @private
*/
doPing (data, mask, readOnly, cb) {
this.sendFrame(Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x09,
mask,
readOnly
}), cb);
doPing(data, mask, readOnly, cb) {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x09,
mask,
readOnly
}),
cb
);
}
/**
@@ -200,24 +189,13 @@ class Sender {
* @param {Function} cb Callback
* @public
*/
pong (data, mask, cb) {
var readOnly = true;
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
pong(data, mask, cb) {
const buf = toBuffer(data);
if (this._deflating) {
this.enqueue([this.doPong, data, mask, readOnly, cb]);
this.enqueue([this.doPong, buf, mask, toBuffer.readOnly, cb]);
} else {
this.doPong(data, mask, readOnly, cb);
this.doPong(buf, mask, toBuffer.readOnly, cb);
}
}
@@ -230,14 +208,17 @@ class Sender {
* @param {Function} cb Callback
* @private
*/
doPong (data, mask, readOnly, cb) {
this.sendFrame(Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x0a,
mask,
readOnly
}), cb);
doPong(data, mask, readOnly, cb) {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x0a,
mask,
readOnly
}),
cb
);
}
/**
@@ -252,28 +233,16 @@ class Sender {
* @param {Function} cb Callback
* @public
*/
send (data, options, cb) {
send(data, options, cb) {
const buf = toBuffer(data);
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
var opcode = options.binary ? 2 : 1;
var rsv1 = options.compress;
var readOnly = true;
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
if (this._firstFragment) {
this._firstFragment = false;
if (rsv1 && perMessageDeflate) {
rsv1 = data.length >= perMessageDeflate._threshold;
rsv1 = buf.length >= perMessageDeflate._threshold;
}
this._compress = rsv1;
} else {
@@ -289,22 +258,25 @@ class Sender {
rsv1,
opcode,
mask: options.mask,
readOnly
readOnly: toBuffer.readOnly
};
if (this._deflating) {
this.enqueue([this.dispatch, data, this._compress, opts, cb]);
this.enqueue([this.dispatch, buf, this._compress, opts, cb]);
} else {
this.dispatch(data, this._compress, opts, cb);
this.dispatch(buf, this._compress, opts, cb);
}
} else {
this.sendFrame(Sender.frame(data, {
fin: options.fin,
rsv1: false,
opcode,
mask: options.mask,
readOnly
}), cb);
this.sendFrame(
Sender.frame(buf, {
fin: options.fin,
rsv1: false,
opcode,
mask: options.mask,
readOnly: toBuffer.readOnly
}),
cb
);
}
}
@@ -322,7 +294,7 @@ class Sender {
* @param {Function} cb Callback
* @private
*/
dispatch (data, compress, options, cb) {
dispatch(data, compress, options, cb) {
if (!compress) {
this.sendFrame(Sender.frame(data, options), cb);
return;
@@ -332,9 +304,9 @@ class Sender {
this._deflating = true;
perMessageDeflate.compress(data, options.fin, (_, buf) => {
this._deflating = false;
options.readOnly = false;
this.sendFrame(Sender.frame(buf, options), cb);
this._deflating = false;
this.dequeue();
});
}
@@ -344,7 +316,7 @@ class Sender {
*
* @private
*/
dequeue () {
dequeue() {
while (!this._deflating && this._queue.length) {
const params = this._queue.shift();
@@ -359,7 +331,7 @@ class Sender {
* @param {Array} params Send operation parameters.
* @private
*/
enqueue (params) {
enqueue(params) {
this._bufferedBytes += params[1].length;
this._queue.push(params);
}
@@ -371,10 +343,12 @@ class Sender {
* @param {Function} cb Callback
* @private
*/
sendFrame (list, cb) {
sendFrame(list, cb) {
if (list.length === 2) {
this._socket.cork();
this._socket.write(list[0]);
this._socket.write(list[1], cb);
this._socket.uncork();
} else {
this._socket.write(list[0], cb);
}
@@ -382,20 +356,3 @@ class Sender {
}
module.exports = Sender;
/**
* Converts an `ArrayBuffer` view into a buffer.
*
* @param {(DataView|TypedArray)} view The view to convert
* @return {Buffer} Converted view
* @private
*/
function viewToBuffer (view) {
const buf = Buffer.from(view.buffer);
if (view.byteLength !== view.buffer.byteLength) {
return buf.slice(view.byteOffset, view.byteOffset + view.byteLength);
}
return buf;
}

View File

@@ -3,9 +3,10 @@
try {
const isValidUTF8 = require('utf-8-validate');
exports.isValidUTF8 = typeof isValidUTF8 === 'object'
? isValidUTF8.Validation.isValidUTF8 // utf-8-validate@<3.0.0
: isValidUTF8;
exports.isValidUTF8 =
typeof isValidUTF8 === 'object'
? isValidUTF8.Validation.isValidUTF8 // utf-8-validate@<3.0.0
: isValidUTF8;
} catch (e) /* istanbul ignore next */ {
exports.isValidUTF8 = () => true;
}

View File

@@ -3,12 +3,13 @@
const EventEmitter = require('events');
const crypto = require('crypto');
const http = require('http');
const url = require('url');
const PerMessageDeflate = require('./permessage-deflate');
const extension = require('./extension');
const constants = require('./constants');
const WebSocket = require('./websocket');
const { GUID } = require('./constants');
const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
/**
* Class representing a WebSocket server.
@@ -20,34 +21,41 @@ class WebSocketServer extends EventEmitter {
* Create a `WebSocketServer` instance.
*
* @param {Object} options Configuration options
* @param {Number} options.backlog The maximum length of the queue of pending
* connections
* @param {Boolean} options.clientTracking Specifies whether or not to track
* clients
* @param {Function} options.handleProtocols An hook to handle protocols
* @param {String} options.host The hostname where to bind the server
* @param {Number} options.maxPayload The maximum allowed message size
* @param {Boolean} options.noServer Enable no server mode
* @param {String} options.path Accept only connections matching this path
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable
* permessage-deflate
* @param {Number} options.port The port where to bind the server
* @param {http.Server} options.server A pre-created HTTP/S server to use
* @param {Function} options.verifyClient An hook to reject connections
* @param {Function} options.handleProtocols An hook to handle protocols
* @param {String} options.path Accept only connections matching this path
* @param {Boolean} options.noServer Enable no server mode
* @param {Boolean} options.clientTracking Specifies whether or not to track clients
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable permessage-deflate
* @param {Number} options.maxPayload The maximum allowed message size
* @param {Function} callback A listener for the `listening` event
*/
constructor (options, callback) {
constructor(options, callback) {
super();
options = Object.assign({
maxPayload: 100 * 1024 * 1024,
perMessageDeflate: false,
handleProtocols: null,
clientTracking: true,
verifyClient: null,
noServer: false,
backlog: null, // use default (511 as implemented in net.js)
server: null,
host: null,
path: null,
port: null
}, options);
options = Object.assign(
{
maxPayload: 100 * 1024 * 1024,
perMessageDeflate: false,
handleProtocols: null,
clientTracking: true,
verifyClient: null,
noServer: false,
backlog: null, // use default (511 as implemented in net.js)
server: null,
host: null,
path: null,
port: null
},
options
);
if (options.port == null && !options.server && !options.noServer) {
throw new TypeError(
@@ -65,7 +73,12 @@ class WebSocketServer extends EventEmitter {
});
res.end(body);
});
this._server.listen(options.port, options.host, options.backlog, callback);
this._server.listen(
options.port,
options.host,
options.backlog,
callback
);
} else if (options.server) {
this._server = options.server;
}
@@ -96,7 +109,7 @@ class WebSocketServer extends EventEmitter {
* @return {(Object|String|null)} The address of the server
* @public
*/
address () {
address() {
if (this.options.noServer) {
throw new Error('The server is operating in "noServer" mode');
}
@@ -111,7 +124,7 @@ class WebSocketServer extends EventEmitter {
* @param {Function} cb Callback
* @public
*/
close (cb) {
close(cb) {
if (cb) this.once('close', cb);
//
@@ -146,9 +159,12 @@ class WebSocketServer extends EventEmitter {
* @return {Boolean} `true` if the request is valid, else `false`
* @public
*/
shouldHandle (req) {
if (this.options.path && url.parse(req.url).pathname !== this.options.path) {
return false;
shouldHandle(req) {
if (this.options.path) {
const index = req.url.indexOf('?');
const pathname = index !== -1 ? req.url.slice(0, index) : req.url;
if (pathname !== this.options.path) return false;
}
return true;
@@ -163,15 +179,22 @@ class WebSocketServer extends EventEmitter {
* @param {Function} cb Callback
* @public
*/
handleUpgrade (req, socket, head, cb) {
handleUpgrade(req, socket, head, cb) {
socket.on('error', socketOnError);
const key =
req.headers['sec-websocket-key'] !== undefined
? req.headers['sec-websocket-key'].trim()
: false;
const version = +req.headers['sec-websocket-version'];
const extensions = {};
if (
req.method !== 'GET' || req.headers.upgrade.toLowerCase() !== 'websocket' ||
!req.headers['sec-websocket-key'] || (version !== 8 && version !== 13) ||
req.method !== 'GET' ||
req.headers.upgrade.toLowerCase() !== 'websocket' ||
!key ||
!keyRegex.test(key) ||
(version !== 8 && version !== 13) ||
!this.shouldHandle(req)
) {
return abortHandshake(socket, 400);
@@ -185,9 +208,7 @@ class WebSocketServer extends EventEmitter {
);
try {
const offers = extension.parse(
req.headers['sec-websocket-extensions']
);
const offers = extension.parse(req.headers['sec-websocket-extensions']);
if (offers[PerMessageDeflate.extensionName]) {
perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
@@ -203,7 +224,8 @@ class WebSocketServer extends EventEmitter {
//
if (this.options.verifyClient) {
const info = {
origin: req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
origin:
req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
secure: !!(req.connection.authorized || req.connection.encrypted),
req
};
@@ -214,7 +236,7 @@ class WebSocketServer extends EventEmitter {
return abortHandshake(socket, code || 401, message, headers);
}
this.completeUpgrade(extensions, req, socket, head, cb);
this.completeUpgrade(key, extensions, req, socket, head, cb);
});
return;
}
@@ -222,12 +244,13 @@ class WebSocketServer extends EventEmitter {
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
}
this.completeUpgrade(extensions, req, socket, head, cb);
this.completeUpgrade(key, extensions, req, socket, head, cb);
}
/**
* Upgrade the connection to WebSocket.
*
* @param {String} key The value of the `Sec-WebSocket-Key` header
* @param {Object} extensions The accepted extensions
* @param {http.IncomingMessage} req The request object
* @param {net.Socket} socket The network socket between the server and client
@@ -235,28 +258,29 @@ class WebSocketServer extends EventEmitter {
* @param {Function} cb Callback
* @private
*/
completeUpgrade (extensions, req, socket, head, cb) {
completeUpgrade(key, extensions, req, socket, head, cb) {
//
// Destroy the socket if the client has already sent a FIN packet.
//
if (!socket.readable || !socket.writable) return socket.destroy();
const key = crypto.createHash('sha1')
.update(req.headers['sec-websocket-key'] + constants.GUID, 'binary')
const digest = crypto
.createHash('sha1')
.update(key + GUID)
.digest('base64');
const headers = [
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
`Sec-WebSocket-Accept: ${key}`
`Sec-WebSocket-Accept: ${digest}`
];
const ws = new WebSocket(null);
var protocol = req.headers['sec-websocket-protocol'];
if (protocol) {
protocol = protocol.trim().split(/ *, */);
protocol = protocol.split(',').map(trim);
//
// Optionally call external protocol selection handler.
@@ -312,10 +336,10 @@ module.exports = WebSocketServer;
* @return {Function} A function that will remove the added listeners when called
* @private
*/
function addListeners (server, map) {
function addListeners(server, map) {
for (const event of Object.keys(map)) server.on(event, map[event]);
return function removeListeners () {
return function removeListeners() {
for (const event of Object.keys(map)) {
server.removeListener(event, map[event]);
}
@@ -328,7 +352,7 @@ function addListeners (server, map) {
* @param {EventEmitter} server The event emitter
* @private
*/
function emitClose (server) {
function emitClose(server) {
server.emit('close');
}
@@ -337,7 +361,7 @@ function emitClose (server) {
*
* @private
*/
function socketOnError () {
function socketOnError() {
this.destroy();
}
@@ -350,23 +374,40 @@ function socketOnError () {
* @param {Object} [headers] Additional HTTP response headers
* @private
*/
function abortHandshake (socket, code, message, headers) {
function abortHandshake(socket, code, message, headers) {
if (socket.writable) {
message = message || http.STATUS_CODES[code];
headers = Object.assign({
'Connection': 'close',
'Content-type': 'text/html',
'Content-Length': Buffer.byteLength(message)
}, headers);
headers = Object.assign(
{
Connection: 'close',
'Content-type': 'text/html',
'Content-Length': Buffer.byteLength(message)
},
headers
);
socket.write(
`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
Object.keys(headers).map(h => `${h}: ${headers[h]}`).join('\r\n') +
'\r\n\r\n' +
message
Object.keys(headers)
.map((h) => `${h}: ${headers[h]}`)
.join('\r\n') +
'\r\n\r\n' +
message
);
}
socket.removeListener('error', socketOnError);
socket.destroy();
}
/**
* Remove whitespace characters from both ends of a string.
*
* @param {String} str The string
* @return {String} A new string representing `str` stripped of whitespace
* characters from both its beginning and end
* @private
*/
function trim(str) {
return str.trim();
}

374
node/node_modules/ws/lib/websocket.js generated vendored
View File

@@ -11,14 +11,20 @@ const url = require('url');
const PerMessageDeflate = require('./permessage-deflate');
const EventTarget = require('./event-target');
const extension = require('./extension');
const constants = require('./constants');
const Receiver = require('./receiver');
const Sender = require('./sender');
const {
BINARY_TYPES,
EMPTY_BUFFER,
GUID,
kStatusCode,
kWebSocket,
NOOP
} = require('./constants');
const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
const kWebSocket = constants.kWebSocket;
const protocolVersions = [8, 13];
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly.
const closeTimeout = 30 * 1000;
/**
* Class representing a WebSocket.
@@ -33,25 +39,27 @@ class WebSocket extends EventEmitter {
* @param {(String|String[])} protocols The subprotocols
* @param {Object} options Connection options
*/
constructor (address, protocols, options) {
constructor(address, protocols, options) {
super();
this.readyState = WebSocket.CONNECTING;
this.protocol = '';
this._binaryType = constants.BINARY_TYPES[0];
this._binaryType = BINARY_TYPES[0];
this._closeFrameReceived = false;
this._closeFrameSent = false;
this._closeMessage = '';
this._closeTimer = null;
this._closeCode = 1006;
this._extensions = {};
this._isServer = true;
this._receiver = null;
this._sender = null;
this._socket = null;
if (address !== null) {
this._isServer = false;
this._redirects = 0;
if (Array.isArray(protocols)) {
protocols = protocols.join(', ');
} else if (typeof protocols === 'object' && protocols !== null) {
@@ -59,27 +67,38 @@ class WebSocket extends EventEmitter {
protocols = undefined;
}
initAsClient.call(this, address, protocols, options);
initAsClient(this, address, protocols, options);
} else {
this._isServer = true;
}
}
get CONNECTING () { return WebSocket.CONNECTING; }
get CLOSING () { return WebSocket.CLOSING; }
get CLOSED () { return WebSocket.CLOSED; }
get OPEN () { return WebSocket.OPEN; }
get CONNECTING() {
return WebSocket.CONNECTING;
}
get CLOSING() {
return WebSocket.CLOSING;
}
get CLOSED() {
return WebSocket.CLOSED;
}
get OPEN() {
return WebSocket.OPEN;
}
/**
* This deviates from the WHATWG interface since ws doesn't support the required
* default "blob" type (instead we define a custom "nodebuffer" type).
* This deviates from the WHATWG interface since ws doesn't support the
* required default "blob" type (instead we define a custom "nodebuffer"
* type).
*
* @type {String}
*/
get binaryType () {
get binaryType() {
return this._binaryType;
}
set binaryType (type) {
if (constants.BINARY_TYPES.indexOf(type) < 0) return;
set binaryType(type) {
if (!BINARY_TYPES.includes(type)) return;
this._binaryType = type;
@@ -92,7 +111,7 @@ class WebSocket extends EventEmitter {
/**
* @type {Number}
*/
get bufferedAmount () {
get bufferedAmount() {
if (!this._socket) return 0;
//
@@ -104,7 +123,7 @@ class WebSocket extends EventEmitter {
/**
* @type {String}
*/
get extensions () {
get extensions() {
return Object.keys(this._extensions).join();
}
@@ -116,7 +135,7 @@ class WebSocket extends EventEmitter {
* @param {Number} maxPayload The maximum allowed message size
* @private
*/
setSocket (socket, head, maxPayload) {
setSocket(socket, head, maxPayload) {
const receiver = new Receiver(
this._binaryType,
this._extensions,
@@ -156,7 +175,7 @@ class WebSocket extends EventEmitter {
*
* @private
*/
emitClose () {
emitClose() {
this.readyState = WebSocket.CLOSED;
if (!this._socket) {
@@ -191,7 +210,7 @@ class WebSocket extends EventEmitter {
* @param {String} data A string explaining why the connection is closing
* @public
*/
close (code, data) {
close(code, data) {
if (this.readyState === WebSocket.CLOSED) return;
if (this.readyState === WebSocket.CONNECTING) {
const msg = 'WebSocket was closed before the connection was established';
@@ -212,20 +231,16 @@ class WebSocket extends EventEmitter {
if (err) return;
this._closeFrameSent = true;
if (this._socket.writable) {
if (this._closeFrameReceived) this._socket.end();
//
// Ensure that the connection is closed even if the closing handshake
// fails.
//
this._closeTimer = setTimeout(
this._socket.destroy.bind(this._socket),
closeTimeout
);
}
if (this._closeFrameReceived) this._socket.end();
});
//
// Specify a timeout for the closing handshake to complete.
//
this._closeTimer = setTimeout(
this._socket.destroy.bind(this._socket),
closeTimeout
);
}
/**
@@ -236,7 +251,7 @@ class WebSocket extends EventEmitter {
* @param {Function} cb Callback which is executed when the ping is sent
* @public
*/
ping (data, mask, cb) {
ping(data, mask, cb) {
if (typeof data === 'function') {
cb = data;
data = mask = undefined;
@@ -257,7 +272,7 @@ class WebSocket extends EventEmitter {
if (typeof data === 'number') data = data.toString();
if (mask === undefined) mask = !this._isServer;
this._sender.ping(data || constants.EMPTY_BUFFER, mask, cb);
this._sender.ping(data || EMPTY_BUFFER, mask, cb);
}
/**
@@ -268,7 +283,7 @@ class WebSocket extends EventEmitter {
* @param {Function} cb Callback which is executed when the pong is sent
* @public
*/
pong (data, mask, cb) {
pong(data, mask, cb) {
if (typeof data === 'function') {
cb = data;
data = mask = undefined;
@@ -289,7 +304,7 @@ class WebSocket extends EventEmitter {
if (typeof data === 'number') data = data.toString();
if (mask === undefined) mask = !this._isServer;
this._sender.pong(data || constants.EMPTY_BUFFER, mask, cb);
this._sender.pong(data || EMPTY_BUFFER, mask, cb);
}
/**
@@ -304,7 +319,7 @@ class WebSocket extends EventEmitter {
* @param {Function} cb Callback which is executed when data is written out
* @public
*/
send (data, options, cb) {
send(data, options, cb) {
if (typeof options === 'function') {
cb = options;
options = {};
@@ -322,18 +337,21 @@ class WebSocket extends EventEmitter {
if (typeof data === 'number') data = data.toString();
const opts = Object.assign({
binary: typeof data !== 'string',
mask: !this._isServer,
compress: true,
fin: true
}, options);
const opts = Object.assign(
{
binary: typeof data !== 'string',
mask: !this._isServer,
compress: true,
fin: true
},
options
);
if (!this._extensions[PerMessageDeflate.extensionName]) {
opts.compress = false;
}
this._sender.send(data || constants.EMPTY_BUFFER, opts, cb);
this._sender.send(data || EMPTY_BUFFER, opts, cb);
}
/**
@@ -341,7 +359,7 @@ class WebSocket extends EventEmitter {
*
* @public
*/
terminate () {
terminate() {
if (this.readyState === WebSocket.CLOSED) return;
if (this.readyState === WebSocket.CONNECTING) {
const msg = 'WebSocket was closed before the connection was established';
@@ -356,7 +374,7 @@ class WebSocket extends EventEmitter {
}
readyStates.forEach((readyState, i) => {
WebSocket[readyStates[i]] = i;
WebSocket[readyState] = i;
});
//
@@ -371,11 +389,13 @@ readyStates.forEach((readyState, i) => {
* @return {(Function|undefined)} The event listener or `undefined`
* @public
*/
get () {
get() {
const listeners = this.listeners(method);
for (var i = 0; i < listeners.length; i++) {
if (listeners[i]._listener) return listeners[i]._listener;
}
return undefined;
},
/**
* Add a listener for the event.
@@ -383,7 +403,7 @@ readyStates.forEach((readyState, i) => {
* @param {Function} listener The listener to add
* @public
*/
set (listener) {
set(listener) {
const listeners = this.listeners(method);
for (var i = 0; i < listeners.length; i++) {
//
@@ -404,154 +424,200 @@ module.exports = WebSocket;
/**
* Initialize a WebSocket client.
*
* @param {WebSocket} websocket The client to initialize
* @param {(String|url.Url|url.URL)} address The URL to which to connect
* @param {String} protocols The subprotocols
* @param {Object} options Connection options
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable permessage-deflate
* @param {Number} options.handshakeTimeout Timeout in milliseconds for the handshake request
* @param {Number} options.protocolVersion Value of the `Sec-WebSocket-Version` header
* @param {String} options.origin Value of the `Origin` or `Sec-WebSocket-Origin` header
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable
* permessage-deflate
* @param {Number} options.handshakeTimeout Timeout in milliseconds for the
* handshake request
* @param {Number} options.protocolVersion Value of the `Sec-WebSocket-Version`
* header
* @param {String} options.origin Value of the `Origin` or
* `Sec-WebSocket-Origin` header
* @param {Number} options.maxPayload The maximum allowed message size
* @param {Boolean} options.followRedirects Whether or not to follow redirects
* @param {Number} options.maxRedirects The maximum number of redirects allowed
* @private
*/
function initAsClient (address, protocols, options) {
options = Object.assign({
protocolVersion: protocolVersions[1],
perMessageDeflate: true,
maxPayload: 100 * 1024 * 1024
}, options, {
createConnection: undefined,
socketPath: undefined,
hostname: undefined,
protocol: undefined,
timeout: undefined,
method: undefined,
auth: undefined,
host: undefined,
path: undefined,
port: undefined
});
function initAsClient(websocket, address, protocols, options) {
const opts = Object.assign(
{
protocolVersion: protocolVersions[1],
maxPayload: 100 * 1024 * 1024,
perMessageDeflate: true,
followRedirects: false,
maxRedirects: 10
},
options,
{
createConnection: undefined,
socketPath: undefined,
hostname: undefined,
protocol: undefined,
timeout: undefined,
method: undefined,
auth: undefined,
host: undefined,
path: undefined,
port: undefined
}
);
if (protocolVersions.indexOf(options.protocolVersion) === -1) {
if (!protocolVersions.includes(opts.protocolVersion)) {
throw new RangeError(
`Unsupported protocol version: ${options.protocolVersion} ` +
`Unsupported protocol version: ${opts.protocolVersion} ` +
`(supported versions: ${protocolVersions.join(', ')})`
);
}
this._isServer = false;
var parsedUrl;
if (typeof address === 'object' && address.href !== undefined) {
parsedUrl = address;
this.url = address.href;
websocket.url = address.href;
} else {
parsedUrl = url.parse(address);
this.url = address;
//
// The WHATWG URL constructor is not available on Node.js < 6.13.0
//
parsedUrl = url.URL ? new url.URL(address) : url.parse(address);
websocket.url = address;
}
const isUnixSocket = parsedUrl.protocol === 'ws+unix:';
if (!parsedUrl.host && (!isUnixSocket || !parsedUrl.pathname)) {
throw new Error(`Invalid URL: ${this.url}`);
throw new Error(`Invalid URL: ${websocket.url}`);
}
const isSecure = parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
const isSecure =
parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
const defaultPort = isSecure ? 443 : 80;
const key = crypto.randomBytes(16).toString('base64');
const httpObj = isSecure ? https : http;
const get = isSecure ? https.get : http.get;
const path = parsedUrl.search
? `${parsedUrl.pathname || '/'}${parsedUrl.search}`
: parsedUrl.pathname || '/';
var perMessageDeflate;
options.createConnection = isSecure ? tlsConnect : netConnect;
options.port = parsedUrl.port || (isSecure ? 443 : 80);
options.host = parsedUrl.hostname.startsWith('[')
opts.createConnection = isSecure ? tlsConnect : netConnect;
opts.defaultPort = opts.defaultPort || defaultPort;
opts.port = parsedUrl.port || defaultPort;
opts.host = parsedUrl.hostname.startsWith('[')
? parsedUrl.hostname.slice(1, -1)
: parsedUrl.hostname;
options.headers = Object.assign({
'Sec-WebSocket-Version': options.protocolVersion,
'Sec-WebSocket-Key': key,
'Connection': 'Upgrade',
'Upgrade': 'websocket'
}, options.headers);
options.path = path;
opts.headers = Object.assign(
{
'Sec-WebSocket-Version': opts.protocolVersion,
'Sec-WebSocket-Key': key,
Connection: 'Upgrade',
Upgrade: 'websocket'
},
opts.headers
);
opts.path = path;
opts.timeout = opts.handshakeTimeout;
if (options.perMessageDeflate) {
if (opts.perMessageDeflate) {
perMessageDeflate = new PerMessageDeflate(
options.perMessageDeflate !== true ? options.perMessageDeflate : {},
opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},
false,
options.maxPayload
opts.maxPayload
);
options.headers['Sec-WebSocket-Extensions'] = extension.format({
opts.headers['Sec-WebSocket-Extensions'] = extension.format({
[PerMessageDeflate.extensionName]: perMessageDeflate.offer()
});
}
if (protocols) {
options.headers['Sec-WebSocket-Protocol'] = protocols;
opts.headers['Sec-WebSocket-Protocol'] = protocols;
}
if (options.origin) {
if (options.protocolVersion < 13) {
options.headers['Sec-WebSocket-Origin'] = options.origin;
if (opts.origin) {
if (opts.protocolVersion < 13) {
opts.headers['Sec-WebSocket-Origin'] = opts.origin;
} else {
options.headers.Origin = options.origin;
opts.headers.Origin = opts.origin;
}
}
if (parsedUrl.auth) {
options.auth = parsedUrl.auth;
opts.auth = parsedUrl.auth;
} else if (parsedUrl.username || parsedUrl.password) {
options.auth = `${parsedUrl.username}:${parsedUrl.password}`;
opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
}
if (isUnixSocket) {
const parts = path.split(':');
options.socketPath = parts[0];
options.path = parts[1];
opts.socketPath = parts[0];
opts.path = parts[1];
}
var req = this._req = httpObj.get(options);
var req = (websocket._req = get(opts));
if (options.handshakeTimeout) {
req.setTimeout(
options.handshakeTimeout,
() => abortHandshake(this, req, 'Opening handshake has timed out')
);
if (opts.timeout) {
req.on('timeout', () => {
abortHandshake(websocket, req, 'Opening handshake has timed out');
});
}
req.on('error', (err) => {
if (this._req.aborted) return;
if (websocket._req.aborted) return;
req = this._req = null;
this.readyState = WebSocket.CLOSING;
this.emit('error', err);
this.emitClose();
req = websocket._req = null;
websocket.readyState = WebSocket.CLOSING;
websocket.emit('error', err);
websocket.emitClose();
});
req.on('response', (res) => {
if (this.emit('unexpected-response', req, res)) return;
const location = res.headers.location;
const statusCode = res.statusCode;
abortHandshake(this, req, `Unexpected server response: ${res.statusCode}`);
if (
location &&
opts.followRedirects &&
statusCode >= 300 &&
statusCode < 400
) {
if (++websocket._redirects > opts.maxRedirects) {
abortHandshake(websocket, req, 'Maximum redirects exceeded');
return;
}
req.abort();
const addr = url.URL
? new url.URL(location, address)
: url.resolve(address, location);
initAsClient(websocket, addr, protocols, options);
} else if (!websocket.emit('unexpected-response', req, res)) {
abortHandshake(
websocket,
req,
`Unexpected server response: ${res.statusCode}`
);
}
});
req.on('upgrade', (res, socket, head) => {
this.emit('upgrade', res);
websocket.emit('upgrade', res);
//
// The user may have closed the connection from a listener of the `upgrade`
// event.
//
if (this.readyState !== WebSocket.CONNECTING) return;
if (websocket.readyState !== WebSocket.CONNECTING) return;
req = this._req = null;
req = websocket._req = null;
const digest = crypto.createHash('sha1')
.update(key + constants.GUID, 'binary')
const digest = crypto
.createHash('sha1')
.update(key + GUID)
.digest('base64');
if (res.headers['sec-websocket-accept'] !== digest) {
abortHandshake(this, socket, 'Invalid Sec-WebSocket-Accept header');
abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');
return;
}
@@ -563,16 +629,16 @@ function initAsClient (address, protocols, options) {
protError = 'Server sent a subprotocol but none was requested';
} else if (protocols && !serverProt) {
protError = 'Server sent no subprotocol';
} else if (serverProt && protList.indexOf(serverProt) === -1) {
} else if (serverProt && !protList.includes(serverProt)) {
protError = 'Server sent an invalid subprotocol';
}
if (protError) {
abortHandshake(this, socket, protError);
abortHandshake(websocket, socket, protError);
return;
}
if (serverProt) this.protocol = serverProt;
if (serverProt) websocket.protocol = serverProt;
if (perMessageDeflate) {
try {
@@ -581,18 +647,22 @@ function initAsClient (address, protocols, options) {
);
if (extensions[PerMessageDeflate.extensionName]) {
perMessageDeflate.accept(
extensions[PerMessageDeflate.extensionName]
);
this._extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
websocket._extensions[
PerMessageDeflate.extensionName
] = perMessageDeflate;
}
} catch (err) {
abortHandshake(this, socket, 'Invalid Sec-WebSocket-Extensions header');
abortHandshake(
websocket,
socket,
'Invalid Sec-WebSocket-Extensions header'
);
return;
}
}
this.setSocket(socket, head, options.maxPayload);
websocket.setSocket(socket, head, opts.maxPayload);
});
}
@@ -603,7 +673,7 @@ function initAsClient (address, protocols, options) {
* @return {net.Socket} The newly created socket used to start the connection
* @private
*/
function netConnect (options) {
function netConnect(options) {
//
// Override `options.path` only if `options` is a copy of the original options
// object. This is always true on Node.js >= 8 but not on Node.js 6 where
@@ -621,7 +691,7 @@ function netConnect (options) {
* @return {tls.TLSSocket} The newly created socket used to start the connection
* @private
*/
function tlsConnect (options) {
function tlsConnect(options) {
options.path = undefined;
options.servername = options.servername || options.host;
return tls.connect(options);
@@ -636,7 +706,7 @@ function tlsConnect (options) {
* @param {String} message The error message
* @private
*/
function abortHandshake (websocket, stream, message) {
function abortHandshake(websocket, stream, message) {
websocket.readyState = WebSocket.CLOSING;
const err = new Error(message);
@@ -660,7 +730,7 @@ function abortHandshake (websocket, stream, message) {
* @param {String} reason The reason for closing
* @private
*/
function receiverOnConclude (code, reason) {
function receiverOnConclude(code, reason) {
const websocket = this[kWebSocket];
websocket._socket.removeListener('data', socketOnData);
@@ -679,7 +749,7 @@ function receiverOnConclude (code, reason) {
*
* @private
*/
function receiverOnDrain () {
function receiverOnDrain() {
this[kWebSocket]._socket.resume();
}
@@ -689,13 +759,13 @@ function receiverOnDrain () {
* @param {(RangeError|Error)} err The emitted error
* @private
*/
function receiverOnError (err) {
function receiverOnError(err) {
const websocket = this[kWebSocket];
websocket._socket.removeListener('data', socketOnData);
websocket.readyState = WebSocket.CLOSING;
websocket._closeCode = err[constants.kStatusCode];
websocket._closeCode = err[kStatusCode];
websocket.emit('error', err);
websocket._socket.destroy();
}
@@ -705,7 +775,7 @@ function receiverOnError (err) {
*
* @private
*/
function receiverOnFinish () {
function receiverOnFinish() {
this[kWebSocket].emitClose();
}
@@ -715,7 +785,7 @@ function receiverOnFinish () {
* @param {(String|Buffer|ArrayBuffer|Buffer[])} data The message
* @private
*/
function receiverOnMessage (data) {
function receiverOnMessage(data) {
this[kWebSocket].emit('message', data);
}
@@ -725,10 +795,10 @@ function receiverOnMessage (data) {
* @param {Buffer} data The data included in the ping frame
* @private
*/
function receiverOnPing (data) {
function receiverOnPing(data) {
const websocket = this[kWebSocket];
websocket.pong(data, !websocket._isServer, constants.NOOP);
websocket.pong(data, !websocket._isServer, NOOP);
websocket.emit('ping', data);
}
@@ -738,7 +808,7 @@ function receiverOnPing (data) {
* @param {Buffer} data The data included in the pong frame
* @private
*/
function receiverOnPong (data) {
function receiverOnPong(data) {
this[kWebSocket].emit('pong', data);
}
@@ -747,7 +817,7 @@ function receiverOnPong (data) {
*
* @private
*/
function socketOnClose () {
function socketOnClose() {
const websocket = this[kWebSocket];
this.removeListener('close', socketOnClose);
@@ -790,7 +860,7 @@ function socketOnClose () {
* @param {Buffer} chunk A chunk of data
* @private
*/
function socketOnData (chunk) {
function socketOnData(chunk) {
if (!this[kWebSocket]._receiver.write(chunk)) {
this.pause();
}
@@ -801,7 +871,7 @@ function socketOnData (chunk) {
*
* @private
*/
function socketOnEnd () {
function socketOnEnd() {
const websocket = this[kWebSocket];
websocket.readyState = WebSocket.CLOSING;
@@ -814,14 +884,12 @@ function socketOnEnd () {
*
* @private
*/
function socketOnError () {
function socketOnError() {
const websocket = this[kWebSocket];
this.removeListener('error', socketOnError);
this.on('error', constants.NOOP);
this.on('error', NOOP);
if (websocket) {
websocket.readyState = WebSocket.CLOSING;
this.destroy();
}
websocket.readyState = WebSocket.CLOSING;
this.destroy();
}

54
node/node_modules/ws/package.json generated vendored
View File

@@ -1,27 +1,32 @@
{
"_from": "ws@6.1.0",
"_id": "ws@6.1.0",
"_args": [
[
"ws@6.2.2",
"/usr/local/www/clonos/node"
]
],
"_from": "ws@6.2.2",
"_id": "ws@6.2.2",
"_inBundle": false,
"_integrity": "sha512-H3dGVdGvW2H8bnYpIDc3u3LH8Wue3Qh+Zto6aXXFzvESkTVT6rAfKR6tR/+coaUvxs8yHtmNV0uioBF62ZGSTg==",
"_integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"_location": "/ws",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "ws@6.1.0",
"raw": "ws@6.2.2",
"name": "ws",
"escapedName": "ws",
"rawSpec": "6.1.0",
"rawSpec": "6.2.2",
"saveSpec": null,
"fetchSpec": "6.1.0"
"fetchSpec": "6.2.2"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/ws/-/ws-6.1.0.tgz",
"_shasum": "119a9dbf92c54e190ec18d10e871d55c95cf9373",
"_spec": "ws@6.1.0",
"_where": "/usr/home/web/cp/clonos/node",
"_resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"_spec": "6.2.2",
"_where": "/usr/local/www/clonos/node",
"author": {
"name": "Einar Otto Stangvik",
"email": "einaros@gmail.com",
@@ -31,29 +36,26 @@
"bugs": {
"url": "https://github.com/websockets/ws/issues"
},
"bundleDependencies": false,
"dependencies": {
"async-limiter": "~1.0.0"
},
"deprecated": false,
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",
"devDependencies": {
"benchmark": "~2.1.2",
"benchmark": "~2.1.4",
"bufferutil": "~4.0.0",
"eslint": "~5.6.1",
"eslint-config-standard": "~12.0.0",
"eslint-plugin-import": "~2.14.0",
"eslint-plugin-node": "~7.0.0",
"eslint-plugin-promise": "~4.0.0",
"eslint-plugin-standard": "~4.0.0",
"mocha": "~5.2.0",
"nyc": "~13.0.1",
"coveralls": "~3.0.3",
"eslint": "~5.15.0",
"eslint-config-prettier": "~4.1.0",
"eslint-plugin-prettier": "~3.0.0",
"mocha": "~6.0.0",
"nyc": "~13.3.0",
"prettier": "~1.16.1",
"utf-8-validate": "~5.0.0"
},
"files": [
"browser.js",
"index.js",
"lib"
"lib/*.js"
],
"homepage": "https://github.com/websockets/ws",
"keywords": [
@@ -72,9 +74,9 @@
"url": "git+https://github.com/websockets/ws.git"
},
"scripts": {
"integration": "eslint . && mocha test/*.integration.js",
"lint": "eslint .",
"test": "eslint . && nyc --reporter=html --reporter=text mocha test/*.test.js"
"integration": "npm run lint && mocha test/*.integration.js",
"lint": "eslint --ignore-path .gitignore . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yml}\"",
"test": "npm run lint && nyc --reporter=html --reporter=text mocha test/*.test.js"
},
"version": "6.1.0"
"version": "6.2.2"
}