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.
- package/assets/js/log.js +4 -0
- package/bin/api.js +85 -1
- package/bin/util.js +1 -1
- package/bin/whistle.js +1 -1
- package/biz/webui/cgi-bin/util.js +1 -1
- package/biz/webui/cgi-bin/values/add.js +15 -13
- package/biz/webui/htdocs/index.html +1 -1
- package/biz/webui/htdocs/js/index.js +38 -39
- package/biz/webui/lib/index.js +39 -30
- package/lib/config.js +11 -18
- package/lib/handlers/file-proxy.js +1 -1
- package/lib/https/ca.js +17 -16
- package/lib/https/h2.js +53 -34
- package/lib/https/index.js +11 -10
- package/lib/index.js +1 -1
- package/lib/inspectors/data.js +8 -4
- package/lib/inspectors/log.js +14 -33
- package/lib/inspectors/res.js +2 -2
- package/lib/inspectors/rules.js +11 -6
- package/lib/inspectors/weinre.js +1 -1
- package/lib/plugins/index.js +44 -53
- package/lib/plugins/load-plugin.js +31 -40
- package/lib/rules/dns.js +1 -1
- package/lib/rules/index.js +1 -0
- package/lib/rules/rules.js +1 -1
- package/lib/rules/util.js +2 -7
- package/lib/service/composer.js +7 -3
- package/lib/service/service.js +3 -5
- package/lib/socket-mgr.js +1 -1
- package/lib/util/common.js +56 -33
- package/lib/util/data-server.js +5 -1
- package/lib/util/drain.js +5 -6
- package/lib/util/file-mgr.js +1 -1
- package/lib/util/http-mgr.js +6 -2
- package/lib/util/index.js +32 -24
- package/lib/util/speed-transform.js +2 -2
- package/lib/util/transproto.js +4 -3
- package/lib/util/whistle-transform.js +2 -2
- package/lib/util/zlib.js +1 -1
- package/package.json +3 -3
package/lib/plugins/index.js
CHANGED
|
@@ -289,8 +289,8 @@ pluginMgr.on('uninstall', function (result) {
|
|
|
289
289
|
});
|
|
290
290
|
});
|
|
291
291
|
|
|
292
|
-
function
|
|
293
|
-
return '[' + (new Date(
|
|
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 =
|
|
1182
|
+
pipe = resolvePipe(req, hRules, rulesMgr);
|
|
1179
1183
|
} else {
|
|
1180
|
-
pipe =
|
|
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
|
|
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
|
|
1241
|
-
return
|
|
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
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
client
|
|
1250
|
-
client
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
820
|
+
socket.once('data', function (chunk) {
|
|
824
821
|
if (!req._hasError) {
|
|
825
|
-
|
|
826
|
-
var on =
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
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 &&
|
|
829
|
+
chunk.length > 1 && socket.unshift(chunk.slice(1));
|
|
833
830
|
cb();
|
|
834
831
|
}
|
|
835
832
|
});
|
|
836
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
2355
|
+
var destroy = function () {
|
|
2363
2356
|
if (!done) {
|
|
2364
2357
|
done = true;
|
|
2365
|
-
socket.
|
|
2358
|
+
socket.destroy();
|
|
2366
2359
|
}
|
|
2367
2360
|
};
|
|
2368
2361
|
socket.on('error', function (err) {
|
|
2369
2362
|
if (!done) {
|
|
2370
|
-
|
|
2363
|
+
destroy();
|
|
2371
2364
|
decoder.emit('error', err);
|
|
2372
2365
|
encoder.emit('error', err);
|
|
2373
2366
|
}
|
|
2374
2367
|
});
|
|
2375
|
-
|
|
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 =
|
|
2384
|
-
decoder.on('error',
|
|
2385
|
-
encoder.on('error',
|
|
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
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
package/lib/rules/index.js
CHANGED
|
@@ -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);
|
package/lib/rules/rules.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
539
|
-
config.dnsOrder = order;
|
|
540
|
-
propertiesStorage.setProperty('dnsOrder', order);
|
|
535
|
+
propertiesStorage.setProperty('dnsOrder', +order);
|
|
541
536
|
}
|
|
542
537
|
},
|
|
543
538
|
getLatestVersion: function (name) {
|
package/lib/service/composer.js
CHANGED
|
@@ -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.
|
|
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.
|
|
327
|
+
unzipStream.once('end', handleResponse);
|
|
324
328
|
});
|
|
325
329
|
client.on('error', execCb || noop);
|
|
326
330
|
client.end(options.body);
|
package/lib/service/service.js
CHANGED
|
@@ -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
|
-
|
|
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
|
}
|
package/lib/util/common.js
CHANGED
|
@@ -469,13 +469,22 @@ exports.addTrailerNames = function (
|
|
|
469
469
|
});
|
|
470
470
|
};
|
|
471
471
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
if (state.endEmitted) {
|
|
472
|
+
function onReadEnd(stream, callback) {
|
|
473
|
+
if (stream.readableEnded) {
|
|
475
474
|
return callback();
|
|
476
475
|
}
|
|
477
|
-
|
|
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
|
|
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
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1914
|
+
var req;
|
|
1915
|
+
var clearTimer = function (err) {
|
|
1916
|
+
if (timer) {
|
|
1917
|
+
err && req && req.destroy();
|
|
1903
1918
|
clearTimeout(timer);
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
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
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
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
|
-
|
|
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;
|
package/lib/util/data-server.js
CHANGED
|
@@ -323,7 +323,7 @@ function handleRequest(req, data) {
|
|
|
323
323
|
delete data.abort;
|
|
324
324
|
}
|
|
325
325
|
};
|
|
326
|
-
|
|
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
|
|
1
|
+
var common = require('./common');
|
|
2
2
|
|
|
3
|
-
var noop =
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
emitEndStream.on('end', endHandler);
|
|
13
|
-
stream.pipe(emitEndStream);
|
|
11
|
+
onReadEnd(stream, endHandler);
|
|
12
|
+
stream.on('data', noop).on('error', noop);
|
|
14
13
|
};
|