add throttling

This commit is contained in:
加里 2014-10-29 16:20:18 +08:00
parent 785924dec2
commit 48e2304765
5 changed files with 47 additions and 23 deletions

View File

@ -216,6 +216,10 @@ Others
* to save request data to local file, use ``` anyproxy --file /path/to/file ```
* anyproxy uses [nedb](https://github.com/louischatriot/nedb) to save request data. Since NeDB's persistence uses an append-only format, you may get some redundant record in local file. For those dupplicated ones with the same id, just use the lastest line of record.
#### throttling
* e.g. throttle to 10kb , use ``` anyproxy --throttle 10 ```
* this is just a rough throttling for downstream, not for network simulation
#### work as a module for nodejs
```
npm install anyproxy --save
@ -233,10 +237,11 @@ var options = {
port : 8001,
hostname : "localhost",
rule : require("path/to/my/ruleModule.js"),
dbFile : null, //save request data to a specified file, will use in-memory db if not specified
webPort : 8002, // port for web interface
socketPort : 8003, // internal port for web socket, replace this when it is conflict with your own service
webConfigPort : 8088 // internal port for web config(beta), replace this when it is conflict with your own service
dbFile : null, // optional, save request data to a specified file, will use in-memory db if not specified
webPort : 8002, // optional, port for web interface
socketPort : 8003, // optional, internal port for web socket, replace this when it is conflict with your own service
webConfigPort : 8088, // optional, internal port for web config(beta), replace this when it is conflict with your own service
throttle : 10, // optional, speed limit in kb/s
};
new proxy.proxyServer(options);

2
bin.js
View File

@ -12,6 +12,7 @@ program
.option('-f, --file [value]', 'save request data to a specified file, will use in-memory db if not specified')
.option('-r, --rule [value]', 'path for rule file,')
.option('-g, --root [value]', 'generate root CA')
.option('-l, --throttle [value]', 'throttle speed in kb/s')
.option('-c, --clear', 'clear all the tmp certificates')
.parse(process.argv);
@ -46,6 +47,7 @@ if(program.clear){
port : program.port,
hostname : program.hostname,
dbFile : program.file,
throttle : program.throttle,
rule : ruleModule
});
}

View File

@ -9,6 +9,7 @@ var http = require("http"),
color = require("colorful"),
Buffer = require('buffer').Buffer,
util = require("./util"),
Stream = require("stream"),
httpsServerMgr = require("./httpsServerMgr");
var httpsServerMgrInstance = new httpsServerMgr(),
@ -109,6 +110,7 @@ function userRequestHandler(req,userRes){
};
options = userRule.replaceRequestOption(req,options) || options;
//update quest data
reqData = userRule.replaceRequestData(req,reqData) || reqData;
options.headers = util.lower_keys(options.headers);
@ -182,13 +184,19 @@ function userRequestHandler(req,userRes){
//send response
},function(callback){
// if(404 == statusCode){
// var html404path = pathUtil.join(__dirname, '..', 'web', '404.html');
// userRes.end(fs.readFileSync(html404path));
// }else{
if(GLOBAL._throttle){
var thrStream = new Stream();
var readable = thrStream.pipe(GLOBAL._throttle.throttle());
readable.pipe(userRes);
thrStream.emit("data",serverResData);
thrStream.emit("end");
callback();
}else{
userRes.end(serverResData);
// }
callback();
callback();
}
//udpate record info
},function(callback){

View File

@ -1,6 +1,6 @@
{
"name": "anyproxy",
"version": "2.6.0",
"version": "2.7.0",
"description": "A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.",
"main": "proxy.js",
"bin": {
@ -15,14 +15,15 @@
"express": "^4.8.5",
"iconv-lite": "^0.4.4",
"ip": "^0.3.2",
"jquery": "^2.1.1",
"jsdom": "^1.0.3",
"juicer": "^0.6.6-stable",
"nedb": "^0.11.0",
"qrcode-npm": "0.0.3",
"socks5-http-client": "^0.1.6",
"socks5-https-client": "^0.2.2",
"ws": "^0.4.32",
"jsdom":"^1.0.3",
"jquery":"^2.1.1"
"stream-throttle": "^0.1.3",
"ws": "^0.4.32"
},
"devDependencies": {},
"scripts": {

View File

@ -1,13 +1,13 @@
//mix some modules to global.util
try{
GLOBAL.util = require('./lib/util');
GLOBAL.util['iconv-lite'] = require("iconv-lite");
GLOBAL.util['colorful'] = require("colorful");
GLOBAL.util['path'] = require("path");
GLOBAL.util['jsdom'] = require('jsdom');
GLOBAL.util['jquery'] = require('jquery');
GLOBAL.util['Socks5ClientHttpAgent'] = require('socks5-http-client/lib/Agent');
GLOBAL.util['Socks5ClientHttpsAgent'] = require('socks5-https-client/lib/Agent');
GLOBAL.util = require('./lib/util');
GLOBAL.util['iconv-lite'] = require("iconv-lite");
GLOBAL.util['colorful'] = require("colorful");
GLOBAL.util['path'] = require("path");
GLOBAL.util['jsdom'] = require('jsdom');
GLOBAL.util['jquery'] = require('jquery');
GLOBAL.util['Socks5ClientHttpAgent'] = require('socks5-http-client/lib/Agent');
GLOBAL.util['Socks5ClientHttpsAgent'] = require('socks5-https-client/lib/Agent');
}catch(e){}
var http = require('http'),
@ -28,7 +28,9 @@ var http = require('http'),
events = require("events"),
express = require("express"),
ip = require("ip"),
fork = require("child_process").fork;
fork = require("child_process").fork,
ThrottleGroup = require("stream-throttle").ThrottleGroup;
var T_TYPE_HTTP = 0,
T_TYPE_HTTPS = 1,
@ -60,6 +62,7 @@ if(fs.existsSync(process.cwd() + '/rule.js')){
//option.socketPort : 8003(default)
//option.webConfigPort : 8088(default)
//option.dbFile : null(default)
//option.throttle : null(default)
function proxyServer(option){
option = option || {};
@ -78,6 +81,11 @@ function proxyServer(option){
GLOBAL.recorder = new Recorder();
}
if(option.throttle){
console.log("throttle :" + option.throttle + "kb/s");
GLOBAL._throttle = new ThrottleGroup({rate: 1024 * parseInt(option.throttle) }); // rate - byte/sec
}
requestHandler.setRules(proxyRules); //TODO : optimize calling for set rule
self.httpProxyServer = null;