Simulator first commit
This commit is contained in:
5
node_modules/stream-throttle/.npmignore
generated
vendored
Normal file
5
node_modules/stream-throttle/.npmignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*~
|
||||
node_modules
|
||||
npm-debug.log
|
||||
tmp
|
||||
.DS_Store
|
1
node_modules/stream-throttle/AUTHORS
generated
vendored
Normal file
1
node_modules/stream-throttle/AUTHORS
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
Tiago Quelhas <tiagoq@gmail.com>
|
26
node_modules/stream-throttle/LICENSE
generated
vendored
Normal file
26
node_modules/stream-throttle/LICENSE
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
Copyright (c) 2013 Tiago Quelhas. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* The names of the authors and contributors may not be used to endorse or
|
||||
promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
49
node_modules/stream-throttle/README.md
generated
vendored
Normal file
49
node_modules/stream-throttle/README.md
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
# stream-throttle #
|
||||
|
||||
A rate limiter for Node.js streams.
|
||||
|
||||
## API usage
|
||||
|
||||
This module exports two classes, `Throttle` and `ThrottleGroup`.
|
||||
|
||||
`Throttle` creates a single throttled stream, based on `stream.Transform`. It accepts an `opts` parameter with the following keys:
|
||||
|
||||
* `opts.rate` is the throttling rate, in bytes per second.
|
||||
* `opts.chunksize` (optional) is the maximum chunk size into which larger writes are decomposed; the default is `opts.rate`/10.
|
||||
|
||||
The `opts` object may also contain options to be passed to the `stream.Transform` constructor.
|
||||
|
||||
For example, the following code throttles stdin to stdout at 10 bytes per second:
|
||||
|
||||
process.stdin.pipe(new Throttle({rate: 10})).pipe(process.stdout)
|
||||
|
||||
`ThrottleGroup` allows the creation of a group of streams whose aggregate bandwidth is throttled. The constructor accepts the same `opts` argument as for `Throttle`. Call `throttle` on a `ThrottleGroup` object to create a new throttled stream belonging to the group.
|
||||
|
||||
For example, the following code creates two HTTP connections to `www.google.com:80`, and throttles their aggregate (downstream) bandwidth to 10 KB/s:
|
||||
|
||||
var addr = { host: 'www.google.com', port: 80 };
|
||||
var tg = new ThrottleGroup({rate: 10240});
|
||||
|
||||
var conn1 = net.createConnection(addr),
|
||||
conn2 = net.createConnection(addr);
|
||||
|
||||
var thr1 = conn1.pipe(tg.throttle()),
|
||||
thr2 = conn2.pipe(tg.throttle());
|
||||
|
||||
// Reads from thr1 and thr2 are throttled to 10 KB/s in aggregate
|
||||
|
||||
## Command line usage
|
||||
|
||||
This package installs a `throttleproxy` binary which implements a command-line utility for throttling connections. Run `throttleproxy -h` for instructions.
|
||||
|
||||
## Contributing
|
||||
|
||||
Feel free to open an issue or send a pull request.
|
||||
|
||||
## License
|
||||
|
||||
BSD-style. See the LICENSE file.
|
||||
|
||||
## Author
|
||||
|
||||
Copyright © 2013 Tiago Quelhas. Contact me at `<tiagoq@gmail.com>`.
|
83
node_modules/stream-throttle/bin/throttleproxy.js
generated
vendored
Executable file
83
node_modules/stream-throttle/bin/throttleproxy.js
generated
vendored
Executable file
@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var net = require('net');
|
||||
var opts = require('commander');
|
||||
var Throttle = require('../src/throttle.js').Throttle;
|
||||
|
||||
function parseAddr(addr) {
|
||||
var result = /^(([^:]*):)?(\d+)$/.exec(addr);
|
||||
if (!result)
|
||||
return null;
|
||||
return {
|
||||
host: result[2],
|
||||
port: result[3]
|
||||
};
|
||||
}
|
||||
|
||||
function parseInteger(s) {
|
||||
if (!/^\d+$/.test(s))
|
||||
return undefined;
|
||||
return parseInt(s, 10);
|
||||
}
|
||||
|
||||
function runProxy(localAddr, remoteAddr, downRate, upRate) {
|
||||
var server = net.createServer(function(local) {
|
||||
|
||||
var remote = net.createConnection(remoteAddr);
|
||||
|
||||
var localThrottle = new Throttle({rate: upRate});
|
||||
var remoteThrottle = new Throttle({rate: downRate});
|
||||
|
||||
local.pipe(localThrottle).pipe(remote);
|
||||
local.on('error', function() {
|
||||
remote.destroy();
|
||||
local.destroy();
|
||||
});
|
||||
|
||||
remote.pipe(remoteThrottle).pipe(local);
|
||||
remote.on('error', function() {
|
||||
local.destroy();
|
||||
remote.destroy();
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(localAddr.port, localAddr.host);
|
||||
}
|
||||
|
||||
function main() {
|
||||
var localAddr, remoteAddr, downRate, upRate;
|
||||
|
||||
opts
|
||||
.option('-l, --localaddr <addr>', 'local address, default 0.0.0.0:8080')
|
||||
.option('-r, --remoteaddr <addr>', 'remote address, default localhost:80')
|
||||
.option('-d, --downstream <bps>', 'downstream bandwidth', parseInteger)
|
||||
.option('-u, --upstream <bps>', 'upstream bandwidth, default equal to downstream', parseInteger)
|
||||
.parse(process.argv);
|
||||
|
||||
if (opts.localaddr !== undefined) {
|
||||
localAddr = parseAddr(opts.localaddr);
|
||||
if (!localAddr)
|
||||
opts.help();
|
||||
} else
|
||||
localAddr = {host: undefined, port: 8080};
|
||||
|
||||
if (opts.remoteaddr !== undefined) {
|
||||
remoteAddr = parseAddr(opts.remoteaddr);
|
||||
if (!remoteAddr)
|
||||
opts.help();
|
||||
} else
|
||||
remoteAddr = {host: undefined, port: 80};
|
||||
|
||||
if (opts.downstream === undefined)
|
||||
opts.help();
|
||||
downRate = opts.downstream;
|
||||
|
||||
if (opts.upstream !== undefined)
|
||||
upRate = opts.upstream;
|
||||
else
|
||||
upRate = downRate;
|
||||
|
||||
runProxy(localAddr, remoteAddr, downRate, upRate);
|
||||
}
|
||||
|
||||
main();
|
1
node_modules/stream-throttle/index.js
generated
vendored
Normal file
1
node_modules/stream-throttle/index.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('./src/throttle.js');
|
71
node_modules/stream-throttle/package.json
generated
vendored
Normal file
71
node_modules/stream-throttle/package.json
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"_from": "stream-throttle@^0.1.3",
|
||||
"_id": "stream-throttle@0.1.3",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=",
|
||||
"_location": "/stream-throttle",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "stream-throttle@^0.1.3",
|
||||
"name": "stream-throttle",
|
||||
"escapedName": "stream-throttle",
|
||||
"rawSpec": "^0.1.3",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^0.1.3"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz",
|
||||
"_shasum": "add57c8d7cc73a81630d31cd55d3961cfafba9c3",
|
||||
"_spec": "stream-throttle@^0.1.3",
|
||||
"_where": "/home/sergiu/linx-audio-simulator",
|
||||
"author": {
|
||||
"name": "Tiago Quelhas",
|
||||
"email": "tiagoq@gmail.com"
|
||||
},
|
||||
"bin": {
|
||||
"throttleproxy": "./bin/throttleproxy.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/tjgq/node-stream-throttle/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Tiago Quelhas",
|
||||
"email": "tiagoq@gmail.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "^2.2.0",
|
||||
"limiter": "^1.0.5"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "A rate limiter for Node.js streams.",
|
||||
"devDependencies": {
|
||||
"async": "^0.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"homepage": "https://github.com/tjgq/node-stream-throttle#readme",
|
||||
"keywords": [
|
||||
"streams",
|
||||
"throttling",
|
||||
"ratelimit"
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "./index.js",
|
||||
"name": "stream-throttle",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/tjgq/node-stream-throttle.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "nodeunit test"
|
||||
},
|
||||
"version": "0.1.3"
|
||||
}
|
75
node_modules/stream-throttle/src/throttle.js
generated
vendored
Normal file
75
node_modules/stream-throttle/src/throttle.js
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
var inherits = require('util').inherits;
|
||||
var Transform = require('stream').Transform;
|
||||
var TokenBucket = require('limiter').TokenBucket;
|
||||
|
||||
/*
|
||||
* Throttle is a throttled stream implementing the stream.Transform interface.
|
||||
* Options:
|
||||
* rate (mandatory): the throttling rate in bytes per second.
|
||||
* chunksize (optional): the maximum chunk size into which larger writes are decomposed.
|
||||
* Any other options are passed to stream.Transform.
|
||||
*/
|
||||
function Throttle(opts, group) {
|
||||
if (group === undefined)
|
||||
group = new ThrottleGroup(opts);
|
||||
this.bucket = group.bucket;
|
||||
this.chunksize = group.chunksize;
|
||||
Transform.call(this, opts);
|
||||
}
|
||||
inherits(Throttle, Transform);
|
||||
|
||||
Throttle.prototype._transform = function(chunk, encoding, done) {
|
||||
process(this, chunk, 0, done);
|
||||
};
|
||||
|
||||
function process(self, chunk, pos, done) {
|
||||
var slice = chunk.slice(pos, pos + self.chunksize);
|
||||
if (!slice.length) {
|
||||
// chunk fully consumed
|
||||
done();
|
||||
return;
|
||||
}
|
||||
self.bucket.removeTokens(slice.length, function(err) {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
}
|
||||
self.push(slice);
|
||||
process(self, chunk, pos + self.chunksize, done);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* ThrottleGroup throttles an aggregate of streams.
|
||||
* Options are the same as for Throttle.
|
||||
*/
|
||||
function ThrottleGroup(opts) {
|
||||
if (!(this instanceof ThrottleGroup))
|
||||
return new ThrottleGroup(opts);
|
||||
|
||||
opts = opts || {};
|
||||
if (opts.rate === undefined)
|
||||
throw new Error('throttle rate is a required argument');
|
||||
if (typeof opts.rate !== 'number' || opts.rate <= 0)
|
||||
throw new Error('throttle rate must be a positive number');
|
||||
if (opts.chunksize !== undefined && (typeof opts.chunksize !== 'number' || opts.chunksize <= 0)) {
|
||||
throw new Error('throttle chunk size must be a positive number');
|
||||
}
|
||||
|
||||
this.rate = opts.rate;
|
||||
this.chunksize = opts.chunksize || this.rate/10;
|
||||
this.bucket = new TokenBucket(this.rate, this.rate, 'second', null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new stream in the throttled group and returns it.
|
||||
* Any supplied options are passed to the Throttle constructor.
|
||||
*/
|
||||
ThrottleGroup.prototype.throttle = function(opts) {
|
||||
return new Throttle(opts, this);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
Throttle: Throttle,
|
||||
ThrottleGroup: ThrottleGroup
|
||||
};
|
49
node_modules/stream-throttle/test/throttle_test.js
generated
vendored
Normal file
49
node_modules/stream-throttle/test/throttle_test.js
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
var async = require('async');
|
||||
var Throttle = require('../index.js').Throttle;
|
||||
var ThrottleGroup = require('../index.js').ThrottleGroup;
|
||||
|
||||
var sendStr = (function() {
|
||||
var s = '0123456789xyzXYZ?!\0åéîõü$£€*<>'; // 30 characters
|
||||
for (var i = 0, str = ''; i < 1000; i++)
|
||||
str += s;
|
||||
return str; // 30K characters
|
||||
})();
|
||||
|
||||
var opts = {rate: 100000}; // 100 KiB/s
|
||||
|
||||
var testSendRecv = function(t, cb) {
|
||||
var recvStr = '';
|
||||
t.on('data', function(chunk) {
|
||||
recvStr += chunk;
|
||||
});
|
||||
t.on('end', function() {
|
||||
cb(sendStr == recvStr);
|
||||
});
|
||||
t.write(sendStr, function() {
|
||||
t.end();
|
||||
});
|
||||
};
|
||||
|
||||
exports.testThrottle = function(test) {
|
||||
var t = new Throttle(opts);
|
||||
|
||||
test.expect(1);
|
||||
testSendRecv(t, function(ok) {
|
||||
test.ok(ok, "received string should equal sent string");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
exports.testGroupThrottle = function(test) {
|
||||
var tg = new ThrottleGroup(opts);
|
||||
|
||||
test.expect(3);
|
||||
async.each([1, 2, 3], function(i, done) {
|
||||
testSendRecv(tg.throttle(), function(ok) {
|
||||
test.ok(ok, "received string should equal sent string");
|
||||
done();
|
||||
});
|
||||
}, function() {
|
||||
test.done();
|
||||
});
|
||||
};
|
Reference in New Issue
Block a user