From bd6d4ded095be672fefda40708da4be1410a2c47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=83=B3=E5=BD=93=E5=BD=93?= <donghua.yan@alipay.com>
Date: Sun, 8 Mar 2015 12:00:39 +0800
Subject: [PATCH] add anyproxy install to install node modules

---
 README.md                                 | 19 ++++++++++++++-----
 bin.js                                    | 14 +++++++++++++-
 package.json                              |  5 +++--
 proxy.js                                  | 21 +++++++++++++--------
 rule_sample/rule_replace_response_data.js |  3 +--
 5 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md
index bb949a6..71fa712 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ Feature
 * a web interface for you to watch realtime request details, where html string with (almost) any charset could be shown correctly
 
 ![screenshot](http://gtms01.alicdn.com/tps/i1/TB1IdgqGXXXXXa9apXXLExM2pXX-854-480.gif)
- 
+
 Quick Start
 --------------
 
@@ -71,7 +71,7 @@ Https features
 After configuring rootCA, anyproxy could help to decrypt https requests, whose approach is also called Man-In-The-Middle(MITM).
 
 #### step 1 - install openssl
-* openssl is availabe here : [http://wiki.openssl.org/index.php/Compilation_and_Installation](http://wiki.openssl.org/index.php/Compilation_and_Installation) 
+* openssl is availabe here : [http://wiki.openssl.org/index.php/Compilation_and_Installation](http://wiki.openssl.org/index.php/Compilation_and_Installation)
 * using ``openssl version -a `` to make sure it is accessible via you command line.
 
 #### step 2 - generate a rootCA and trust it
@@ -96,8 +96,17 @@ After configuring rootCA, anyproxy could help to decrypt https requests, whose a
 
 Others
 -----------------
+#### to install node modules
 
-#### to save request data 
+* to install node modules for supporting rules development, use ``` anyproxy install ```
+* for example ``` anyproxy install underscore ```
+* and in rule file
+```
+var base = path.join(process.env.NODE_PATH,'anyproxy','node_modules');
+var underscore = require(path.join(base,'underscore'));
+```
+
+#### to save request data
 * 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.
 * [TrafficeRecorder](https://github.com/ottomao/TrafficRecorder) is another tool based on anyproxy to help recording all request data, including header and body. You may have a try.
@@ -118,7 +127,7 @@ var proxy = require("anyproxy");
 
 //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(); 
+!proxy.isRootCAFileExists() && proxy.generateRootCA();
 
 var options = {
     type          : "http",
@@ -129,7 +138,7 @@ var options = {
     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 
+    throttle      : 10,    // optional, speed limit in kb/s
     disableWebInterface : false //optional, set it when you don't want to use the web interface
 };
 new proxy.proxyServer(options);
diff --git a/bin.js b/bin.js
index 2b3f8da..91ade58 100644
--- a/bin.js
+++ b/bin.js
@@ -1,10 +1,10 @@
 #!/usr/bin/env node
 
 var program     = require('commander'),
-    proxy       = require("./proxy.js"),
     color       = require('colorful'),
     fs          = require("fs"),
     path        = require("path"),
+    npm         = require("npm"),
     packageInfo = require("./package.json");
 
 program
@@ -18,6 +18,7 @@ program
     .option('-l, --throttle [value]', 'throttle speed in kb/s (kbyte / sec)')
     .option('-i, --intercept', 'intercept(decrypt) https requests when root CA exists')
     .option('-c, --clear', 'clear all the tmp certificates')
+    .option('install', 'install node modules')
     .parse(process.argv);
 
 if(program.clear){
@@ -30,7 +31,18 @@ if(program.clear){
     require("./lib/certMgr").generateRootCA(function(){
         process.exit(0);
     });
+}else if(program.install){
+    npm.load({
+        "prefix": process.env.NODE_PATH + '/anyproxy/'
+    }, function (er) {
+        npm.commands.install(program.args || [], function (er, data) {
+            if(er)throw er;
+        })
+        npm.registry.log.on("log", function (message) {
+        })
+    });
 }else{
+    var proxy = require("./proxy.js");
     var ruleModule;
 
     if(program.rule){
diff --git a/package.json b/package.json
index 1492e0d..4f14acb 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "anyproxy",
-  "version": "3.2.2",
+  "version": "3.2.3",
   "description": "A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.",
   "main": "proxy.js",
   "bin": {
@@ -19,7 +19,8 @@
     "nedb": "^0.11.0",
     "qrcode-npm": "0.0.3",
     "stream-throttle": "^0.1.3",
-    "ws": "^0.4.32"
+    "ws": "^0.4.32",
+    "npm": "^2.7.0"
   },
   "devDependencies": {
     "proxy-eval": ">=1.1.1"
diff --git a/proxy.js b/proxy.js
index 34b1bb0..e26cd0c 100644
--- a/proxy.js
+++ b/proxy.js
@@ -48,7 +48,12 @@ try{
     if(fs.existsSync(path.join(process.cwd(),'rule.js'))){
         default_rule = require(path.join(process.cwd(),'rule'));
     }
-}catch(e){}
+}catch(e){
+    if(e){
+        console.log("error" + e);
+        throw e;
+    }
+}
 
 //option
 //option.type     : 'http'(default) or 'https'
@@ -59,7 +64,7 @@ try{
 //option.socketPort    : 8003(default)
 //option.webConfigPort : 8088(default)
 //option.dbFile        : null(default)
-//option.throttle      : null(default) 
+//option.throttle      : null(default)
 //option.disableWebInterface
 //option.interceptHttps ,internal param for https
 function proxyServer(option){
@@ -74,7 +79,7 @@ function proxyServer(option){
         socketPort          = option.socketPort    || DEFAULT_WEBSOCKET_PORT, //port for websocket
         proxyConfigPort     = option.webConfigPort || DEFAULT_CONFIG_PORT,    //port to ui config server
         disableWebInterface = !!option.disableWebInterface ;
-        
+
     if(option.dbFile){
         GLOBAL.recorder = new Recorder({filename: option.dbFile});
     }else{
@@ -113,7 +118,7 @@ function proxyServer(option){
                 }else{
                     self.httpProxyServer = http.createServer(requestHandler.userRequestHandler);
                     callback(null);
-                }        
+                }
             },
 
             //listen CONNECT method for https over http
@@ -197,7 +202,7 @@ function proxyServer(option){
                         console.log('AnyProxy is about to exit with code:', code);
                         process.exit();
                     });
-                    
+
                     process.on("uncaughtException",function(err){
                         child_webServer.kill();
                         console.log('Caught exception: ' + err);
@@ -230,7 +235,7 @@ function proxyServer(option){
         function(err,result){
             if(!err){
                 var tipText = (proxyType == T_TYPE_HTTP ? "Http" : "Https") + " proxy started at " + color.bold(ip.address() + ":" + proxyPort);
-                console.log(color.green(tipText)); 
+                console.log(color.green(tipText));
             }else{
                 var tipText = "err when start proxy server :(";
                 console.log(color.red(tipText));
@@ -311,7 +316,7 @@ function UIConfigServer(port){
             res.setHeader("Content-Type", "application/json;charset=UTF-8");
             res.end(JSON.stringify({success : true}));
 
-            requestHandler.setRules(customerRule);    
+            requestHandler.setRules(customerRule);
             self.emit("rule_changed");
         });
     });
@@ -327,4 +332,4 @@ inherits(UIConfigServer, events.EventEmitter);
 
 module.exports.proxyServer        = proxyServer;
 module.exports.generateRootCA     = certMgr.generateRootCA;
-module.exports.isRootCAFileExists = certMgr.isRootCAFileExists;
\ No newline at end of file
+module.exports.isRootCAFileExists = certMgr.isRootCAFileExists;
diff --git a/rule_sample/rule_replace_response_data.js b/rule_sample/rule_replace_response_data.js
index 0976ea2..c049ac6 100644
--- a/rule_sample/rule_replace_response_data.js
+++ b/rule_sample/rule_replace_response_data.js
@@ -3,7 +3,6 @@
 module.exports = {
 
     replaceServerResDataAsync: function(req,res,serverResData,callback){
-
         //append "hello world" to all web pages
         if(/html/i.test(res.headers['content-type'])){
             var newDataStr = serverResData.toString();
@@ -14,4 +13,4 @@ module.exports = {
         }
 
     }
-};
\ No newline at end of file
+};