whistle 2.9.14 → 2.9.15-beta

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/bin/ca/cli.js ADDED
@@ -0,0 +1,95 @@
1
+ var net = require('net');
2
+ var fs = require('fs');
3
+ var path = require('path');
4
+ var installRootCA = require('./index');
5
+ var util = require('../util');
6
+ var fileMgr = require('../../lib/util/file-mgr');
7
+ var httpMgr = require('../../lib/util/http-mgr');
8
+ var commonUtil = require('../../lib/util/common');
9
+ var config = require('../../lib/config');
10
+
11
+ var NUM_RE = /^\d+$/;
12
+ var HOST_SUFFIX_RE = /\:(\d+|auto)?$/;
13
+ var HOST_RE = /^[a-z\d_-]+(?:\.[a-z\d_-]+)*$/i;
14
+ var URL_RE = /^https?:\/\/./i;
15
+ var MAX_LEN = 1024 * 1024;
16
+
17
+ function installCert(certFile, url) {
18
+ try {
19
+ installRootCA(fileMgr.convertSlash(certFile));
20
+ util.info('Install root CA (' + (url || certFile) + ') successful.');
21
+ } catch (e) {
22
+ util.error(e.message);
23
+ }
24
+ }
25
+
26
+ function install(addr) {
27
+ if (addr.file) {
28
+ return installCert(addr.file);
29
+ }
30
+ addr.needRawData = true;
31
+ addr.maxLength = MAX_LEN;
32
+ addr.headers = {
33
+ 'user-agent': 'whistle/' + config.name
34
+ };
35
+ httpMgr.request(addr, function(err, body, res) {
36
+ if (err) {
37
+ return util.error(err.message);
38
+ }
39
+ if (res.statusCode != 200) {
40
+ return util.error('Bad response (' + res.statusCode + ').');
41
+ }
42
+ if (!body || !body.length) {
43
+ return util.error('No content.');
44
+ }
45
+ var tempFile = path.join(commonUtil.getWhistlePath(), Date.now() + '-' + util.getHash(addr.url) + '.crt');
46
+ fs.writeFileSync(tempFile, body);
47
+ installCert(tempFile, addr.url);
48
+ fs.unlinkSync(tempFile);
49
+ });
50
+ }
51
+
52
+ module.exports = function(argv) {
53
+ var options = {};
54
+ argv.forEach(function(arg) {
55
+ if (NUM_RE.test(arg)) {
56
+ delete options.addr;
57
+ options.port = parseInt(arg, 10) || options.port;
58
+ } else if (net.isIP(arg)) {
59
+ delete options.addr;
60
+ options.host = arg || options.host;
61
+ } else if (HOST_SUFFIX_RE.test(arg)) {
62
+ delete options.port;
63
+ delete options.addr;
64
+ var port = RegExp.$1;
65
+ if (port > 0) {
66
+ options.port = parseInt(port, 10) || options.port;
67
+ }
68
+ var host = arg.slice(0, - port.length - 1);
69
+ if (host[0] === '[') {
70
+ host = host.substring(1);
71
+ }
72
+ var lastIndex = host.length - 1;
73
+ if (host[lastIndex] === ']') {
74
+ host = host.substring(0, lastIndex);
75
+ }
76
+ if (host && (net.isIP(host) || HOST_RE.test(host))) {
77
+ options.host = host || options.host;
78
+ }
79
+ } else {
80
+ delete options.port;
81
+ delete options.host;
82
+ if (URL_RE.test(arg)) {
83
+ options.addr = { url: arg };
84
+ } else {
85
+ options.addr = { file: arg };
86
+ }
87
+ }
88
+ });
89
+ if (!options.addr) {
90
+ var host = options.host || '127.0.0.1';
91
+ var port = options.port || util.getDefaultPort();
92
+ options.addr = { url: 'http://' + host + ':' + port + '/cgi-bin/rootca' };
93
+ }
94
+ install(options.addr);
95
+ };
@@ -0,0 +1 @@
1
+ export default function (certFile: String): void;
@@ -0,0 +1,43 @@
1
+ var spawnSync = require('child_process').spawnSync;
2
+
3
+ function checkSuccess(result) {
4
+ var stderr = result.stderr;
5
+ if (stderr && stderr.length) {
6
+ throw new Error(stderr + '');
7
+ }
8
+ }
9
+
10
+ function getKeyChain() {
11
+ var result = spawnSync('security', ['default-keychain']);
12
+ checkSuccess(result);
13
+ return (result.stdout + '').split('"')[1];
14
+ }
15
+
16
+ function installMac(certPath) {
17
+ var result = spawnSync('security', ['add-trusted-cert', '-k', getKeyChain(), certPath]);
18
+ checkSuccess(result);
19
+ var msg = result.stdout + '';
20
+ if (/Error:/i.test(msg)) {
21
+ throw new Error(msg);
22
+ }
23
+ }
24
+
25
+
26
+ function installWin(certFile) {
27
+ var result = spawnSync('certutil', ['-addstore', '-user', 'Root', certFile]);
28
+ checkSuccess(result);
29
+ if (/ERROR_CANCELLED/i.test(result.stdout + '')) {
30
+ throw new Error('The authorization was canceled by the user.');
31
+ }
32
+ }
33
+
34
+ module.exports = function(certFile) {
35
+ var platform = process.platform;
36
+ if (platform === 'darwin') {
37
+ return installMac(certFile);
38
+ }
39
+ if (platform === 'win32') {
40
+ return installWin(certFile);
41
+ }
42
+ throw new Error('Platform ' + platform + ' is unsupported to install root CA for now.');
43
+ };
package/bin/proxy/cli.js CHANGED
@@ -2,33 +2,33 @@ var net = require('net');
2
2
  var proxy = require('./index');
3
3
  var util = require('../util');
4
4
 
5
- var readConfig = util.readConfig;
6
5
  var OFF_RE = /^(?:o|0|-{0,2}off)$/i;
7
6
  var BYPASS_RE = /^(?:-{0,2}bypass|-x|-b)$/i;
8
7
  var NUM_RE = /^\d+$/;
9
8
  var HOST_SUFFIX_RE = /\:(\d+|auto)?$/;
10
9
  var HOST_RE = /^[a-z\d_-]+(?:\.[a-z\d_-]+)*$/i;
11
10
 
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
11
  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 + ').');
12
+ try {
13
+ if (proxy.enableProxy(options)) {
14
+ util.info('Setting global proxy (' + options.host + ':' + options.port + ') successful.');
15
+ } else {
16
+ util.error('Failed to set global proxy (' + options.host + ':' + options.port + ').');
17
+ }
18
+ } catch (e) {
19
+ util.error(e.message);
24
20
  }
25
21
  }
26
22
 
27
23
  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.');
24
+ try {
25
+ if (proxy.disableProxy()) {
26
+ util.info('Turn off global proxy successful.');
27
+ } else {
28
+ util.error('Failed to turn off global proxy.');
29
+ }
30
+ } catch (e) {
31
+ util.error(e.message);
32
32
  }
33
33
  }
34
34
 
@@ -69,7 +69,7 @@ module.exports = function(argv) {
69
69
  }
70
70
  });
71
71
  if (!options.port) {
72
- options.port = getDefaultPort();
72
+ options.port = util.getDefaultPort();
73
73
  }
74
74
  options.host = options.host || '127.0.0.1';
75
75
  enableProxy(options);
package/bin/util.js CHANGED
@@ -7,12 +7,13 @@ var config = require('../lib/config');
7
7
  var colors = require('colors/safe');
8
8
  var path = require('path');
9
9
  var createHmac = require('crypto').createHmac;
10
+
10
11
  /*eslint no-console: "off"*/
11
12
  var CHECK_RUNNING_CMD = process.platform === 'win32' ?
12
13
  'tasklist /fi "PID eq %s" | findstr /i "node.exe"'
13
14
  : 'ps -f -p %s | grep "node"';
14
15
  var isWin = process.platform === 'win32';
15
-
16
+
16
17
  function isRunning(pid, callback) {
17
18
  pid ? cp.exec(util.format(CHECK_RUNNING_CMD, pid),
18
19
  function (err, stdout, stderr) {
@@ -88,6 +89,15 @@ function showUsage(isRunning, options, restart) {
88
89
  if (parseInt(process.version.slice(1), 10) < 6) {
89
90
  warn(colors.bold('\nWarning: The current Node version is too low, access https://nodejs.org to install the latest version, or may not be able to Capture HTTPS CONNECTs\n'));
90
91
  }
92
+ var bypass = options.init;
93
+ if (bypass == null) {
94
+ return;
95
+ }
96
+ return {
97
+ host: options.host || '127.0.0.1',
98
+ port: port,
99
+ bypass: typeof bypass === 'string' ? bypass : undefined
100
+ };
91
101
  }
92
102
 
93
103
  exports.showUsage = showUsage;
@@ -146,4 +156,11 @@ exports.readConfigList = readConfigList;
146
156
  exports.getHash = function(str) {
147
157
  var hmac = createHmac('sha256', 'a secret');
148
158
  return hmac.update(str).digest('hex');
149
- };
159
+ };
160
+
161
+ exports.getDefaultPort = function () {
162
+ var conf = readConfig();
163
+ conf = conf && conf.options;
164
+ var port = conf && conf.port;
165
+ return port > 0 ? port : 8899;
166
+ };
package/bin/whistle.js CHANGED
@@ -8,14 +8,28 @@ var showStatus = require('./status');
8
8
  var util = require('./util');
9
9
  var plugin = require('./plugin');
10
10
  var setProxy = require('./proxy/cli');
11
+ var installCA = require('./ca/cli');
11
12
 
12
- var showUsage = util.showUsage;
13
13
  var error = util.error;
14
14
  var info = util.info;
15
15
 
16
+ function handleEnd(err, options, restart) {
17
+ options = util.showUsage(err, options, restart);
18
+ if (!options) {
19
+ return;
20
+ }
21
+ var host = options.host + ':' + options.port;
22
+ var argv = [host];
23
+ if (options.bypass) {
24
+ argv.push('-x', options.bypass);
25
+ }
26
+ setProxy(argv);
27
+ installCA([host]);
28
+ }
29
+
16
30
  function showStartupInfo(err, options, debugMode, restart) {
17
31
  if (!err || err === true) {
18
- return showUsage(err, options, restart);
32
+ return handleEnd(err, options, restart);
19
33
  }
20
34
  if (/listen EADDRINUSE/.test(err)) {
21
35
  options = util.formatOptions(options);
@@ -55,7 +69,7 @@ program.setConfig({
55
69
  showStartupInfo(err, options, true);
56
70
  return;
57
71
  }
58
- showUsage(false, options);
72
+ handleEnd(false, options);
59
73
  console.log('Press [Ctrl+C] to stop ' + config.name + '...');
60
74
  },
61
75
  startCallback: showStartupInfo,
@@ -85,6 +99,8 @@ program
85
99
  .description('Add rules from local js file (.whistle.js by default)');
86
100
  program.command('proxy')
87
101
  .description('Set global proxy');
102
+ program.command('ca')
103
+ .description('Install root CA');
88
104
  program.command('install')
89
105
  .description('Install whistle plugin');
90
106
  program.command('uninstall')
@@ -117,6 +133,7 @@ program
117
133
  .option('-R, --reqCacheSize [reqCacheSize]', 'set the cache size of request data (600 by default)', String, undefined)
118
134
  .option('-F, --frameCacheSize [frameCacheSize]', 'set the cache size of webSocket and socket\'s frames (512 by default)', String, undefined)
119
135
  .option('-A, --addon [pluginPaths]', 'add custom plugin paths', String, undefined)
136
+ .option('--init [bypass]', 'auto set global proxy (and bypass) and install root CA')
120
137
  .option('--config [workers]', 'start the cluster server and set worker number (os.cpus().length by default)', String, undefined)
121
138
  .option('--cluster [config]', 'load the startup config from a local file', String, undefined)
122
139
  .option('--dnsServer [dnsServer]', 'set custom dns servers', String, undefined)
@@ -143,6 +160,8 @@ if (cmd === 'status') {
143
160
  showStatus(all, storage);
144
161
  } else if (cmd === 'proxy') {
145
162
  setProxy(Array.prototype.slice.call(argv, 3));
163
+ } else if (cmd === 'ca') {
164
+ installCA(Array.prototype.slice.call(argv, 3));
146
165
  } else if (/^([a-z]{1,2})?uni(nstall)?$/.test(cmd)) {
147
166
  plugin.uninstall(Array.prototype.slice.call(argv, 3));
148
167
  } else if (/^([a-z]{1,2})?i(nstall)?$/.test(cmd)) {
@@ -8,6 +8,6 @@
8
8
  </head>
9
9
  <body style="overscroll-behavior-x: none;">
10
10
  <div id="container" class="main"></div>
11
- <script src="js/index.js?v=2.9.14"></script>
11
+ <script src="js/index.js?v=2.9.15"></script>
12
12
  </body>
13
13
  </html>