whistle 2.9.13 → 2.9.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/bin/proxy/cli.js +76 -0
- package/bin/proxy/index.d.ts +9 -0
- package/bin/proxy/index.js +49 -0
- package/bin/proxy/mac/Whistle +0 -0
- package/bin/proxy/mac/index.js +61 -0
- package/bin/proxy/win/index.js +32 -0
- package/bin/proxy/win/refresh.exe +0 -0
- package/bin/status.js +6 -6
- package/bin/use.js +2 -2
- package/bin/whistle.js +10 -5
- package/biz/index.js +1 -1
- package/biz/webui/cgi-bin/util.js +1 -1
- package/biz/webui/htdocs/index.html +1 -1
- package/biz/webui/htdocs/js/index.js +43 -43
- package/biz/webui/lib/index.js +3 -3
- package/lib/plugins/get-plugins-sync.js +1 -0
- package/lib/plugins/index.js +3 -1
- package/lib/plugins/load-plugin.js +2 -0
- package/lib/upgrade.js +1 -1
- package/lib/util/common.js +21 -0
- package/lib/util/index.js +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -179,6 +179,7 @@ Debugging mode:
|
|
|
179
179
|
For more details, please visit [install and start](https://avwo.github.io/whistle/install.html)
|
|
180
180
|
|
|
181
181
|
# Proxing Settings
|
|
182
|
+
> https://wproxy.org/whistle/proxy.html
|
|
182
183
|
##### configuring server & port
|
|
183
184
|
1. proxying server:127.0.0.1(if whistle is deployed in remote server or virtual machine, change this address to corresponding IP address)
|
|
184
185
|
2. default port:8899(if port 8899 is used already, you can specify new port using `-p` when start. More details can be visited by executing `whistle help` or `w2 help` (only supported in `v0.7.0` and higher version)
|
|
@@ -321,6 +322,7 @@ Open [Rules](http://local.whistlejs.com/) tab in whistle, and create a group nam
|
|
|
321
322
|
|
|
322
323
|
# Documentation
|
|
323
324
|
1. [Install and start](https://avwo.github.io/whistle/install.html)
|
|
325
|
+
1. [Setting proxy](https://wproxy.org/whistle/proxy.html)
|
|
324
326
|
2. [CLI operation](https://avwo.github.io/whistle/cli.html)
|
|
325
327
|
2. [How to update](https://avwo.github.io/whistle/update.html)
|
|
326
328
|
3. [Quickly start](https://avwo.github.io/whistle/quickstart.html)
|
package/bin/proxy/cli.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
var net = require('net');
|
|
2
|
+
var proxy = require('./index');
|
|
3
|
+
var util = require('../util');
|
|
4
|
+
|
|
5
|
+
var readConfig = util.readConfig;
|
|
6
|
+
var OFF_RE = /^(?:o|0|-{0,2}off)$/i;
|
|
7
|
+
var BYPASS_RE = /^(?:-{0,2}bypass|-x|-b)$/i;
|
|
8
|
+
var NUM_RE = /^\d+$/;
|
|
9
|
+
var HOST_SUFFIX_RE = /\:(\d+|auto)?$/;
|
|
10
|
+
var HOST_RE = /^[a-z\d_-]+(?:\.[a-z\d_-]+)*$/i;
|
|
11
|
+
|
|
12
|
+
function getDefaultPort() {
|
|
13
|
+
var conf = readConfig();
|
|
14
|
+
conf = conf && conf.options;
|
|
15
|
+
var port = conf && conf.port;
|
|
16
|
+
return port > 0 ? port : 8899;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function enableProxy(options) {
|
|
20
|
+
if (proxy.enableProxy(options)) {
|
|
21
|
+
util.info('Setting global proxy (' + options.host + ':' + options.port + ') successful.');
|
|
22
|
+
} else {
|
|
23
|
+
util.error('Failed to set global proxy (' + options.host + ':' + options.port + ').');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function disableProxy() {
|
|
28
|
+
if (proxy.disableProxy()) {
|
|
29
|
+
util.info('Turn off global proxy successful.');
|
|
30
|
+
} else {
|
|
31
|
+
util.error('Failed to turn off global proxy.');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = function(argv) {
|
|
36
|
+
var cmd = argv[0];
|
|
37
|
+
if (OFF_RE.test(cmd)) {
|
|
38
|
+
return disableProxy();
|
|
39
|
+
}
|
|
40
|
+
var options = {};
|
|
41
|
+
var skip;
|
|
42
|
+
argv.forEach(function(arg) {
|
|
43
|
+
if (skip) {
|
|
44
|
+
options.bypass = arg;
|
|
45
|
+
skip = false;
|
|
46
|
+
} else if (BYPASS_RE.test(arg)) {
|
|
47
|
+
skip = true;
|
|
48
|
+
} else if (NUM_RE.test(arg)) {
|
|
49
|
+
options.port = parseInt(arg, 10) || options.port;
|
|
50
|
+
} else if (net.isIP(arg)) {
|
|
51
|
+
options.host = arg || options.host;
|
|
52
|
+
} else if (HOST_SUFFIX_RE.test(arg)) {
|
|
53
|
+
var port = RegExp.$1;
|
|
54
|
+
delete options.port;
|
|
55
|
+
if (port > 0) {
|
|
56
|
+
options.port = parseInt(port, 10) || options.port;
|
|
57
|
+
}
|
|
58
|
+
var host = arg.slice(0, - port.length - 1);
|
|
59
|
+
if (host[0] === '[') {
|
|
60
|
+
host = host.substring(1);
|
|
61
|
+
}
|
|
62
|
+
var lastIndex = host.length - 1;
|
|
63
|
+
if (host[lastIndex] === ']') {
|
|
64
|
+
host = host.substring(0, lastIndex);
|
|
65
|
+
}
|
|
66
|
+
if (host && (net.isIP(host) || HOST_RE.test(host))) {
|
|
67
|
+
options.host = host || options.host;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
if (!options.port) {
|
|
72
|
+
options.port = getDefaultPort();
|
|
73
|
+
}
|
|
74
|
+
options.host = options.host || '127.0.0.1';
|
|
75
|
+
enableProxy(options);
|
|
76
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
var os = require('os');
|
|
2
|
+
var net = require('net');
|
|
3
|
+
var mac = require('./mac');
|
|
4
|
+
var win = require('./win');
|
|
5
|
+
|
|
6
|
+
var platform = os.platform();
|
|
7
|
+
var BYPASS_RE = /^[*a-z\d_-]+(?:\.[*a-z\d_-]+)*$/i;
|
|
8
|
+
|
|
9
|
+
function getBypass(bypass) {
|
|
10
|
+
if (!bypass || typeof bypass !== 'string') {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
var map = {};
|
|
14
|
+
bypass = bypass.trim().toLowerCase();
|
|
15
|
+
return bypass.split(/[\s,;]+/).filter(function(host) {
|
|
16
|
+
if (!map[host] && (host === '<local>' || net.isIP(host) || BYPASS_RE.test(host))) {
|
|
17
|
+
map[host] = 1;
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// only support mac & win
|
|
25
|
+
function getProxyMgr() {
|
|
26
|
+
if (platform === 'win32') {
|
|
27
|
+
return win;
|
|
28
|
+
}
|
|
29
|
+
if (platform === 'darwin') {
|
|
30
|
+
return mac;
|
|
31
|
+
}
|
|
32
|
+
throw new Error('Platform ' + platform + ' is unsupported to set global proxy for now.');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
exports.enableProxy = function(options) {
|
|
36
|
+
var host = options.host.toLowerCase();
|
|
37
|
+
var enableProxy = getProxyMgr().enableProxy;
|
|
38
|
+
var bypass = getBypass(options.bypass);
|
|
39
|
+
return enableProxy({
|
|
40
|
+
host: host,
|
|
41
|
+
port: options.port,
|
|
42
|
+
bypass: bypass
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
exports.disableProxy = function() {
|
|
47
|
+
var disableProxy = getProxyMgr().disableProxy;
|
|
48
|
+
return disableProxy();
|
|
49
|
+
};
|
|
Binary file
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
var execSync = require('child_process').execSync;
|
|
2
|
+
var join = require('path').join;
|
|
3
|
+
|
|
4
|
+
var PROXY_HELPER = join(__dirname, 'Whistle');
|
|
5
|
+
|
|
6
|
+
function getProxyServer(isSecure) {
|
|
7
|
+
var str = execSync('networksetup -get' + (isSecure ? 'secure' : '') + 'webproxy "Wi-Fi"') + '';
|
|
8
|
+
var result = {};
|
|
9
|
+
str.split(/[\r\n]+/).forEach(function(line) {
|
|
10
|
+
var index = line.indexOf(':');
|
|
11
|
+
var key = line.substring(0, index).trim().toLowerCase();
|
|
12
|
+
var value = line.substring(index + 1).trim().toLowerCase();
|
|
13
|
+
if (key === 'enabled') {
|
|
14
|
+
result.enabled = value === 'yes';
|
|
15
|
+
} else if (key === 'server') {
|
|
16
|
+
result.host = value;
|
|
17
|
+
} else if (key === 'port') {
|
|
18
|
+
result.port = value;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getCurProxy() {
|
|
25
|
+
return {
|
|
26
|
+
http: getProxyServer(),
|
|
27
|
+
https: getProxyServer(true)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function checkProxy(p1, p2) {
|
|
32
|
+
if (!p1.enabled) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return p1.host == p2.host && p1.port == p2.port;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
exports.enableProxy = function(options) {
|
|
39
|
+
var bypass = options.bypass;
|
|
40
|
+
var port = options.port;
|
|
41
|
+
if (bypass) {
|
|
42
|
+
bypass = ' -x "' + bypass + '"';
|
|
43
|
+
} else {
|
|
44
|
+
bypass = '';
|
|
45
|
+
}
|
|
46
|
+
execSync('\'' + PROXY_HELPER + '\' -m global -p ' + port + ' -r ' + port + ' -s ' + options.host + bypass);
|
|
47
|
+
try {
|
|
48
|
+
var curProxy = getCurProxy();
|
|
49
|
+
return checkProxy(curProxy.http, options) && checkProxy(curProxy.https, options);
|
|
50
|
+
} catch (e) {}
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
exports.disableProxy = function() {
|
|
55
|
+
execSync('\'' + PROXY_HELPER + '\' -m off');
|
|
56
|
+
try {
|
|
57
|
+
var curProxy = getCurProxy();
|
|
58
|
+
return !curProxy.http.enabled && !curProxy.https.enabled;
|
|
59
|
+
} catch (e) {}
|
|
60
|
+
return true;
|
|
61
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
var execSync = require('child_process').execSync;
|
|
2
|
+
var join = require('path').join;
|
|
3
|
+
|
|
4
|
+
var REFRESH_PROXY = join(__dirname, 'refresh');
|
|
5
|
+
var REG_PATH = 'reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v';
|
|
6
|
+
|
|
7
|
+
function disableProxy() {
|
|
8
|
+
var proxyCmd = REG_PATH + ' ProxyEnable /t REG_DWORD /d 0 /f';
|
|
9
|
+
var pacCmd = REG_PATH + ' AutoConfigURL /t REG_DWORD /d 0 /f';
|
|
10
|
+
var detectCmd = REG_PATH + ' AutoDetect /t REG_DWORD /d 0 /f';
|
|
11
|
+
execSync(proxyCmd + ' & ' + pacCmd + ' & ' + detectCmd);
|
|
12
|
+
execSync(REFRESH_PROXY);
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.enableProxy = function(options) {
|
|
17
|
+
disableProxy();
|
|
18
|
+
var bypass = options.bypass;
|
|
19
|
+
var setCmd = REG_PATH + ' ProxyServer /t REG_SZ /d ' + options.host + ':' + options.port + ' /f';
|
|
20
|
+
var enableCmd = REG_PATH + ' ProxyEnable /t REG_DWORD /d 1 /f';
|
|
21
|
+
var cmd = setCmd + ' & ' + enableCmd;
|
|
22
|
+
|
|
23
|
+
if (bypass) {
|
|
24
|
+
bypass = REG_PATH + ' ProxyOverride /t REG_SZ /d "' + bypass.join(';') + '" /f';
|
|
25
|
+
cmd = cmd + ' & ' + bypass;
|
|
26
|
+
}
|
|
27
|
+
execSync(cmd);
|
|
28
|
+
execSync(REFRESH_PROXY);
|
|
29
|
+
return true;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
exports.disableProxy = disableProxy;
|
|
Binary file
|
package/bin/status.js
CHANGED
|
@@ -26,15 +26,15 @@ function showAll(byStop) {
|
|
|
26
26
|
if (!len) {
|
|
27
27
|
warn('[!] No running whistle.');
|
|
28
28
|
} else {
|
|
29
|
-
var tips = [
|
|
29
|
+
var tips = ['[i] All running whistle:'];
|
|
30
30
|
confList.forEach(function(conf, i) {
|
|
31
31
|
++i;
|
|
32
32
|
var options = conf.options;
|
|
33
|
-
tips.push(' ' + i + '.
|
|
34
|
-
+
|
|
35
|
-
+ (options.
|
|
36
|
-
+ (
|
|
37
|
-
+ (byStop ? colors.red(' (
|
|
33
|
+
tips.push(' ' + i + '.' + (conf.pid ? ' PID: ' + conf.pid + ',' : '')
|
|
34
|
+
+ ' Port: ' + (options.port || pkg.port)
|
|
35
|
+
+ (options.host ? ', Host: ' + options.host : '')
|
|
36
|
+
+ (options.storage ? ', Storage: ' + options.storage : '')
|
|
37
|
+
+ (byStop ? colors.red(' (Stop cmd: ' + (options.storage ? 'w2 stop -S ' + options.storage : 'w2 stop') + ')') : ''));
|
|
38
38
|
});
|
|
39
39
|
byStop && warn('[!] This whistle is not running.');
|
|
40
40
|
info(tips.join('\n'));
|
package/bin/use.js
CHANGED
|
@@ -113,7 +113,7 @@ function checkDefault(running, storage, callback) {
|
|
|
113
113
|
module.exports = function(filepath, storage, force) {
|
|
114
114
|
storage = storage || '';
|
|
115
115
|
var config = readConfig(storage) || '';
|
|
116
|
-
options = config.options;
|
|
116
|
+
options = config.options;
|
|
117
117
|
var pid = options && config.pid;
|
|
118
118
|
var addon = options && options.addon;
|
|
119
119
|
var conf = require('../lib/config');
|
|
@@ -151,7 +151,7 @@ module.exports = function(filepath, storage, force) {
|
|
|
151
151
|
'rules=' + encodeURIComponent(rules)
|
|
152
152
|
].join('&');
|
|
153
153
|
request(body, function() {
|
|
154
|
-
info('Setting whistle
|
|
154
|
+
info('Setting whistle (' + (options.host || '127.0.0.1') + ':' + port + ') rules successful.');
|
|
155
155
|
});
|
|
156
156
|
};
|
|
157
157
|
if (force) {
|
package/bin/whistle.js
CHANGED
|
@@ -7,6 +7,7 @@ var useRules = require('./use');
|
|
|
7
7
|
var showStatus = require('./status');
|
|
8
8
|
var util = require('./util');
|
|
9
9
|
var plugin = require('./plugin');
|
|
10
|
+
var setProxy = require('./proxy/cli');
|
|
10
11
|
|
|
11
12
|
var showUsage = util.showUsage;
|
|
12
13
|
var error = util.error;
|
|
@@ -80,15 +81,17 @@ program
|
|
|
80
81
|
.command('status')
|
|
81
82
|
.description('Show the running status');
|
|
82
83
|
program
|
|
83
|
-
.command('add
|
|
84
|
+
.command('add')
|
|
84
85
|
.description('Add rules from local js file (.whistle.js by default)');
|
|
86
|
+
program.command('proxy')
|
|
87
|
+
.description('Set global proxy');
|
|
85
88
|
program.command('install')
|
|
86
|
-
.description('Install
|
|
89
|
+
.description('Install whistle plugin');
|
|
87
90
|
program.command('uninstall')
|
|
88
|
-
.description('Uninstall
|
|
91
|
+
.description('Uninstall whistle plugin');
|
|
89
92
|
program.command('exec')
|
|
90
|
-
.description('Exec whistle plugin
|
|
91
|
-
|
|
93
|
+
.description('Exec whistle plugin cmd');
|
|
94
|
+
|
|
92
95
|
program
|
|
93
96
|
.option('-D, --baseDir [baseDir]', 'set the configured storage root path', String, undefined)
|
|
94
97
|
.option('-z, --certDir [directory]', 'set custom certificate store directory', String, undefined)
|
|
@@ -138,6 +141,8 @@ if (cmd === 'status') {
|
|
|
138
141
|
storage = argv[4];
|
|
139
142
|
}
|
|
140
143
|
showStatus(all, storage);
|
|
144
|
+
} else if (cmd === 'proxy') {
|
|
145
|
+
setProxy(Array.prototype.slice.call(argv, 3));
|
|
141
146
|
} else if (/^([a-z]{1,2})?uni(nstall)?$/.test(cmd)) {
|
|
142
147
|
plugin.uninstall(Array.prototype.slice.call(argv, 3));
|
|
143
148
|
} else if (/^([a-z]{1,2})?i(nstall)?$/.test(cmd)) {
|
package/biz/index.js
CHANGED
|
@@ -138,7 +138,7 @@ module.exports = function(req, res, next) {
|
|
|
138
138
|
} else if (localRule = rules.resolveLocalRule(req)) {
|
|
139
139
|
req.url = localRule.url;
|
|
140
140
|
if (localRule.realPort) {
|
|
141
|
-
req.headers.host = '127.0.0.1:' + localRule.realPort;
|
|
141
|
+
req.headers.host = '127.0.0.1:' + localRule.realPort;
|
|
142
142
|
util.transformReq(req, res, localRule.realPort);
|
|
143
143
|
} else {
|
|
144
144
|
handleUIReq(req, res);
|
|
@@ -148,7 +148,7 @@ exports.sendGzip = function(req, res, data) {
|
|
|
148
148
|
res.json(data);
|
|
149
149
|
} catch (e) {
|
|
150
150
|
res.status(500).send(config.debugMode ?
|
|
151
|
-
'<pre>' + util.getErrorStack(err) + '</pre>' : 'Internal Server Error');
|
|
151
|
+
'<pre>' + util.encodeHtml(util.getErrorStack(err)) + '</pre>' : 'Internal Server Error');
|
|
152
152
|
}
|
|
153
153
|
return;
|
|
154
154
|
}
|