anyproxy/proxy.js

173 lines
5.5 KiB
JavaScript
Raw Normal View History

2014-09-03 01:10:26 +08:00
//mix some modules to global.util
try{
2014-09-04 22:21:51 +08:00
GLOBAL.util = require('./lib/util');
GLOBAL.util['iconv-lite'] = require("iconv-lite");
GLOBAL.util['colorful'] = require("colorful");
2014-09-06 10:15:51 +08:00
GLOBAL.util['path'] = require("path");
2014-09-03 01:10:26 +08:00
}catch(e){}
2014-08-11 16:43:14 +08:00
var http = require('http'),
https = require('https'),
fs = require('fs'),
async = require("async"),
url = require('url'),
program = require('commander'),
2014-08-13 11:51:39 +08:00
color = require('colorful'),
certMgr = require("./lib/certMgr"),
2014-08-19 15:31:28 +08:00
getPort = require("./lib/getPort"),
2014-08-27 17:42:42 +08:00
requestHandler = require("./lib/requestHandler"),
Recorder = require("./lib/Recorder"),
2014-09-04 11:22:35 +08:00
util = require("./lib/util"),
2014-08-27 17:42:42 +08:00
entities = require("entities"),
express = require("express"),
2014-09-06 09:50:49 +08:00
path = require("path"),
2014-08-27 17:42:42 +08:00
WebSocketServer= require('ws').Server;
GLOBAL.recorder = new Recorder();
2014-08-11 16:43:14 +08:00
2014-09-04 11:22:35 +08:00
var T_TYPE_HTTP = 0,
2014-08-27 17:42:42 +08:00
T_TYPE_HTTPS = 1,
DEFAULT_PORT = 8001,
DEFAULT_WEB_PORT = 8002,
DEFAULT_WEBSOCKET_PORT = 8003,
DEFAULT_HOST = "localhost",
DEFAULT_TYPE = T_TYPE_HTTP;
2014-08-11 16:43:14 +08:00
2014-09-06 09:50:49 +08:00
var default_rule = require('./lib/rule_default');
if(fs.existsSync(path.join(util.getUserHome(),"/.anyproxy/rule_default.js"))){
default_rule = require(path.join(util.getUserHome(),"/.anyproxy/rule_default"));
}
2014-09-06 10:15:51 +08:00
if(fs.existsSync(process.cwd() + '/rule.js')){
default_rule = require(process.cwd() + '/rule');
}
2014-09-06 09:50:49 +08:00
2014-09-04 11:22:35 +08:00
//option
//option.type : 'http'(default) or 'https'
//option.port : 8001(default)
//option.rule : ruleModule
//option.hostname : localhost(default)
function proxyServer(option){
option = option || {};
var self = this,
proxyType = /https/i.test(option.type || DEFAULT_TYPE) ? T_TYPE_HTTPS : T_TYPE_HTTP ,
proxyPort = option.port || DEFAULT_PORT,
proxyHost = option.hostname || DEFAULT_HOST,
2014-09-06 09:50:49 +08:00
proxyRules = option.rule || default_rule;
2014-09-04 11:22:35 +08:00
2014-09-05 13:53:12 +08:00
requestHandler.setRules(proxyRules); //TODO : optimize calling for set rule
2014-08-14 22:58:30 +08:00
self.httpProxyServer = null;
2014-08-13 11:51:39 +08:00
2014-08-14 22:58:30 +08:00
async.series(
[
2014-08-13 11:51:39 +08:00
//creat proxy server
2014-08-11 16:43:14 +08:00
function(callback){
if(proxyType == T_TYPE_HTTPS){
2014-08-11 17:48:32 +08:00
certMgr.getCertificate(proxyHost,function(err,keyContent,crtContent){
2014-08-11 16:43:14 +08:00
if(err){
callback(err);
}else{
2014-08-14 22:58:30 +08:00
self.httpProxyServer = https.createServer({
2014-08-11 16:43:14 +08:00
key : keyContent,
cert: crtContent
2014-08-13 11:51:39 +08:00
},requestHandler.userRequestHandler);
2014-08-11 16:43:14 +08:00
callback(null);
}
});
}else{
2014-08-14 22:58:30 +08:00
self.httpProxyServer = http.createServer(requestHandler.userRequestHandler);
2014-08-11 16:43:14 +08:00
callback(null);
}
},
2014-09-04 11:22:35 +08:00
//listen CONNECT method for https over http
2014-08-11 16:43:14 +08:00
function(callback){
2014-08-14 22:58:30 +08:00
self.httpProxyServer.on('connect',requestHandler.connectReqHandler);
2014-08-14 22:58:30 +08:00
self.httpProxyServer.listen(proxyPort);
2014-08-11 16:43:14 +08:00
callback(null);
2014-09-04 11:22:35 +08:00
},
//start web interface
function(callback){
startWebServer();
callback(null);
2014-08-11 16:43:14 +08:00
}
],
//final callback
function(err,result){
if(!err){
2014-08-13 11:51:39 +08:00
var tipText = (proxyType == T_TYPE_HTTP ? "Http" : "Https") + " proxy started at port " + proxyPort;
console.log(color.green(tipText));
2014-08-11 16:43:14 +08:00
}else{
2014-08-13 11:51:39 +08:00
var tipText = "err when start proxy server :(";
console.log(color.red(tipText));
2014-08-11 16:43:14 +08:00
console.log(err);
}
}
);
2014-08-14 22:58:30 +08:00
2014-09-04 11:22:35 +08:00
self.close = function(){
self.httpProxyServer && self.httpProxyServer.close();
console.log(color.green("server closed :" + proxyHost + ":" + proxyPort));
}
2014-08-11 16:43:14 +08:00
}
2014-08-27 17:42:42 +08:00
function startWebServer(port){
port = port || DEFAULT_WEB_PORT;
//web interface
var app = express();
app.use(function(req, res, next) {
res.setHeader("note", "THIS IS A REQUEST FROM ANYPROXY WEB INTERFACE");
return next();
});
app.get("/summary",function(req,res){
GLOBAL.recorder.getSummaryList(function(err,docs){
if(err){
res.end(err.toString());
}else{
res.json(docs.slice(docs.length -500));
}
});
});
app.get("/body",function(req,res){
var reqQuery = url.parse(req.url,true);
var id = reqQuery.query.id;
res.setHeader("Content-Type","text/html");
res.writeHead(200);
var body = GLOBAL.recorder.getBody(id);
res.end(entities.encodeHTML(body));
});
app.use(express.static(__dirname + '/web'));
app.listen(port);
var tipText = "web interface started at port " + port;
console.log(color.green(tipText));
//web socket interface
var wss = new WebSocketServer({port: DEFAULT_WEBSOCKET_PORT});
2014-09-02 15:59:58 +08:00
wss.on("connection",function(ws){});
2014-08-27 17:42:42 +08:00
wss.broadcast = function(data) {
for(var i in this.clients){
this.clients[i].send(data);
}
};
GLOBAL.recorder.on("update",function(data){
wss.broadcast( JSON.stringify(data) );
});
}
2014-08-14 22:58:30 +08:00
module.exports.proxyServer = proxyServer;
2014-08-14 10:59:49 +08:00
module.exports.generateRootCA = certMgr.generateRootCA;
module.exports.isRootCAFileExists = certMgr.isRootCAFileExists;