whistle 2.10.1 → 2.10.3

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.
Files changed (46) hide show
  1. package/assets/js/log.js +44 -27
  2. package/assets/menu.html +2 -0
  3. package/assets/modal.html +2 -0
  4. package/assets/tab.html +3 -3
  5. package/bin/use.js +236 -101
  6. package/bin/util.js +10 -7
  7. package/bin/whistle.js +5 -5
  8. package/biz/webui/cgi-bin/download.js +1 -1
  9. package/biz/webui/cgi-bin/get-data.js +0 -5
  10. package/biz/webui/cgi-bin/init.js +0 -2
  11. package/biz/webui/cgi-bin/rules/clear-dns-cache.js +7 -0
  12. package/biz/webui/htdocs/index.html +2 -2
  13. package/biz/webui/htdocs/js/index.js +53 -50
  14. package/biz/webui/lib/index.js +49 -4
  15. package/lib/config.js +6 -4
  16. package/lib/handlers/file-proxy.js +1 -1
  17. package/lib/https/ca.js +39 -9
  18. package/lib/https/index.js +109 -114
  19. package/lib/index.js +1 -5
  20. package/lib/inspectors/data.js +119 -13
  21. package/lib/inspectors/log.js +4 -0
  22. package/lib/inspectors/req.js +5 -3
  23. package/lib/inspectors/weinre.js +7 -2
  24. package/lib/plugins/get-plugins-sync.js +15 -11
  25. package/lib/plugins/get-plugins.js +11 -12
  26. package/lib/plugins/load-plugin.js +1 -1
  27. package/lib/plugins/module-paths.js +4 -0
  28. package/lib/plugins/util.js +8 -0
  29. package/lib/rules/dns.js +4 -0
  30. package/lib/rules/index.js +0 -1
  31. package/lib/rules/protocols.js +3 -9
  32. package/lib/rules/rules.js +21 -22
  33. package/lib/service/composer.js +10 -5
  34. package/lib/{util/log-server.js → service/console-log.js} +37 -34
  35. package/lib/service/index.js +2 -4
  36. package/lib/service/service.js +64 -15
  37. package/lib/service/util.js +3 -42
  38. package/lib/socket-mgr.js +2 -16
  39. package/lib/tunnel.js +2 -4
  40. package/lib/upgrade.js +1 -1
  41. package/lib/util/common.js +115 -17
  42. package/lib/util/index.js +48 -40
  43. package/package.json +2 -2
  44. package/biz/webui/cgi-bin/import-remote.js +0 -37
  45. package/biz/webui/cgi-bin/log/set.js +0 -7
  46. package/lib/util/parse-query.js +0 -35
@@ -20,6 +20,7 @@ var common = require('../../../lib/util/common');
20
20
  var getWorker = require('../../../lib/plugins/util').getWorker;
21
21
  var loadAuthPlugins = require('../../../lib/plugins').loadAuthPlugins;
22
22
  var parseUrl = require('../../../lib/util/parse-url-safe');
23
+ var loadService = require('../../../lib/service');
23
24
 
24
25
  var sendError = cgiUtil.sendError;
25
26
  var sendGzipText = cgiUtil.sendGzipText;
@@ -55,12 +56,32 @@ var MENU_URL = '???_WHISTLE_PLUGIN_EXT_CONTEXT_MENU_' + config.port + '???';
55
56
  var INSPECTOR_URL = '???_WHISTLE_PLUGIN_INSPECTOR_TAB_' + config.port + '???';
56
57
  var KEY_RE_G = /\${[^{}\s]+}|{\S+}/g;
57
58
  var COMMENT_RE = /#[^\r\n]*$/mg;
59
+ var MAX_LEN = 1024 * 1024 * 6;
60
+ var HTTP_RE = /https?:\/\/\S/i;
61
+
62
+ function hasLogin() {
63
+ return config.username && config.password;
64
+ }
65
+
66
+ function isTempFile(query) {
67
+ var files = query.files;
68
+ if (files && typeof files === 'string') {
69
+ return false;
70
+ }
71
+ return common.getTempFile(query.filename);
72
+ }
58
73
 
59
74
  function sendToService(req, res) {
60
- proxyEvent.loadService(function(err, options) {
75
+ if (!hasLogin() && req.path === '/cgi-bin/temp/get' && !isTempFile(req.query)) {
76
+ res.setHeader('Content-Type', 'application/json; charset=utf-8');
77
+ res.end('{"ec":0,"value":"","forbidden":true}');
78
+ return;
79
+ }
80
+ loadService(function(err, options) {
61
81
  if (err) {
62
82
  common.sendRes(res, 500, err.stack || err);
63
83
  } else {
84
+ req.headers[common.WHISTLE_UID_HEADER] = config.uid;
64
85
  util.transformReq(req, res, options.port);
65
86
  }
66
87
  });
@@ -390,13 +411,37 @@ function cgiHandler(req, res) {
390
411
  handleResponse();
391
412
  });
392
413
  }
414
+ app.get('/cgi-bin/import-remote', function(req, res) {
415
+ var url = req.query.url;
416
+ if (HTTP_RE.test(url)) {
417
+ util.request({
418
+ url: url,
419
+ maxLength: MAX_LEN
420
+ }, function(err, body, r) {
421
+ if (err) {
422
+ var msg = err.code === 'EEXCEED' ? 'The size of response body exceeds 6MB' : err.message;
423
+ return res.json({ec: 2, em: msg});
424
+ }
425
+ var status = r.statusCode;
426
+ if (status !== 200) {
427
+ var em = status > 200 && status < 400 ? 'No data' : 'Request failed';
428
+ return res.json({ec: 2, em: em + ' (statusCode: ' + status + ')'});
429
+ }
430
+ return res.json({ec: 0, body: body});
431
+ });
432
+ } else if (util.isString(url)) {
433
+ req.url = '/cgi-bin/temp/get?filename=' + encodeURIComponent(url);
434
+ req.query.filename = url;
435
+ sendToService(req, res);
436
+ } else {
437
+ res.json({ec: 400, em: 'Bad url'});
438
+ }
439
+ });
393
440
  app.all('/service/*', sendToService);
394
441
  app.all('/cgi-bin/service/*', sendToService);
395
442
  app.all('/cgi-bin/sessions/*', sendToService);
443
+ app.all('/cgi-bin/log/*', sendToService);
396
444
  app.post('/cgi-bin/plugins/install', sendToService);
397
- app.all('/favicon.ico', function(req, res) {
398
- res.sendFile(htdocs.getImgFile('favicon.ico'));
399
- });
400
445
 
401
446
  function readPluginPage(req, res, plugin, html, config) {
402
447
  res.type('html');
package/lib/config.js CHANGED
@@ -148,15 +148,17 @@ function getDataDir(dirname) {
148
148
  }
149
149
 
150
150
  config.baseDir = getDataDir();
151
- config.TEMP_FILES_PATH = path.join(getWhistlePath(), 'temp_files');
152
151
  config.CUSTOM_PLUGIN_PATH = path.join(getWhistlePath(), 'custom_plugins');
153
152
  config.CUSTOM_CERTS_DIR = path.resolve(getWhistlePath(), 'custom_certs');
154
153
  config.SAVED_SESSIONS_PATH = path.resolve(getWhistlePath(), 'saved_sessions');
155
154
  config.DEV_PLUGINS_PATH = path.resolve(getWhistlePath(), 'dev_plugins');
155
+ config.rulesDir = path.join(config.baseDir, 'rules');
156
+ config.valuesDir = path.join(config.baseDir, 'values');
157
+ config.propertiesDir = path.join(config.baseDir, 'properties');
156
158
 
157
159
  try {
158
- fse.ensureDirSync(config.TEMP_FILES_PATH);
159
- var blankFile = path.join(config.TEMP_FILES_PATH, 'blank');
160
+ fse.ensureDirSync(common.TEMP_FILES_PATH);
161
+ var blankFile = path.join(common.TEMP_FILES_PATH, 'blank');
160
162
  if (!fs.existsSync(blankFile)) {
161
163
  fs.writeFileSync(blankFile, '');
162
164
  }
@@ -793,7 +795,7 @@ exports.extend = function (newConf) {
793
795
  setDefaultResultOrder(m.toLowerCase());
794
796
  } else if (m === 'proxyOnly') {
795
797
  config.pureProxy = true;
796
- } else if (m === 'useMultipleRules' || m === 'enableMultipleRules') {
798
+ } else if (m === 'useMultipleRules' || m === 'enableMultipleRules' || m === 'allowMultipleChoice') {
797
799
  config.allowMultipleChoice = true;
798
800
  } else if (m === 'disableMultipleRules') {
799
801
  config.allowMultipleChoice = false;
@@ -66,7 +66,7 @@ function parseRes(str, rawHeaderNames, fromValue) {
66
66
  };
67
67
  }
68
68
  var headers = str.split(CRLF_RE);
69
- var statusLine = headers.shift().trim().split(/\s+/g);
69
+ var statusLine = headers.shift().trim().split(/\s+/);
70
70
  headers = util.parseHeaders(headers, rawHeaderNames);
71
71
  if (fromValue) {
72
72
  delete headers['content-encoding'];
package/lib/https/ca.js CHANGED
@@ -15,8 +15,6 @@ var common = require('../util/common');
15
15
  var rulesUtil = require('../rules/util');
16
16
 
17
17
  var pki = forge.pki;
18
- var CUR_VERSION = process.version;
19
- var requiredVersion = parseInt(CUR_VERSION.slice(1), 10) >= 6;
20
18
  var HTTPS_DIR = mkdir(path.join(config.getDataDir(), 'certs'));
21
19
  var ROOT_NEW_KEY_FILE = path.join(HTTPS_DIR, 'root_new.key');
22
20
  var ROOT_NEW_CRT_FILE = path.join(HTTPS_DIR, 'root_new.crt');
@@ -40,6 +38,7 @@ var customCertCount = 0;
40
38
  var cachePairs = new LRU({ max: 5120 });
41
39
  var certsCache = new LRU({ max: 256 });
42
40
  var remoteCerts = new LRU({ max: 1280 });
41
+ var KEY_SIZE = 2048;
43
42
  var ILEGAL_CHAR_RE = /[^a-z\d-]/i;
44
43
  // https://cloud.tencent.com/developer/ask/sof/58155
45
44
  var RANDOM_SERIAL = '/' + Date.now() + '/' + process.pid + '/' + Math.floor(Math.random() * 100);
@@ -58,12 +57,12 @@ exports.remoteCerts = remoteCerts;
58
57
  exports.createSecureContext = createSecureContext;
59
58
  exports.CUSTOM_CERTS_DIR = CUSTOM_CERTS_DIR;
60
59
 
61
- function isRootCa(name) {
60
+ function notRootCa(name) {
62
61
  return name !== 'root';
63
62
  }
64
63
 
65
64
  function checkFilename(name) {
66
- return name && !ILLEGAL_PATH_RE.test(name) && isRootCa(name);
65
+ return name && !ILLEGAL_PATH_RE.test(name) && notRootCa(name);
67
66
  }
68
67
 
69
68
  function resetAllCerts() {
@@ -84,7 +83,7 @@ if (timer && typeof timer.unref === 'function') {
84
83
  timer.unref();
85
84
  }
86
85
 
87
- if (!useNewKey && requiredVersion && !checkCertificate()) {
86
+ if (!useNewKey && !checkCertificate()) {
88
87
  try {
89
88
  fs.unlinkSync(ROOT_KEY_FILE);
90
89
  fs.unlinkSync(ROOT_CRT_FILE);
@@ -108,7 +107,7 @@ function isExpiredCert(crt) {
108
107
  function checkCertificate() {
109
108
  try {
110
109
  var crt = pki.certificateFromPem(fs.readFileSync(ROOT_CRT_FILE));
111
- if (crt.publicKey.n.toString(2).length < 2048 || isExpiredCert(crt.validity)) {
110
+ if (crt.publicKey.n.toString(2).length < KEY_SIZE || isExpiredCert(crt.validity)) {
112
111
  return false;
113
112
  }
114
113
  return /^whistle\.\d+$/.test(getCommonName(crt));
@@ -178,6 +177,19 @@ exports.hasCustomCerts = function () {
178
177
  return customCertCount;
179
178
  };
180
179
 
180
+ var rootSkiBytes;
181
+
182
+ function getRootSKI() {
183
+ if (!rootSkiBytes) {
184
+ try {
185
+ rootSkiBytes = ROOT_CRT.generateSubjectKeyIdentifier().getBytes();
186
+ } catch (e) {
187
+ rootSkiBytes = null;
188
+ }
189
+ }
190
+ return rootSkiBytes;
191
+ }
192
+
181
193
  function getCacheCert(hostname) {
182
194
  return (
183
195
  customPairs[hostname] ||
@@ -207,6 +219,20 @@ function createSelfCert(hostname) {
207
219
  ]);
208
220
  cert.setIssuer(ROOT_CRT.subject.attributes);
209
221
  cert.setExtensions([
222
+ {
223
+ name: 'basicConstraints',
224
+ cA: false
225
+ },
226
+ {
227
+ name: 'keyUsage',
228
+ digitalSignature: true,
229
+ keyEncipherment: true
230
+ },
231
+ {
232
+ name: 'extKeyUsage',
233
+ serverAuth: true,
234
+ clientAuth: true
235
+ },
210
236
  {
211
237
  name: 'subjectAltName',
212
238
  altNames: [
@@ -220,6 +246,10 @@ function createSelfCert(hostname) {
220
246
  value: hostname
221
247
  }
222
248
  ]
249
+ },
250
+ {
251
+ name: 'authorityKeyIdentifier',
252
+ keyIdentifier: getRootSKI() // Get SKI from ROOT_CRT for authorityKeyIdentifier extension
223
253
  }
224
254
  ]);
225
255
  cert.sign(ROOT_KEY, forge.md.sha256.create());
@@ -265,7 +295,7 @@ function parseAllCustomCerts() {
265
295
  var validity = info.validity;
266
296
  var altNames = info.altNames;
267
297
  var dnsName = [];
268
- var disabled = (isRootCa(filename) && rulesUtil.isDisabledCertFile(filename)) || undefined;
298
+ var disabled = (notRootCa(filename) && rulesUtil.isDisabledCertFile(filename)) || undefined;
269
299
  altNames.forEach(function (item) {
270
300
  if ((item.type === 2 || item.type === 7) && !pairs[item.value]) {
271
301
  if (!disabled) {
@@ -439,7 +469,7 @@ function createRootCA() {
439
469
 
440
470
  function createCACert(opts) {
441
471
  opts = opts || {};
442
- var keys = pki.rsa.generateKeyPair(requiredVersion ? 2048 : 1024);
472
+ var keys = pki.rsa.generateKeyPair(KEY_SIZE);
443
473
  var cert = createCert(keys.publicKey);
444
474
  var now = Date.now() + common.padLeft(Math.floor(Math.random() * 1000), 3);
445
475
  var attrs = [
@@ -757,7 +787,7 @@ exports.setActiveCert = function (opts) {
757
787
  return;
758
788
  }
759
789
  var filename = opts.filename;
760
- if (isRootCa(filename) && allCustomCerts[filename]) {
790
+ if (notRootCa(filename) && allCustomCerts[filename]) {
761
791
  rulesUtil.setDisabledCertFile(filename, opts.disabled);
762
792
  parseAllCustomCerts();
763
793
  }
@@ -207,7 +207,7 @@ function resolveWebsocket(socket, wss) {
207
207
  };
208
208
 
209
209
  var plugin = pluginMgr.resolveWhistlePlugins(socket);
210
- abortIfUnavailable(socket);
210
+ handleEnd(socket);
211
211
  pluginMgr.getRules(socket, function (rulesMgr) {
212
212
  if (rulesMgr) {
213
213
  socket.pluginRules = rulesMgr;
@@ -394,7 +394,7 @@ function resolveWebsocket(socket, wss) {
394
394
  proxySocket.on('error', handleProxyError);
395
395
  reqSocket = proxySocket;
396
396
  proxySocket.on('secureConnect', function () {
397
- abortIfUnavailable(reqSocket);
397
+ handleEnd(reqSocket);
398
398
  pipeData();
399
399
  });
400
400
  } catch (e) {
@@ -403,7 +403,7 @@ function resolveWebsocket(socket, wss) {
403
403
  return;
404
404
  }
405
405
  reqSocket = proxySocket;
406
- abortIfUnavailable(reqSocket);
406
+ handleEnd(reqSocket);
407
407
  pipeData();
408
408
  };
409
409
  // 对应 internal-proxy 要用直接请求,方便用来穿透 nginx
@@ -557,7 +557,7 @@ function resolveWebsocket(socket, wss) {
557
557
  return execCallback(e);
558
558
  }
559
559
  if (retryConnect) {
560
- abortIfUnavailable(reqSocket);
560
+ handleEnd(reqSocket);
561
561
  } else {
562
562
  retryConnect = function (e) {
563
563
  if (!newIp && (newIp = util.getLocalhostIP(e, socket, socket._w2hostname, socket.hostIp))) {
@@ -621,7 +621,7 @@ function resolveWebsocket(socket, wss) {
621
621
  var disable = socket.disable;
622
622
  if (retryConnect) {
623
623
  reqSocket.removeListener('error', retryConnect);
624
- abortIfUnavailable(reqSocket);
624
+ handleEnd(reqSocket);
625
625
  retryConnect = null;
626
626
  }
627
627
  clearTimeout(timeout);
@@ -718,9 +718,10 @@ function resolveWebsocket(socket, wss) {
718
718
  extend(headers, reqHeaders);
719
719
  headers.host = headers.host || host;
720
720
  }
721
- auth = util.getAuthBasic(auth || authObj);
721
+ authObj = auth || authObj;
722
+ auth = util.getAuthBasic(authObj);
722
723
  if (auth) {
723
- headers['authorization'] = auth;
724
+ headers[(authObj.proxy ? 'proxy-' : '') + 'authorization'] = auth;
724
725
  }
725
726
  var reqRuleData = { headers: headers };
726
727
  util.setReqCors(reqRuleData, reqCors);
@@ -847,7 +848,7 @@ function resolveWebsocket(socket, wss) {
847
848
  }
848
849
  }
849
850
 
850
- function abortIfUnavailable(socket) {
851
+ function handleEnd(socket) {
851
852
  return util.onSocketEnd(socket, destroy);
852
853
  }
853
854
  var destroyed, reqDestroyed, resDestroyed;
@@ -1080,11 +1081,10 @@ function toHttp1(req, res) {
1080
1081
  formatRawHeaders(svrRes, isH2)
1081
1082
  );
1082
1083
  var write = res.write;
1083
- var handleError = function (e) {
1084
- e && handleAbort();
1085
- };
1086
1084
  res.write = function (chunk) {
1087
- return write.call(res, chunk, handleError);
1085
+ return write.call(res, chunk, function (e) {
1086
+ e && handleAbort();
1087
+ });
1088
1088
  };
1089
1089
  svrRes.pipe(res);
1090
1090
  res.flushHeaders && res.flushHeaders();
@@ -1168,152 +1168,147 @@ module.exports = function (socket, next, isWebPort) {
1168
1168
 
1169
1169
  util.onSocketEnd(socket, destroy);
1170
1170
 
1171
- function abortIfUnavailable(s) {
1172
- return s.on('error', destroy);
1173
- }
1174
1171
  var clientIp = socket.clientIp;
1175
1172
  var clientPort = socket.clientPort;
1176
- util.readOneChunk(
1177
- socket,
1178
- function (chunk) {
1179
- headersStr = chunk && chunk.toString();
1180
- var isHttp = chunk && HTTP_RE.test(headersStr);
1181
- var statusLine = isHttp && RegExp['$&'];
1182
- if (isHttp && CONNECT_RE.test(RegExp.$1)) {
1183
- chunk = addClientInfo(socket, chunk, statusLine, clientIp, clientPort);
1184
- util.connect(
1185
- {
1186
- port: config.port,
1187
- host: LOCALHOST
1188
- },
1173
+ util.readOneChunk(socket, function (chunk) {
1174
+ headersStr = chunk && chunk.toString();
1175
+ var isHttp = chunk && HTTP_RE.test(headersStr);
1176
+ var statusLine = isHttp && RegExp['$&'];
1177
+ if (isHttp && CONNECT_RE.test(RegExp.$1)) {
1178
+ chunk = addClientInfo(socket, chunk, statusLine, clientIp, clientPort);
1179
+ util.connect(
1180
+ {
1181
+ port: config.port,
1182
+ host: config.host || LOCALHOST
1183
+ },
1189
1184
  function (err, s) {
1190
1185
  reqSocket = s;
1191
1186
  if (err || socket._hasError) {
1192
1187
  return destroy(err);
1193
1188
  }
1189
+ reqSocket.on('error', destroy);
1194
1190
  reqSocket.write(chunk);
1195
1191
  reqSocket.pipe(socket).pipe(reqSocket);
1196
- abortIfUnavailable(reqSocket);
1197
1192
  socket.resume();
1198
1193
  }
1199
1194
  );
1200
- return;
1201
- }
1202
- if (!chunk) {
1195
+ return;
1196
+ }
1197
+ if (!chunk) {
1203
1198
  //没有数据
1204
- return isWebPort ? socket.destroy() : next(chunk);
1205
- }
1206
- if (isHttp) {
1207
- if (isEnable('forHttps') || disable.captureHttp) {
1208
- next(chunk);
1209
- } else {
1210
- socket.resume();
1211
- server.emit('connection', socket);
1212
- socket.emit(
1199
+ return isWebPort ? socket.destroy() : next(chunk);
1200
+ }
1201
+ if (isHttp) {
1202
+ if (isEnable('forHttps') || disable.captureHttp) {
1203
+ next(chunk);
1204
+ } else {
1205
+ socket.resume();
1206
+ server.emit('connection', socket);
1207
+ socket.emit(
1213
1208
  'data',
1214
1209
  addClientInfo(socket, chunk, statusLine, clientIp, clientPort)
1215
1210
  );
1216
- }
1217
- } else if (isEnable('forHttp') || disable.captureHttps) {
1211
+ }
1212
+ } else if (isEnable('forHttp') || disable.captureHttps) {
1213
+ return next(chunk);
1214
+ } else {
1215
+ var isHttpH2 = HTTP2_RE.test(headersStr);
1216
+ if (!isHttpH2 && chunk[0] != 22) {
1218
1217
  return next(chunk);
1219
- } else {
1220
- var isHttpH2 = HTTP2_RE.test(headersStr);
1221
- if (!isHttpH2 && chunk[0] != 22) {
1222
- return next(chunk);
1223
- }
1224
- var useSNI, domain, serverKey;
1225
- var handleConnect = function (port) {
1226
- var promise =
1218
+ }
1219
+ var useSNI, domain, serverKey;
1220
+ var handleConnect = function (port) {
1221
+ var promise =
1227
1222
  !isHttpH2 && !useSNI && serverAgent.existsServer(serverKey);
1228
- var httpsServer = promise && promise.cert && promise.server;
1229
- if (httpsServer && httpsServer.setSecureContext) {
1230
- var cert = serverAgent.createCertificate(domain);
1231
- if (
1223
+ var httpsServer = promise && promise.cert && promise.server;
1224
+ if (httpsServer && httpsServer.setSecureContext) {
1225
+ var cert = serverAgent.createCertificate(domain);
1226
+ if (
1232
1227
  cert.key !== promise.cert.key ||
1233
1228
  cert.cert !== promise.cert.cert
1234
1229
  ) {
1235
- try {
1236
- cert._ctx = cert._ctx || ca.createSecureContext(cert);
1237
- httpsServer.setSecureContext(cert._ctx);
1238
- promise.cert = cert;
1239
- } catch (e) {}
1240
- }
1230
+ try {
1231
+ cert._ctx = cert._ctx || ca.createSecureContext(cert);
1232
+ httpsServer.setSecureContext(cert._ctx);
1233
+ promise.cert = cert;
1234
+ } catch (e) {}
1241
1235
  }
1242
- util.connect(
1243
- {
1244
- port: port,
1245
- host: LOCALHOST,
1246
- localAddress: LOCALHOST
1247
- },
1236
+ }
1237
+ util.connect(
1238
+ {
1239
+ port: port,
1240
+ host: LOCALHOST,
1241
+ localAddress: LOCALHOST
1242
+ },
1248
1243
  function (err, s) {
1249
1244
  reqSocket = s;
1250
1245
  if (err || socket._hasError) {
1251
1246
  return destroy(err);
1252
1247
  }
1248
+ reqSocket.on('error', destroy);
1253
1249
  socket._w2TunnelKey = reqSocket.localPort + ':' + reqSocket.remotePort;
1254
1250
  tunnelTmplData.set(socket._w2TunnelKey, getTunnelData(socket, clientIp, clientPort, isHttpH2));
1255
1251
  reqSocket.write(chunk);
1256
1252
  reqSocket.pipe(socket).pipe(reqSocket);
1257
1253
  socket.resume();
1258
- abortIfUnavailable(reqSocket);
1259
1254
  }
1260
1255
  );
1261
- };
1262
- var useNoSNIServer = function () {
1263
- serverKey = requestCert ? ':' + domain : domain;
1264
- serverAgent.createServer(serverKey, handlers, handleConnect, 0, 0);
1265
- };
1256
+ };
1257
+ var useNoSNIServer = function () {
1258
+ serverKey = requestCert ? ':' + domain : domain;
1259
+ serverAgent.createServer(serverKey, handlers, handleConnect, 0, 0);
1260
+ };
1266
1261
 
1267
- var handleRequest = function () {
1268
- if (useSNI) {
1269
- var disableH2 = !properties.isEnableHttp2();
1270
- if (disable.http2) {
1271
- disableH2 = true;
1272
- } else if (enable.http2) {
1273
- disableH2 = false;
1274
- }
1275
- getSNIServer(h2Handlers, handleConnect, disableH2, requestCert);
1276
- } else if (isHttpH2) {
1277
- getHttp2Server(h2Handlers, handleConnect);
1278
- } else {
1279
- useNoSNIServer();
1262
+ var handleRequest = function () {
1263
+ if (useSNI) {
1264
+ var disableH2 = !properties.isEnableHttp2();
1265
+ if (disable.http2) {
1266
+ disableH2 = true;
1267
+ } else if (enable.http2) {
1268
+ disableH2 = false;
1280
1269
  }
1281
- };
1282
- if (isHttpH2) {
1283
- return handleRequest();
1270
+ getSNIServer(h2Handlers, handleConnect, disableH2, requestCert);
1271
+ } else if (isHttpH2) {
1272
+ getHttp2Server(h2Handlers, handleConnect);
1273
+ } else {
1274
+ useNoSNIServer();
1284
1275
  }
1285
- useSNI = checkSNI(chunk);
1286
- var servername = useSNI || socket.tunnelHostname;
1287
- if (
1276
+ };
1277
+ if (isHttpH2) {
1278
+ return handleRequest();
1279
+ }
1280
+ useSNI = checkSNI(chunk);
1281
+ var servername = useSNI || socket.tunnelHostname;
1282
+ if (
1288
1283
  !servername ||
1289
1284
  (useSNI ? disable.captureSNI : (disable.captureNoSNI || (net.isIP(servername) && !isCaptureIp()))) ||
1290
1285
  (socket.useProxifier && !ca.existsCustomCert(servername))
1291
1286
  ) {
1292
- return next(chunk);
1293
- }
1294
- var requestCert =
1287
+ return next(chunk);
1288
+ }
1289
+ var requestCert =
1295
1290
  (enable.clientCert || enable.requestCert) &&
1296
1291
  !disable.clientCert &&
1297
1292
  !disable.requestCert;
1298
- domain = getDomain(servername);
1299
- socket.curUrl = socket.fullUrl = 'https://' + servername;
1300
- socket.useSNI = useSNI;
1301
- socket.serverName = socket.servername = servername;
1302
- socket.commonName = domain;
1303
- loadCert(socket, function (cert) {
1304
- if (socket._hasError) {
1305
- return destroy();
1306
- }
1307
- if (cert === false) {
1308
- return next(chunk);
1309
- }
1310
- if (cert) {
1311
- domain = servername;
1312
- }
1313
- handleRequest();
1314
- });
1315
- }
1316
- },
1293
+ domain = getDomain(servername);
1294
+ socket.curUrl = socket.fullUrl = 'https://' + servername;
1295
+ socket.useSNI = useSNI;
1296
+ socket.serverName = socket.servername = servername;
1297
+ socket.commonName = domain;
1298
+ loadCert(socket, function (cert) {
1299
+ if (socket._hasError) {
1300
+ return destroy();
1301
+ }
1302
+ if (cert === false) {
1303
+ return next(chunk);
1304
+ }
1305
+ if (cert) {
1306
+ domain = servername;
1307
+ }
1308
+ handleRequest();
1309
+ });
1310
+ }
1311
+ },
1317
1312
  isWebPort ? 0 : TIMEOUT
1318
1313
  );
1319
1314
  };
package/lib/index.js CHANGED
@@ -11,10 +11,8 @@ var setupHttps = require('./https').setup;
11
11
  var httpsUtil = require('./https/ca');
12
12
  var rulesUtil = require('./rules/util');
13
13
  var initDataServer = require('./util/data-server');
14
- var initLogServer = require('./util/log-server');
15
14
  var pluginMgr = require('./plugins');
16
15
  var config = require('./config');
17
- var loadService = require('./service');
18
16
  var initSocketMgr = require('./socket-mgr');
19
17
  var tunnelProxy = require('./tunnel');
20
18
  var upgradeProxy = require('./upgrade');
@@ -61,7 +59,6 @@ function proxy(callback, _server) {
61
59
  tunnelProxy(server, proxyEvents);
62
60
  upgradeProxy(server);
63
61
  initDataServer(proxyEvents);
64
- initLogServer(proxyEvents);
65
62
  rulesUtil.setup(proxyEvents);
66
63
  var properties = rulesUtil.properties;
67
64
  if (config.disableAllRules) {
@@ -224,7 +221,6 @@ function exportInterfaces(obj) {
224
221
  obj.httpsUtil = httpsUtil;
225
222
  obj.pluginMgr = pluginMgr;
226
223
  obj.logger = logger;
227
- obj.loadService = loadService;
228
224
  obj.setAuth = config.setAuth;
229
225
  obj.setUIHost = config.setUIHost;
230
226
  obj.setPluginUIHost = config.setPluginUIHost;
@@ -254,7 +250,7 @@ function handleGlobalException(err) {
254
250
  code === 'ERR_HTTP_TRAILER_INVALID' ||
255
251
  code === 'ERR_INTERNAL_ASSERTION' ||
256
252
  code === 'ERR_INVALID_ARG_TYPE' ||
257
- (err && /finishwrite/i.test(err.message)))
253
+ (err && /finishwrite|'_hadError'/i.test(err.message)))
258
254
  ) {
259
255
  return;
260
256
  }