From 5b52859900906269d8a25161f1a99821e1f406b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=B2=88=E8=BE=B0?= <changzheng.ycz@alibaba-inc.com>
Date: Sun, 3 Apr 2016 02:04:27 +0800
Subject: [PATCH] add global proxy

---
 bin.js              |   4 +-
 lib/proxyManager.js | 137 ++++++++++++++++++++++++++++++++++++++++++++
 proxy.js            |  19 ++++++
 3 files changed, 159 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 bin.js
 create mode 100644 lib/proxyManager.js

diff --git a/bin.js b/bin.js
old mode 100644
new mode 100755
index 6130849..d79aaac
--- a/bin.js
+++ b/bin.js
@@ -22,6 +22,7 @@ program
     .option('-i, --intercept', 'intercept(decrypt) https requests when root CA exists')
     .option('-s, --silent', 'do not print anything into terminal')
     .option('-c, --clear', 'clear all the tmp certificates')
+    .option('-o, --global', 'set as global proxy')
     .option('install', '[alpha] install node modules')
     .parse(process.argv);
 
@@ -67,7 +68,7 @@ if(program.clear){
             logUtil.printLog("failed to load rule file :" + e.toString(), logUtil.T_ERR);
         }
     }else{
-        //a feature for donghua.yan 
+        //a feature for donghua.yan
         //read rule file from a specific position
         (function(){
             try{
@@ -91,6 +92,7 @@ if(program.clear){
         webPort             : program.web,
         rule                : ruleModule,
         disableWebInterface : false,
+        globalProxy         : program.global,
         interceptHttps      : program.intercept,
         silent              : program.silent
     });
diff --git a/lib/proxyManager.js b/lib/proxyManager.js
new file mode 100644
index 0000000..18c6937
--- /dev/null
+++ b/lib/proxyManager.js
@@ -0,0 +1,137 @@
+var child_process = require('child_process');
+
+var networkTypes = ['Ethernet', 'Thunderbolt Ethernet', 'Wi-Fi'];
+
+function execSync(cmd) {
+	var stdout, status = 0;
+
+	try {
+		stdout = child_process.execSync(cmd);
+	} catch (err) {
+		stdout = err.stdout;
+		status = err.status;
+	}
+
+	return {
+		stdout: stdout.toString(),
+		status: status
+	};
+}
+
+
+/**
+ * ------------------------------------------------------------------------
+ * linux like system proxy manager
+ * ------------------------------------------------------------------------
+ */
+
+var unixLikeSysProxyManager = {};
+
+unixLikeSysProxyManager.getNetworkType = function() {
+
+	for (var i = 0; i < networkTypes.length; i++) {
+
+		var
+			type = networkTypes[i],
+			result = execSync('networksetup -getwebproxy ' + type);
+
+		if (result.status === 0) {
+			unixLikeSysProxyManager.networkType = type;
+			return type;
+		}
+	}
+
+	throw new Error('Unknown network type');
+};
+
+unixLikeSysProxyManager.enableGlobalProxy = function(ip, port) {
+
+	if (!ip && !port) {
+		console.log('proxy server\'s ip and port is required');
+		return;
+	};
+
+	var networkType = unixLikeSysProxyManager.networkType || unixLikeSysProxyManager.getNetworkType();
+
+	var result = execSync(
+
+		// set http proxy
+		'sudo networksetup -setwebproxy ${networkType} ${ip} ${port}; '
+			.replace("${networkType}", networkType)
+			.replace("${ip}", ip)
+			.replace("${port}", port) +
+
+		// set https proxy
+		'sudo networksetup -setsecurewebproxy ${networkType} ${ip} ${port}'
+			.replace("${networkType}", networkType)
+			.replace("${ip}", ip)
+			.replace("${port}", port));
+
+	return result;
+};
+
+unixLikeSysProxyManager.disableGlobalProxy = function() {
+	var networkType = unixLikeSysProxyManager.networkType || unixLikeSysProxyManager.getNetworkType();
+
+	var result = execSync(
+
+		// disable http proxy
+		'networksetup -setwebproxystate ${networkType} off; '
+			.replace(/\$\{networkType\}/g, networkType) +
+
+		// disable https proxy
+		'networksetup -setsecurewebproxystate ${networkType} off'
+			.replace(/\$\{networkType\}/g, networkType));
+
+	return result;
+};
+
+unixLikeSysProxyManager.getProxyState = function() {
+	var networkType = unixLikeSysProxyManager.networkType || unixLikeSysProxyManager.getNetworkType();
+	var result = execSync('networksetup -getwebproxy ${networkType}'.replace('${networkType}', networkType));
+
+	return result;
+};
+
+
+
+/**
+ * ------------------------------------------------------------------------
+ * windows proxy manager
+ * ------------------------------------------------------------------------
+ */
+
+var winSysProxyManager = {};
+
+winSysProxyManager.enableGlobalProxy = function(ip, port) {
+
+	if (!ip && !port) {
+		console.log('proxy server\'s ip and port is required');
+		return;
+	};
+
+	return execSync(
+
+			// set proxy
+			'reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyServer /t REG_SZ /d ${ip}:${port} /f & '
+				.replace("${ip}", ip)
+				.replace("${port}", port) +
+
+			// enable proxy
+			'reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable /t REG_DWORD /d 1 /f');
+
+};
+
+winSysProxyManager.disableGlobalProxy = function() {
+	return execSync('reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f');
+};
+
+winSysProxyManager.getProxyState = function() {
+	return '';
+};
+
+winSysProxyManager.getNetworkType = function() {
+	return '';
+};
+
+module.exports = /^win/.test(process.platform) ? winSysProxyManager : unixLikeSysProxyManager;
diff --git a/proxy.js b/proxy.js
index bfcdace..1634625 100644
--- a/proxy.js
+++ b/proxy.js
@@ -158,11 +158,30 @@ function proxyServer(option){
                 callback(null);
             },
 
+
+            function(callback) {
+
+                if (option.globalProxy) {
+                    var result = require('./lib/proxyManager').enableGlobalProxy(ip.address(), proxyPort);
+
+                    if (result.status) {
+                        console.log(color.red(result.stdout));
+                    }
+                }
+
+            },
+
             //server status manager
             function(callback){
 
                 process.on("exit",function(code){
                     logUtil.printLog('AnyProxy is about to exit with code: ' + code, logUtil.T_ERR);
+                    var result = require('./lib/proxyManager').disableGlobalProxy();
+
+                    if (result.status) {
+                        console.log(color.red(result.stdout));
+                    }
+
                     process.exit();
                 });