whistle 2.10.8 → 2.10.10

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.
@@ -289,8 +289,8 @@ pluginMgr.on('uninstall', function (result) {
289
289
  });
290
290
  });
291
291
 
292
- function formatMTime(mtime) {
293
- return '[' + (new Date(mtime).toLocaleTimeString()) + ']';
292
+ function showUpdateInfo(action, name) {
293
+ return '[' + (new Date().toLocaleTimeString()) + '] ' + action + ' ' + name.slice(0, -1);
294
294
  }
295
295
 
296
296
  function showVerbose(oldData, newData) {
@@ -319,30 +319,15 @@ function showVerbose(oldData, newData) {
319
319
 
320
320
  uninstallData &&
321
321
  Object.keys(uninstallData).forEach(function (name) {
322
- console.log(
323
- colors.red(
324
- formatMTime(uninstallData[name].mtime) +
325
- ' UNINSTALL ' + name.slice(0, -1)
326
- )
327
- );
322
+ console.log(colors.red(showUpdateInfo('UNINSTALL', name)));
328
323
  });
329
324
  installData &&
330
325
  Object.keys(installData).forEach(function (name) {
331
- console.log(
332
- colors.green(
333
- formatMTime(installData[name].mtime) +
334
- ' INSTALL ' + name.slice(0, -1)
335
- )
336
- );
326
+ console.log(colors.green(showUpdateInfo('INSTALL', name)));
337
327
  });
338
328
  updateData &&
339
329
  Object.keys(updateData).forEach(function (name) {
340
- console.log(
341
- colors.yellow(
342
- formatMTime(updateData[name].mtime) +
343
- ' UPDATE ' + name.slice(0, -1)
344
- )
345
- );
330
+ console.log(colors.yellow(showUpdateInfo('UPDATE', name)));
346
331
  });
347
332
  }
348
333
 
@@ -1155,6 +1140,10 @@ function emptyFilter(val) {
1155
1140
  return !!val;
1156
1141
  }
1157
1142
 
1143
+ function isClosed(req) {
1144
+ return req._hasClosed || req._hasError;
1145
+ }
1146
+
1158
1147
  function getRulesMgr(type, req, res, callback) {
1159
1148
  var plugins = req.whistlePlugins;
1160
1149
  if (!plugins) {
@@ -1170,14 +1159,29 @@ function getPluginRulesCallback(req, callback) {
1170
1159
  };
1171
1160
  }
1172
1161
 
1162
+ function resolvePipe(req, m1, m2) {
1163
+ if (req.isPluginReq) {
1164
+ return;
1165
+ }
1166
+ var filter = m1 && m1.resolveFilter(req);
1167
+ if (m2) {
1168
+ var filter2 = m2.resolveFilter(req);
1169
+ filter = filter ? extend(filter, filter2) : filter2;
1170
+ }
1171
+ if (util.isIgnored(filter, 'pipe')) {
1172
+ return;
1173
+ }
1174
+ return (m1 && m1.resolvePipe(req)) || (m2 && m2.resolvePipe(req));
1175
+ }
1176
+
1173
1177
  function resolvePipePlugin(req, callback) {
1174
1178
  if (req._pipePlugin == null) {
1175
1179
  var pipe;
1176
1180
  var hRules = req.headerRulesMgr;
1177
1181
  if (config.multiEnv) {
1178
- pipe = (hRules && hRules.resolvePipe(req)) || rulesMgr.resolvePipe(req);
1182
+ pipe = resolvePipe(req, hRules, rulesMgr);
1179
1183
  } else {
1180
- pipe = rulesMgr.resolvePipe(req) || (hRules && hRules.resolvePipe(req));
1184
+ pipe = resolvePipe(req, rulesMgr, hRules);
1181
1185
  }
1182
1186
  var plugin;
1183
1187
  req._pipeRule = pipe;
@@ -1205,7 +1209,7 @@ function getPipe(type, hookName) {
1205
1209
  }
1206
1210
  resolvePipePlugin(req, function (ports) {
1207
1211
  var port = ports && ports[type + 'Port'];
1208
- if (!port || req._hasClosed || req._hasError) {
1212
+ if (!port || isClosed(req)) {
1209
1213
  return callback();
1210
1214
  }
1211
1215
  var options = getOptions(req, res, isRes && 'resRules');
@@ -1232,46 +1236,33 @@ function getPipe(type, hookName) {
1232
1236
  delete req.headers['sec-websocket-extensions'];
1233
1237
  }
1234
1238
  }
1235
- var client;
1236
1239
  var done;
1237
1240
  var handleConnect = function (socket, _res) {
1238
1241
  if (!done) {
1239
1242
  done = true;
1240
- if (req._hasError) {
1241
- return socket.destroy();
1243
+ if (isClosed(req)) {
1244
+ return util.endSocket(socket);
1242
1245
  }
1246
+ req.once('_closed', function () {
1247
+ util.endSocket(socket);
1248
+ });
1243
1249
  callback(socket);
1250
+ } else if (socket) {
1251
+ util.endSocket(socket);
1244
1252
  }
1245
1253
  };
1246
- var destroy = function () {
1247
- if (client) {
1248
- client.destroy();
1249
- client.socket && client.socket.destroy();
1250
- client = null;
1251
- handleConnect();
1252
- }
1253
- };
1254
- var handleError = function (err) {
1255
- if (client) {
1256
- destroy();
1257
- if (err) {
1258
- debugMode && console.log(req._pipeRule.matcher, type);
1259
- (res || req).emit('error', err);
1260
- }
1261
- }
1262
- };
1263
- client = config.connect(options, handleConnect);
1264
- client.on('error', function () {
1265
- if (client) {
1266
- destroy();
1267
- client = !req._hasError && config.connect(options, handleConnect);
1268
- client && util.onSocketEnd(client, handleError);
1254
+ var client = config.connect(options, handleConnect);
1255
+ client.once('error', function () {
1256
+ if (!done && !req._hasError) {
1257
+ client = config.connect(options, handleConnect);
1258
+ client.once('error', function (err) {
1259
+ if (!done && !isClosed(req)) {
1260
+ debugMode && console.log(type, err);
1261
+ (res || req).emit('error', err);
1262
+ }
1263
+ });
1269
1264
  }
1270
1265
  });
1271
- req.once('_closed', function() {
1272
- handleConnect();
1273
- destroy();
1274
- });
1275
1266
  });
1276
1267
  };
1277
1268
  }
@@ -117,7 +117,7 @@ var appendTrailers = function (_res, res, newTrailers, req) {
117
117
  return;
118
118
  }
119
119
  common.addTrailerNames(_res, newTrailers, null, null, req);
120
- common.onResEnd(_res, function () {
120
+ common.onReadEnd(_res, function () {
121
121
  var trailers = _res.trailers;
122
122
  if (
123
123
  !res.chunkedEncoding ||
@@ -786,15 +786,12 @@ var getSession = function (req, cb, isReq) {
786
786
  retryRequestSession();
787
787
  };
788
788
 
789
- var initWsReq = function (req, res) {
790
- initReq(req, res, true);
791
- };
792
- var initConnectReq = function (req, res) {
789
+ var setupConnect = function (req, socket, isServer) {
793
790
  if (req.originalReq && req.originalRes) {
794
791
  return;
795
792
  }
796
793
  var established;
797
- initWsReq(req, res);
794
+ initReq(req, socket, isServer);
798
795
  req.sendEstablished = function (err, cb) {
799
796
  if (established) {
800
797
  return;
@@ -815,25 +812,25 @@ var initConnectReq = function (req, res) {
815
812
  ];
816
813
  if (err || !cb || !req.headers[common.ACK_HEADER]) {
817
814
  resCtn.push('\r\n', body);
818
- res.write(resCtn.join('\r\n'));
815
+ socket.write(resCtn.join('\r\n'));
819
816
  return cb && cb();
820
817
  }
821
818
  resCtn.push('x-whistle-allow-tunnel-ack: 1');
822
819
  resCtn.push('\r\n', body);
823
- res.once('data', function (chunk) {
820
+ socket.once('data', function (chunk) {
824
821
  if (!req._hasError) {
825
- res.pause();
826
- var on = res.on;
827
- res.on = function () {
828
- res.on = on;
829
- res.resume();
822
+ socket.pause();
823
+ var on = socket.on;
824
+ socket.on = function () {
825
+ socket.on = on;
826
+ socket.resume();
830
827
  return on.apply(this, arguments);
831
828
  };
832
- chunk.length > 1 && res.unshift(chunk.slice(1));
829
+ chunk.length > 1 && socket.unshift(chunk.slice(1));
833
830
  cb();
834
831
  }
835
832
  });
836
- return res.write(resCtn.join('\r\n'));
833
+ return socket.write(resCtn.join('\r\n'));
837
834
  };
838
835
  };
839
836
 
@@ -1111,10 +1108,6 @@ function handleWsSignal(receiver, sender) {
1111
1108
  };
1112
1109
  }
1113
1110
 
1114
- function destroySocket() {
1115
- this.destroy();
1116
- }
1117
-
1118
1111
  function formatRules(rules) {
1119
1112
  if (Array.isArray(rules)) {
1120
1113
  return rules.join('\n');
@@ -2240,7 +2233,7 @@ module.exports = async function (options, callback) {
2240
2233
  break;
2241
2234
  case PLUGIN_HOOKS.HTTP:
2242
2235
  if (httpServer) {
2243
- initWsReq(req, socket);
2236
+ initReq(req, socket, true);
2244
2237
  var curUrl = req.originalReq.realUrl;
2245
2238
  httpServer.setMaxWsPayload = setMaxWsPayload;
2246
2239
  var svrRes = '';
@@ -2354,41 +2347,39 @@ module.exports = async function (options, callback) {
2354
2347
 
2355
2348
  var emitHttpPipe = function (httpServer, req, socket) {
2356
2349
  if (httpServer) {
2357
- initConnectReq(req, socket);
2350
+ setupConnect(req, socket);
2358
2351
  req.sendEstablished(function () {
2359
2352
  var decoder = getDecodeTransform();
2360
2353
  var encoder = getEncodeTransform();
2361
2354
  var done;
2362
- var handleError = function (err) {
2355
+ var destroy = function () {
2363
2356
  if (!done) {
2364
2357
  done = true;
2365
- socket.emit('error', err || new Error('destroyed'));
2358
+ socket.destroy();
2366
2359
  }
2367
2360
  };
2368
2361
  socket.on('error', function (err) {
2369
2362
  if (!done) {
2370
- done = true;
2363
+ destroy();
2371
2364
  decoder.emit('error', err);
2372
2365
  encoder.emit('error', err);
2373
2366
  }
2374
2367
  });
2375
- encoder.once('finish', function () {
2376
- done = true;
2377
- });
2378
- socket.on('close', function () {
2368
+ socket.once('close', function () {
2379
2369
  done = true;
2380
2370
  decoder.emit('close');
2381
2371
  encoder.emit('close');
2382
2372
  });
2383
- decoder.destroy = encoder.destroy = handleError;
2384
- decoder.on('error', handleError);
2385
- encoder.on('error', handleError);
2373
+ decoder.destroy = encoder.destroy = destroy;
2374
+ decoder.on('error', destroy);
2375
+ encoder.on('error', destroy);
2386
2376
  ADDITIONAL_FIELDS.forEach(function (key) {
2387
2377
  decoder[key] = req[key];
2388
2378
  });
2389
- socket.pipe(decoder);
2390
- encoder.pipe(socket);
2391
- socket.on('end', destroySocket);
2379
+ encoder.once('finish', function() {
2380
+ socket.end();
2381
+ });
2382
+ encoder.pipe(socket).pipe(decoder);
2392
2383
  httpServer.emit('request', decoder, encoder);
2393
2384
  });
2394
2385
  }
@@ -2396,7 +2387,7 @@ module.exports = async function (options, callback) {
2396
2387
 
2397
2388
  function pipeUpgrade(pipeSvr, req, socket, head, fromClient, toServer) {
2398
2389
  if (pipeSvr) {
2399
- initConnectReq(req, socket);
2390
+ setupConnect(req, socket);
2400
2391
  req.sendEstablished(function () {
2401
2392
  addFrameHandler(req, socket, maxWsPayload, fromClient, toServer);
2402
2393
  pipeSvr.emit('connect', req, socket, head);
@@ -2433,7 +2424,7 @@ module.exports = async function (options, callback) {
2433
2424
  break;
2434
2425
  case PLUGIN_HOOKS.TUNNEL:
2435
2426
  if (tunnelServer) {
2436
- initConnectReq(req, socket);
2427
+ setupConnect(req, socket, true);
2437
2428
  req.sendEstablished(function () {
2438
2429
  var reqRules;
2439
2430
  req.setRules = req.setReqRules = socket.setReqRules = function (rules) {
@@ -2524,7 +2515,7 @@ module.exports = async function (options, callback) {
2524
2515
  }
2525
2516
  break;
2526
2517
  case PLUGIN_HOOKS.TUNNEL_REQ_READ:
2527
- initConnectReq(req, socket);
2518
+ setupConnect(req, socket);
2528
2519
  pipeServer = req._isUpgrade ? wsReqRead : tunnelReqRead;
2529
2520
  if (pipeServer) {
2530
2521
  req.sendEstablished(function () {
@@ -2537,7 +2528,7 @@ module.exports = async function (options, callback) {
2537
2528
  }
2538
2529
  break;
2539
2530
  case PLUGIN_HOOKS.TUNNEL_REQ_WRITE:
2540
- initConnectReq(req, socket);
2531
+ setupConnect(req, socket);
2541
2532
  pipeServer = req._isUpgrade ? wsReqWrite : tunnelReqWrite;
2542
2533
  if (pipeServer) {
2543
2534
  req.sendEstablished(function () {
@@ -2549,7 +2540,7 @@ module.exports = async function (options, callback) {
2549
2540
  }
2550
2541
  break;
2551
2542
  case PLUGIN_HOOKS.TUNNEL_RES_READ:
2552
- initConnectReq(req, socket);
2543
+ setupConnect(req, socket);
2553
2544
  pipeServer = req._isUpgrade ? wsResRead : tunnelResRead;
2554
2545
  if (pipeServer) {
2555
2546
  req.sendEstablished(function () {
@@ -2562,7 +2553,7 @@ module.exports = async function (options, callback) {
2562
2553
  }
2563
2554
  break;
2564
2555
  case PLUGIN_HOOKS.TUNNEL_RES_WRITE:
2565
- initConnectReq(req, socket);
2556
+ setupConnect(req, socket);
2566
2557
  pipeServer = req._isUpgrade ? wsResWrite : tunnelResWrite;
2567
2558
  if (pipeServer) {
2568
2559
  req.sendEstablished(function () {
package/lib/rules/dns.js CHANGED
@@ -50,7 +50,7 @@ function lookDnsOverHttps(hostname, callback) {
50
50
  } catch (e) {
51
51
  err = data || e;
52
52
  }
53
- return callback(err || 'DNS Over HTTPS Look Failed');
53
+ return callback(err || 'DNS over HTTPS Look Failed');
54
54
  });
55
55
  }
56
56
 
@@ -51,6 +51,7 @@ exports.getEnabledRules = function() {
51
51
  exports.getMFlag = function() {
52
52
  return rules._mflag;
53
53
  };
54
+ exports.resolveFilter = rules.resolveFilter.bind(rules);
54
55
  exports.parse = rules.parse.bind(rules);
55
56
  exports.append = rules.append.bind(rules);
56
57
  exports.resolveSNICallback = rules.resolveSNICallback.bind(rules);
@@ -916,7 +916,7 @@ function checkInternal(req, rule) {
916
916
  }
917
917
 
918
918
  function resolveRuleList(req, list, vals, index, isFilter, isEnableProxy, host, isReq) {
919
- var curUrl = util.formatUrl(req.curUrl);
919
+ var curUrl = util.formatUrl(req.curUrl || req.fullUrl);
920
920
  var notHttp = list.isRuleProto && curUrl[0] !== 'h';
921
921
  //支持域名匹配
922
922
  var domainUrl = removePort(curUrl);
package/lib/rules/util.js CHANGED
@@ -19,12 +19,9 @@ var inlineValues = {};
19
19
  var proxy, pluginMgr;
20
20
  var serviceRules;
21
21
  var mockRules;
22
- var dnsOrder = propertiesStorage.getProperty('dnsOrder');
23
22
 
24
23
  config.ipv6Only = config.ipv6Only || !!propertiesStorage.getProperty('ipv6Only');
25
- if (!config.dnsOrder && !config.setDefaultResultOrder(dnsOrder)) {
26
- config.dnsOrder = config.defaultDnsOrder;
27
- }
24
+ config.setDefaultResultOrder(propertiesStorage.getProperty('dnsOrder'));
28
25
 
29
26
  function limitValueLen(name, len) {
30
27
  var value = propertiesStorage.getProperty(name);
@@ -535,9 +532,7 @@ exports.properties = {
535
532
  },
536
533
  setDnsOrder: function(order) {
537
534
  if (config.setDefaultResultOrder(order)) {
538
- order = +order;
539
- config.dnsOrder = order;
540
- propertiesStorage.setProperty('dnsOrder', order);
535
+ propertiesStorage.setProperty('dnsOrder', +order);
541
536
  }
542
537
  },
543
538
  getLatestVersion: function (name) {
@@ -257,13 +257,12 @@ function handleHttp(options, cb, count, reqId, testId) {
257
257
  svrRes.on('error', execCb);
258
258
  var buffer;
259
259
  var enableStream;
260
- var unzipStream = common.getUnzipStream(svrRes.headers);
261
260
  var timer = reqId && setTimeout(function() {
262
261
  composeData.setData(reqId, buffer, true);
263
262
  enableStream = true;
264
263
  timer = buffer = undefined;
265
264
  handleResponse();
266
- common.onResEnd(svrRes, function() {
265
+ common.onReadEnd(svrRes, function() {
267
266
  var buf = composeData.getData(reqId);
268
267
  if (buf) {
269
268
  buf._hasW2End = true;
@@ -293,6 +292,11 @@ function handleHttp(options, cb, count, reqId, testId) {
293
292
  execCb(null, result);
294
293
  buffer = null;
295
294
  };
295
+ if (!common.hasBody(svrRes, options)) {
296
+ drain(svrRes);
297
+ return handleResponse();
298
+ }
299
+ var unzipStream = common.getUnzipStream(svrRes.headers);
296
300
  if (unzipStream) {
297
301
  unzipStream.on('error', function(err) {
298
302
  drain(svrRes);
@@ -320,7 +324,7 @@ function handleHttp(options, cb, count, reqId, testId) {
320
324
  }
321
325
  }
322
326
  });
323
- unzipStream.on('end', handleResponse);
327
+ unzipStream.once('end', handleResponse);
324
328
  });
325
329
  client.on('error', execCb || noop);
326
330
  client.end(options.body);
@@ -18,8 +18,6 @@ var Limiter = require('async-limiter');
18
18
  var common = require('../util/common');
19
19
  var logger = require('./console-log');
20
20
 
21
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
22
-
23
21
  var saveData = dataCenter.saveData;
24
22
  var shareData = dataCenter.shareData;
25
23
  var requestData = dataCenter.requestData;
@@ -304,11 +302,11 @@ function installPlugins(data, clientId) {
304
302
  function sessionsHandler() {
305
303
  var app = express();
306
304
  app.use(function (req, res, next) {
307
- req.on('error', abort);
308
- res.on('error', abort);
309
- function abort() {
305
+ function destroy() {
310
306
  res.destroy();
311
307
  }
308
+ req.on('error', destroy);
309
+ res.on('error', destroy);
312
310
  if (req.headers[common.WHISTLE_UID_HEADER] !== config.uid) {
313
311
  return res.status(403).end('Forbidden');
314
312
  }
package/lib/socket-mgr.js CHANGED
@@ -379,7 +379,7 @@ function handleWsSend(ctx, reqTrans, sendStatus, handleTransform, frameCtx, even
379
379
  reqReceiver.onData = function (data, opts, drain) {
380
380
  var ignore;
381
381
  if (drain !== true && hasFilter) {
382
- data = execHandleFrame(frameCtx, data, opts);
382
+ data = execHandleFrame(frameCtx, data, opts, true);
383
383
  if (!data) {
384
384
  return;
385
385
  }
@@ -469,13 +469,22 @@ exports.addTrailerNames = function (
469
469
  });
470
470
  };
471
471
 
472
- exports.onResEnd = function (res, callback) {
473
- var state = res._readableState || '';
474
- if (state.endEmitted) {
472
+ function onReadEnd(stream, callback) {
473
+ if (stream.readableEnded) {
475
474
  return callback();
476
475
  }
477
- res.on('end', callback);
478
- };
476
+ stream.once('end', callback);
477
+ }
478
+
479
+ function onWriteEnd(stream, callback) {
480
+ if (stream.writableFinished) {
481
+ return callback();
482
+ }
483
+ stream.once('finish', callback);
484
+ }
485
+
486
+ exports.onReadEnd = onReadEnd;
487
+ exports.onWriteEnd = onWriteEnd;
479
488
 
480
489
  var UPGRADE_RE = /^\s*upgrade\s*$/i;
481
490
  var WS_RE = /^\s*websocket\s*$/i;
@@ -725,7 +734,7 @@ function readStream(stream, callback) {
725
734
  stream.on('data', function(chunk) {
726
735
  buffer.push(chunk);
727
736
  });
728
- stream.once('end', function() {
737
+ onReadEnd(stream, function() {
729
738
  var buf;
730
739
  var text;
731
740
  var json;
@@ -899,12 +908,11 @@ exports.onSocketEnd = function(socket, callback) {
899
908
  callback = null;
900
909
  }
901
910
  };
902
- if (socket.aborted || socket.destroyed || socket._hasError) {
911
+ if (socket.aborted || socket.destroyed || socket.closed || socket._hasError) {
903
912
  return execCallback();
904
913
  }
905
914
  socket.on('error', execCallback);
906
915
  socket.once('close', execCallback);
907
- socket.once('end', execCallback);
908
916
  socket.once('timeout', execCallback);
909
917
  };
910
918
 
@@ -1579,6 +1587,14 @@ function safeEncodeURIComponent(ch) {
1579
1587
  return ch;
1580
1588
  }
1581
1589
 
1590
+ function safeDecodeURIComponent(str) {
1591
+ try {
1592
+ return decodeURIComponent(str);
1593
+ } catch (e) {}
1594
+
1595
+ return str;
1596
+ }
1597
+
1582
1598
  exports.safeEncodeURIComponent = safeEncodeURIComponent;
1583
1599
 
1584
1600
  /**
@@ -1893,32 +1909,43 @@ exports.connectInner = function (options, cb, config) {
1893
1909
  if (req) {
1894
1910
  req.emit('error', TIMEOUT_ERR);
1895
1911
  req.destroy();
1896
- req.socket && req.socket.destroy();
1897
1912
  }
1898
1913
  }, CONN_TIMEOUT);
1899
- var req = httpModule.request(proxyOptions);
1900
- req.on('error', noop);
1901
- req
1902
- .on('connect', function (res, socket) {
1914
+ var req;
1915
+ var clearTimer = function (err) {
1916
+ if (timer) {
1917
+ err && req && req.destroy();
1903
1918
  clearTimeout(timer);
1904
- socket.on('error', noop);
1905
- if (res.statusCode !== 200) {
1906
- var err = new Error(
1919
+ timer = null;
1920
+ }
1921
+ };
1922
+ req = httpModule.request(proxyOptions);
1923
+ req.on('error', clearTimer);
1924
+ req.on('connect', function (res, socket) {
1925
+ if (!timer) {
1926
+ return;
1927
+ }
1928
+ clearTimer();
1929
+ socket.on('error', function() {
1930
+ socket.destroy();
1931
+ });
1932
+ if (res.statusCode !== 200) {
1933
+ var err = new Error(
1907
1934
  'Tunneling socket could not be established, statusCode=' +
1908
1935
  res.statusCode
1909
1936
  );
1910
- err.statusCode = res.statusCode;
1911
- socket.destroy();
1912
- process.nextTick(function () {
1913
- req.emit('error', err);
1914
- });
1915
- return;
1916
- }
1917
- if (res.headers[ALLOW_ACK]) {
1918
- socket.write('1');
1919
- }
1920
- cb(socket, res);
1921
- })
1937
+ err.statusCode = res.statusCode;
1938
+ socket.destroy();
1939
+ process.nextTick(function () {
1940
+ req.emit('error', err);
1941
+ });
1942
+ return;
1943
+ }
1944
+ if (res.headers[ALLOW_ACK]) {
1945
+ socket.write('1');
1946
+ }
1947
+ cb(socket, res);
1948
+ })
1922
1949
  .end();
1923
1950
  return req;
1924
1951
  };
@@ -2052,11 +2079,7 @@ exports.getSessionInfo = function(headers) {
2052
2079
  var value = data[LAST_RAW_INDEX + index];
2053
2080
  if (value) {
2054
2081
  rawResult[key] = value;
2055
- try {
2056
- result[key] = decodeURIComponent(value);
2057
- } catch (e) {
2058
- result[key] = value;
2059
- }
2082
+ result[key] = safeDecodeURIComponent(value);
2060
2083
  }
2061
2084
  });
2062
2085
  result._ = rawResult;
@@ -323,7 +323,7 @@ function handleRequest(req, data) {
323
323
  delete data.abort;
324
324
  }
325
325
  };
326
- req.on('end', removeAbort);
326
+ util.onReadEnd(req, removeAbort);
327
327
  req.on('error', removeAbort);
328
328
  req.on('abort', removeAbort);
329
329
  data.version = version;
@@ -743,6 +743,10 @@ module.exports = function init(_proxy) {
743
743
  }
744
744
  }
745
745
 
746
+ if (filterType === 'SSE') {
747
+ return rawType === 'text/event-stream';
748
+ }
749
+
746
750
  var curType = util.getContentType(rawType);
747
751
  for (i = 0, len = TYPES.length; i < len; i++) {
748
752
  type = TYPES[i];
package/lib/util/drain.js CHANGED
@@ -1,14 +1,13 @@
1
- var createTransform = require('./common').createTransform;
1
+ var common = require('./common');
2
2
 
3
- var noop = function () {};
3
+ var noop = common.noop;
4
+ var onReadEnd = common.onReadEnd;
4
5
 
5
6
  module.exports = function (stream, endHandler) {
6
7
  if (stream._hasAlreadyDrain || (!stream.noReqBody && stream.useH2)) {
7
8
  return typeof endHandler == 'function' && endHandler();
8
9
  }
9
10
  stream._hasAlreadyDrain = true;
10
- var emitEndStream = createTransform();
11
- emitEndStream.on('data', noop).on('error', noop);
12
- emitEndStream.on('end', endHandler);
13
- stream.pipe(emitEndStream);
11
+ onReadEnd(stream, endHandler);
12
+ stream.on('data', noop).on('error', noop);
14
13
  };
@@ -58,7 +58,7 @@ function readSingleFile(path, callback) {
58
58
  }
59
59
  });
60
60
  stream.on('error', execCallback);
61
- stream.on('end', execCallback);
61
+ stream.once('end', execCallback);
62
62
  }
63
63
 
64
64
  function getFileMap(list) {