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).

152
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,11 +113,10 @@ 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.
// Below options specified as default values.
concurrencyLimit: 10, // Limits zlib concurrency for perf.
threshold: 1024, // Size (in bytes) below which messages
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

View File

@@ -1,5 +1,7 @@
'use strict';
const { EMPTY_BUFFER } = require('./constants');
/**
* Merges an array of buffers into a new buffer.
*
@@ -9,6 +11,9 @@
* @public
*/
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;
@@ -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 = {
concat,
mask(source, mask, output, offset, length) {
if (length < 48) _mask(source, mask, output, offset, length);
else bu.mask(source, mask, output, offset, length);
},
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

@@ -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
@@ -195,17 +196,27 @@ function parse (header) {
* @public
*/
function format(extensions) {
return Object.keys(extensions).map((extension) => {
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) => {
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(', ');
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');
@@ -55,9 +53,8 @@ class PerMessageDeflate {
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,7 +62,8 @@ class PerMessageDeflate {
this.params = null;
if (!zlibLimiter) {
const concurrency = this._options.concurrencyLimit !== undefined
const concurrency =
this._options.concurrencyLimit !== undefined
? this._options.concurrencyLimit
: 10;
zlibLimiter = new Limiter({ concurrency });
@@ -130,22 +128,15 @@ class PerMessageDeflate {
*/
cleanup() {
if (this._inflate) {
if (this._inflate[kWriteInProgress]) {
this._inflate[kPendingClose] = true;
} else {
this._inflate.close();
this._inflate = null;
}
}
if (this._deflate) {
if (this._deflate[kWriteInProgress]) {
this._deflate[kPendingClose] = true;
} else {
this._deflate.close();
this._deflate = null;
}
}
}
/**
* Accept an extension negotiation offer.
@@ -339,7 +330,8 @@ class PerMessageDeflate {
if (!this._inflate) {
const key = `${endpoint}_max_window_bits`;
const windowBits = typeof this.params[key] !== 'number'
const windowBits =
typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
@@ -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] = [];
}
@@ -408,7 +395,8 @@ class PerMessageDeflate {
if (!this._deflate) {
const key = `${endpoint}_max_window_bits`;
const windowBits = typeof this.params[key] !== 'number'
const windowBits =
typeof this.params[key] !== 'number'
? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
@@ -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] = [];
}
@@ -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();
}
@@ -503,6 +497,6 @@ function inflateOnError (err) {
// closed when an error is emitted.
//
this[kPerMessageDeflate]._inflate = null;
err[constants.kStatusCode] = 1007;
err[kStatusCode] = 1007;
this[kCallback](err);
}

83
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.
*
@@ -30,8 +35,8 @@ class Receiver extends stream.Writable {
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;
@@ -62,7 +67,7 @@ class Receiver extends stream.Writable {
* @param {Function} cb Callback
*/
_write(chunk, encoding, cb) {
if (this._opcode === 0x08) return cb();
if (this._opcode === 0x08 && this._state == GET_INFO) return cb();
this._bufferedBytes += chunk.length;
this._buffers.push(chunk);
@@ -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;
}
@@ -314,7 +320,7 @@ class Receiver extends stream.Writable {
* @private
*/
getData(cb) {
var data = constants.EMPTY_BUFFER;
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);
@@ -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);
@@ -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);
}
@@ -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;
}
}
@@ -480,34 +487,6 @@ function error (ErrorCtor, message, prefix, statusCode) {
);
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);
}

143
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.
@@ -43,7 +43,7 @@ class Sender {
* @public
*/
static frame(data, options) {
const merge = data.length < 1024 || (options.mask && options.readOnly);
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];
}
@@ -107,8 +101,8 @@ class Sender {
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);
@@ -135,13 +129,16 @@ class Sender {
* @private
*/
doClose(data, mask, cb) {
this.sendFrame(Sender.frame(data, {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x08,
mask,
readOnly: false
}), cb);
}),
cb
);
}
/**
@@ -153,23 +150,12 @@ class Sender {
* @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;
}
}
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);
}
}
@@ -183,13 +169,16 @@ class Sender {
* @private
*/
doPing(data, mask, readOnly, cb) {
this.sendFrame(Sender.frame(data, {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x09,
mask,
readOnly
}), cb);
}),
cb
);
}
/**
@@ -201,23 +190,12 @@ class Sender {
* @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;
}
}
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);
}
}
@@ -231,13 +209,16 @@ class Sender {
* @private
*/
doPong(data, mask, readOnly, cb) {
this.sendFrame(Sender.frame(data, {
this.sendFrame(
Sender.frame(data, {
fin: true,
rsv1: false,
opcode: 0x0a,
mask,
readOnly
}), cb);
}),
cb
);
}
/**
@@ -253,27 +234,15 @@ class Sender {
* @public
*/
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, {
this.sendFrame(
Sender.frame(buf, {
fin: options.fin,
rsv1: false,
opcode,
mask: options.mask,
readOnly
}), cb);
readOnly: toBuffer.readOnly
}),
cb
);
}
}
@@ -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();
});
}
@@ -373,8 +345,10 @@ class Sender {
*/
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,7 +3,8 @@
try {
const isValidUTF8 = require('utf-8-validate');
exports.isValidUTF8 = typeof isValidUTF8 === 'object'
exports.isValidUTF8 =
typeof isValidUTF8 === 'object'
? isValidUTF8.Validation.isValidUTF8 // utf-8-validate@<3.0.0
: isValidUTF8;
} catch (e) /* istanbul ignore next */ {

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,22 +21,27 @@ 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) {
super();
options = Object.assign({
options = Object.assign(
{
maxPayload: 100 * 1024 * 1024,
perMessageDeflate: false,
handleProtocols: null,
@@ -47,7 +53,9 @@ class WebSocketServer extends EventEmitter {
host: null,
path: null,
port: null
}, options);
},
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;
}
@@ -147,8 +160,11 @@ class WebSocketServer extends EventEmitter {
* @public
*/
shouldHandle(req) {
if (this.options.path && url.parse(req.url).pathname !== this.options.path) {
return false;
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;
@@ -166,12 +182,19 @@ class WebSocketServer extends EventEmitter {
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.
@@ -353,15 +377,20 @@ function socketOnError () {
function abortHandshake(socket, code, message, headers) {
if (socket.writable) {
message = message || http.STATUS_CODES[code];
headers = Object.assign({
'Connection': 'close',
headers = Object.assign(
{
Connection: 'close',
'Content-type': 'text/html',
'Content-Length': Buffer.byteLength(message)
}, headers);
},
headers
);
socket.write(
`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
Object.keys(headers).map(h => `${h}: ${headers[h]}`).join('\r\n') +
Object.keys(headers)
.map((h) => `${h}: ${headers[h]}`)
.join('\r\n') +
'\r\n\r\n' +
message
);
@@ -370,3 +399,15 @@ function abortHandshake (socket, code, message, headers) {
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();
}

272
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.
@@ -39,19 +45,21 @@ class WebSocket extends EventEmitter {
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,18 +67,29 @@ 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}
*/
@@ -79,7 +98,7 @@ class WebSocket extends EventEmitter {
}
set binaryType(type) {
if (constants.BINARY_TYPES.indexOf(type) < 0) return;
if (!BINARY_TYPES.includes(type)) return;
this._binaryType = type;
@@ -212,21 +231,17 @@ 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.
// Specify a timeout for the closing handshake to complete.
//
this._closeTimer = setTimeout(
this._socket.destroy.bind(this._socket),
closeTimeout
);
}
});
}
/**
* Send a ping.
@@ -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);
}
/**
@@ -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);
}
/**
@@ -322,18 +337,21 @@ class WebSocket extends EventEmitter {
if (typeof data === 'number') data = data.toString();
const opts = Object.assign({
const opts = Object.assign(
{
binary: typeof data !== 'string',
mask: !this._isServer,
compress: true,
fin: true
}, options);
},
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);
}
/**
@@ -356,7 +374,7 @@ class WebSocket extends EventEmitter {
}
readyStates.forEach((readyState, i) => {
WebSocket[readyStates[i]] = i;
WebSocket[readyState] = i;
});
//
@@ -376,6 +394,8 @@ readyStates.forEach((readyState, i) => {
for (var i = 0; i < listeners.length; i++) {
if (listeners[i]._listener) return listeners[i]._listener;
}
return undefined;
},
/**
* Add a listener for the event.
@@ -404,22 +424,34 @@ 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({
function initAsClient(websocket, address, protocols, options) {
const opts = Object.assign(
{
protocolVersion: protocolVersions[1],
maxPayload: 100 * 1024 * 1024,
perMessageDeflate: true,
maxPayload: 100 * 1024 * 1024
}, options, {
followRedirects: false,
maxRedirects: 10
},
options,
{
createConnection: undefined,
socketPath: undefined,
hostname: undefined,
@@ -430,128 +462,162 @@ function initAsClient (address, protocols, options) {
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,
opts.headers = Object.assign(
{
'Sec-WebSocket-Version': opts.protocolVersion,
'Sec-WebSocket-Key': key,
'Connection': 'Upgrade',
'Upgrade': 'websocket'
}, options.headers);
options.path = path;
if (options.perMessageDeflate) {
perMessageDeflate = new PerMessageDeflate(
options.perMessageDeflate !== true ? options.perMessageDeflate : {},
false,
options.maxPayload
Connection: 'Upgrade',
Upgrade: 'websocket'
},
opts.headers
);
options.headers['Sec-WebSocket-Extensions'] = extension.format({
opts.path = path;
opts.timeout = opts.handshakeTimeout;
if (opts.perMessageDeflate) {
perMessageDeflate = new PerMessageDeflate(
opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},
false,
opts.maxPayload
);
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);
});
}
@@ -695,7 +765,7 @@ function receiverOnError (err) {
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();
}
@@ -728,7 +798,7 @@ function receiverOnMessage (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);
}
@@ -818,10 +888,8 @@ 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();
}
}

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"
}