diff --git a/README.md b/README.md index 17e5790..c4cde38 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Feature * work as http or https proxy * fully configurable, you can modify a request at any stage by your own javascript code * when working as https proxy, it can generate and intercept https requests for any domain without complaint by browser (after you trust its root CA) -* provide a web interface +* a web interface is availabe for you to view request details ![screenshot](http://gtms03.alicdn.com/tps/i3/TB1ddyqGXXXXXbXXpXXihxC1pXX-1000-549.jpg_640x640q90.jpg) @@ -54,6 +54,9 @@ module.exports = { /* these functions will overwrite the default ones, write your own when necessary. */ + summary:function(){ + console.log("this is a blank rule for anyproxy"); + }, //whether to intercept this request by local logic //if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore @@ -76,8 +79,7 @@ module.exports = { return newProtocol; }, - //req is user's request sent to the proxy server - //option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...}) + //req is user's request which will be sent to the proxy server, docs : http://nodejs.org/api/http.html#http_http_request_options_callback //you may return a customized option to replace the original option //you should not write content-length header in options, since anyproxy will handle it for you replaceRequestOption : function(req,option){ @@ -150,8 +152,17 @@ npm install anyproxy --save ```javascript var proxy = require("anyproxy"); -!proxy.isRootCAFileExists() && proxy.generateRootCA(); //please manually trust this rootCA -new proxy.proxyServer("http","8001", "localhost" ,"path/to/rule/file.js"); +//create cert when you want to use https features +//please manually trust this rootCA when it is the first time you run it +!proxy.isRootCAFileExists() && proxy.generateRootCA(); + +var options = { + type : "http", + port : "8001", + hostname : "localhost", + rule : require("path/to/my/ruleModule.js") +}; +new proxy.proxyServer(options); ``` diff --git a/bin.js b/bin.js index ea86b51..ee46f15 100644 --- a/bin.js +++ b/bin.js @@ -25,6 +25,27 @@ if(program.clear){ process.exit(0); }); }else{ - new proxy.proxyServer(program.type,program.port, program.host ,program.rule); + var ruleModule; + + if(program.rule){ + if(fs.existsSync(program.rule)){ + try{ //for abs path + ruleModule = require(program.rule); + }catch(e){ //for relative path + ruleModule = require("./" + program.rule); + } + console.log(color.green("rule file loaded")); + }else{ + console.log(color.red("can not find rule file")); + } + } + + new proxy.proxyServer({ + type : program.type, + port : program.port, + hostname : program.hostname, + rule : ruleModule + }); +} + -} \ No newline at end of file diff --git a/package.json b/package.json index a9340cd..027404d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "anyproxy", - "version": "2.1.2", + "version": "2.2.0", "description": "a charles/fiddler like proxy written in NodeJs, which can handle HTTPS requests and CROS perfectly.", "main": "proxy.js", "bin": { diff --git a/proxy.js b/proxy.js index 1d28df9..2151eea 100644 --- a/proxy.js +++ b/proxy.js @@ -15,13 +15,14 @@ var http = require('http'), getPort = require("./lib/getPort"), requestHandler = require("./lib/requestHandler"), Recorder = require("./lib/Recorder"), + util = require("./lib/util"), entities = require("entities"), express = require("express"), WebSocketServer= require('ws').Server; GLOBAL.recorder = new Recorder(); -var T_TYPE_HTTP = 0, +var T_TYPE_HTTP = 0, T_TYPE_HTTPS = 1, DEFAULT_PORT = 8001, DEFAULT_WEB_PORT = 8002, @@ -29,35 +30,22 @@ var T_TYPE_HTTP = 0, DEFAULT_HOST = "localhost", DEFAULT_TYPE = T_TYPE_HTTP; -function proxyServer(type, port, hostname,ruleFile){ - var self = this, - proxyType = /https/i.test(type || DEFAULT_TYPE) ? T_TYPE_HTTPS : T_TYPE_HTTP , - proxyPort = port || DEFAULT_PORT, - proxyHost = hostname || DEFAULT_HOST; +//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, + proxyRules = option.rule; + + requestHandler.setRules(proxyRules); self.httpProxyServer = null; - self.close = function(){ - self.httpProxyServer && self.httpProxyServer.close(); - console.log(color.green("server closed :" + proxyHost + ":" + proxyPort)); - } - - startWebServer(); - - if(ruleFile){ - if(fs.existsSync(ruleFile)){ - try{ //for abs path - requestHandler.setRules(require(ruleFile)); - }catch(e){ //for relative path - requestHandler.setRules(require("./" + ruleFile)); - } - console.log(color.green("rule file loaded")); - }else{ - console.log(color.red("can not find rule file")); - } - }else{ - rules = require("./lib/rule_default.js"); - requestHandler.setRules(rules); - } async.series( [ @@ -82,12 +70,18 @@ function proxyServer(type, port, hostname,ruleFile){ } }, + //listen CONNECT method for https over http function(callback){ - //listen CONNECT method for https over http self.httpProxyServer.on('connect',requestHandler.connectReqHandler); self.httpProxyServer.listen(proxyPort); callback(null); + }, + + //start web interface + function(callback){ + startWebServer(); + callback(null); } ], @@ -104,6 +98,10 @@ function proxyServer(type, port, hostname,ruleFile){ } ); + self.close = function(){ + self.httpProxyServer && self.httpProxyServer.close(); + console.log(color.green("server closed :" + proxyHost + ":" + proxyPort)); + } } function startWebServer(port){ diff --git a/rule_sample/rule__blank.js b/rule_sample/rule__blank.js index e7f8f1e..6f46678 100644 --- a/rule_sample/rule__blank.js +++ b/rule_sample/rule__blank.js @@ -27,8 +27,7 @@ module.exports = { return newProtocol; }, - //req is user's request sent to the proxy server - //option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...}) + //req is user's request which will be sent to the proxy server, docs : http://nodejs.org/api/http.html#http_http_request_options_callback //you may return a customized option to replace the original option //you should not write content-length header in options, since anyproxy will handle it for you replaceRequestOption : function(req,option){