whistle 2.10.9 → 2.10.11
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 +3 -1
- package/bin/util.js +1 -1
- package/bin/whistle.js +5 -0
- package/biz/webui/cgi-bin/get-data.js +0 -1
- package/biz/webui/cgi-bin/init.js +0 -1
- package/biz/webui/cgi-bin/status.js +2 -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 +50 -51
- package/biz/webui/lib/index.js +39 -30
- package/index.js +10 -12
- package/lib/config.js +25 -79
- package/lib/handlers/file-proxy.js +1 -1
- package/lib/https/ca.js +18 -17
- package/lib/https/h2.js +54 -35
- package/lib/https/index.js +124 -107
- package/lib/inspectors/data.js +9 -3
- package/lib/inspectors/log.js +14 -33
- package/lib/inspectors/req.js +3 -6
- package/lib/inspectors/res.js +2 -5
- package/lib/inspectors/rules.js +11 -6
- package/lib/inspectors/weinre.js +1 -1
- package/lib/plugins/index.js +45 -54
- package/lib/plugins/load-plugin.js +31 -40
- package/lib/rules/dns.js +1 -1
- package/lib/rules/index.js +3 -1
- package/lib/rules/protocols.js +2 -4
- package/lib/rules/rules.js +3 -5
- package/lib/rules/util.js +2 -7
- package/lib/service/compose-data.js +2 -1
- package/lib/service/composer.js +12 -10
- package/lib/service/service.js +3 -5
- package/lib/socket-mgr.js +5 -2
- package/lib/tunnel.js +9 -5
- package/lib/util/common.js +190 -37
- 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 +48 -69
- 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 +4 -4
|
@@ -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);
|
|
@@ -386,6 +387,7 @@ function getScriptContext(req, res, body, pattern, frameOpts) {
|
|
|
386
387
|
}
|
|
387
388
|
if (frameOpts) {
|
|
388
389
|
ctx.ctx = {
|
|
390
|
+
destroy: frameOpts.destroy,
|
|
389
391
|
sendToServer: frameOpts.sendToServer,
|
|
390
392
|
sendToClient: frameOpts.sendToClient,
|
|
391
393
|
handleSendToClientFrame: null,
|
|
@@ -434,7 +436,7 @@ function getReqPayload(req, res, cb) {
|
|
|
434
436
|
|
|
435
437
|
function execRulesScript(script, req, res, body, pattern, frameOpts) {
|
|
436
438
|
var context = getScriptContext(req, res, body, pattern, frameOpts);
|
|
437
|
-
if (!util.
|
|
439
|
+
if (!util.runInContext(script, context)) {
|
|
438
440
|
return '';
|
|
439
441
|
}
|
|
440
442
|
if (frameOpts) {
|
package/lib/rules/protocols.js
CHANGED
|
@@ -272,12 +272,10 @@ function isWebProtocol(protocol) {
|
|
|
272
272
|
|
|
273
273
|
exports.isWebProtocol = isWebProtocol;
|
|
274
274
|
|
|
275
|
-
function
|
|
275
|
+
function isWsProtocol(protocol) {
|
|
276
276
|
return protocol == 'ws:' || protocol == 'wss:';
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
-
exports.isWebsocketProtocol = isWebsocketProtocol;
|
|
280
|
-
|
|
281
279
|
function isFileProxy(protocol) {
|
|
282
280
|
return RULE_RE.test(protocol) || LOC_RE.test(protocol);
|
|
283
281
|
}
|
|
@@ -298,7 +296,7 @@ function contains(name) {
|
|
|
298
296
|
}
|
|
299
297
|
name += ':';
|
|
300
298
|
return (
|
|
301
|
-
|
|
299
|
+
isWsProtocol(name) ||
|
|
302
300
|
isWebProtocol(name) ||
|
|
303
301
|
isFileProxy(name) ||
|
|
304
302
|
name == 'tunnel:'
|
package/lib/rules/rules.js
CHANGED
|
@@ -54,10 +54,8 @@ var REG_URL_SYMBOL_RE = /^(\^+)/;
|
|
|
54
54
|
var PATTERN_FILTER_RE = /^(?:filter|ignore):\/\/(.+)\/(i)?$/;
|
|
55
55
|
var LINE_PROPS_RE = /^lineProps:\/\/(.*)$/;
|
|
56
56
|
var FILTER_RE = /^(?:excludeFilter|includeFilter):\/\/(.*)$/;
|
|
57
|
-
var PROPS_FILTER_RE =
|
|
58
|
-
|
|
59
|
-
var PURE_FILTER_RE =
|
|
60
|
-
/^(?:excludeFilter|includeFilter):\/\/(statusCode|from|env|clientIp|clientIP|clientPort|remoteAddress|remotePort|serverIp|serverIP|chance|probability|serverPort|host|re[qs](?:H(?:eaders?)?)?)[.=](.+)$/;
|
|
57
|
+
var PROPS_FILTER_RE = /^(?:filter|excludeFilter|includeFilter|ignore):\/\/(m(?:ethod)?|i(?:p)?|h(?:eader)?|env|s(?:tatusCode)?|sni|from|b(?:ody)?|clientIp|clientIP|clientPort|remoteAddress|remotePort|serverIp|serverIP|serverPort|chance|probability|host|re[qs](?:H(?:eaders?)?)?)[:=](.+)$/;
|
|
58
|
+
var PURE_FILTER_RE = /^(?:excludeFilter|includeFilter):\/\/(re[qs](?:H(?:eaders?)?)?)\.(.+)$/;
|
|
61
59
|
var PATTERN_WILD_FILTER_RE = /^(?:filter|ignore):\/\/(!)?(\*+\/)/;
|
|
62
60
|
var INLINE_RE = /^((?:filter|excludeFilter|includeFilter|ignore):\/\/)(\(.*\)|\<.*\>)$/;
|
|
63
61
|
var CHROME_PATH_RE = /^file:\/\/\/[A-Z]:\//;
|
|
@@ -916,7 +914,7 @@ function checkInternal(req, rule) {
|
|
|
916
914
|
}
|
|
917
915
|
|
|
918
916
|
function resolveRuleList(req, list, vals, index, isFilter, isEnableProxy, host, isReq) {
|
|
919
|
-
var curUrl = util.formatUrl(req.curUrl);
|
|
917
|
+
var curUrl = util.formatUrl(req.curUrl || req.fullUrl);
|
|
920
918
|
var notHttp = list.isRuleProto && curUrl[0] !== 'h';
|
|
921
919
|
//支持域名匹配
|
|
922
920
|
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) {
|
|
@@ -22,8 +22,9 @@ exports = module.exports = function(req, res) {
|
|
|
22
22
|
} else {
|
|
23
23
|
cache.set(reqId, '');
|
|
24
24
|
}
|
|
25
|
+
curBuf = curBuf.toString('base64');
|
|
25
26
|
}
|
|
26
|
-
result[reqId] = curBuf
|
|
27
|
+
result[reqId] = curBuf;
|
|
27
28
|
});
|
|
28
29
|
res.json(result);
|
|
29
30
|
};
|
package/lib/service/composer.js
CHANGED
|
@@ -154,10 +154,7 @@ function handleConnect(options, cb, count, testId) {
|
|
|
154
154
|
proxyHost: PROXY_OPTS.host,
|
|
155
155
|
proxyPort: PROXY_OPTS.port,
|
|
156
156
|
headers: options.headers
|
|
157
|
-
}, function(socket, svrRes
|
|
158
|
-
if (err) {
|
|
159
|
-
return handleCallback(execCb, err, null, testId);
|
|
160
|
-
}
|
|
157
|
+
}, function(socket, svrRes) {
|
|
161
158
|
if (TLS_PROTOS.indexOf(options.protocol) !== -1) {
|
|
162
159
|
socket = tls.connect({
|
|
163
160
|
rejectUnauthorized: config.rejectUnauthorized,
|
|
@@ -171,7 +168,7 @@ function handleConnect(options, cb, count, testId) {
|
|
|
171
168
|
socket.write(data);
|
|
172
169
|
options.body = data = null;
|
|
173
170
|
}
|
|
174
|
-
handleCallback(execCb,
|
|
171
|
+
handleCallback(execCb, null, svrRes, testId);
|
|
175
172
|
}, config).on('error', execCb || noop);
|
|
176
173
|
}
|
|
177
174
|
}
|
|
@@ -257,13 +254,12 @@ function handleHttp(options, cb, count, reqId, testId) {
|
|
|
257
254
|
svrRes.on('error', execCb);
|
|
258
255
|
var buffer;
|
|
259
256
|
var enableStream;
|
|
260
|
-
var unzipStream = common.getUnzipStream(svrRes.headers);
|
|
261
257
|
var timer = reqId && setTimeout(function() {
|
|
262
258
|
composeData.setData(reqId, buffer, true);
|
|
263
259
|
enableStream = true;
|
|
264
260
|
timer = buffer = undefined;
|
|
265
261
|
handleResponse();
|
|
266
|
-
common.
|
|
262
|
+
common.onReadEnd(svrRes, function() {
|
|
267
263
|
var buf = composeData.getData(reqId);
|
|
268
264
|
if (buf) {
|
|
269
265
|
buf._hasW2End = true;
|
|
@@ -278,8 +274,9 @@ function handleHttp(options, cb, count, reqId, testId) {
|
|
|
278
274
|
}
|
|
279
275
|
clearTimeout(timer);
|
|
280
276
|
var headers = svrRes.headers;
|
|
281
|
-
|
|
282
|
-
|
|
277
|
+
var trailer = headers.trailer;
|
|
278
|
+
if (typeof trailer === 'string' && trailer.indexOf(',') !== -1) {
|
|
279
|
+
headers.trailer = trailer.split(',');
|
|
283
280
|
}
|
|
284
281
|
var result = {
|
|
285
282
|
statusCode: svrRes.statusCode,
|
|
@@ -293,6 +290,11 @@ function handleHttp(options, cb, count, reqId, testId) {
|
|
|
293
290
|
execCb(null, result);
|
|
294
291
|
buffer = null;
|
|
295
292
|
};
|
|
293
|
+
if (!common.hasBody(svrRes, options)) {
|
|
294
|
+
drain(svrRes);
|
|
295
|
+
return handleResponse();
|
|
296
|
+
}
|
|
297
|
+
var unzipStream = common.getUnzipStream(svrRes.headers);
|
|
296
298
|
if (unzipStream) {
|
|
297
299
|
unzipStream.on('error', function(err) {
|
|
298
300
|
drain(svrRes);
|
|
@@ -320,7 +322,7 @@ function handleHttp(options, cb, count, reqId, testId) {
|
|
|
320
322
|
}
|
|
321
323
|
}
|
|
322
324
|
});
|
|
323
|
-
unzipStream.
|
|
325
|
+
unzipStream.once('end', handleResponse);
|
|
324
326
|
});
|
|
325
327
|
client.on('error', execCb || noop);
|
|
326
328
|
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
|
}
|
|
@@ -657,6 +657,9 @@ function getFrameSender(options, toServer) {
|
|
|
657
657
|
function getFrameCtx(options, callback) {
|
|
658
658
|
var req = options.req;
|
|
659
659
|
rules.getFrameScriptCtx(req.rules.frameScript, req, options.res, {
|
|
660
|
+
destroy: function() {
|
|
661
|
+
destroy(options.reqId);
|
|
662
|
+
},
|
|
660
663
|
sendToClient: getFrameSender(options),
|
|
661
664
|
sendToServer: getFrameSender(options, true)
|
|
662
665
|
}, callback);
|
|
@@ -703,7 +706,7 @@ exports.handleUpgrade = function (req, res) {
|
|
|
703
706
|
resTrans.on('error', emitError);
|
|
704
707
|
res.headers = res.headers || {};
|
|
705
708
|
req.wsExts = res.headers['sec-websocket-extensions'] || '';
|
|
706
|
-
var options = { req: req, res: res };
|
|
709
|
+
var options = { req: req, res: res, reqId: reqId };
|
|
707
710
|
pluginMgr.getWsPipe(
|
|
708
711
|
req,
|
|
709
712
|
res,
|
package/lib/tunnel.js
CHANGED
|
@@ -206,10 +206,9 @@ function tunnelProxy(server, proxy, type) {
|
|
|
206
206
|
if (!isIPHost || !hasCustomCerts()) {
|
|
207
207
|
return false;
|
|
208
208
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return reqSocket.useProxifier;
|
|
209
|
+
var useProxifier = (config.proxifier2 || (config.proxifier && isWebPort)) && !disable.proxifier;
|
|
210
|
+
reqSocket.useProxifier = useProxifier;
|
|
211
|
+
return useProxifier;
|
|
213
212
|
};
|
|
214
213
|
var resolvedPlugin;
|
|
215
214
|
if (isIntercept()) {
|
|
@@ -248,14 +247,19 @@ function tunnelProxy(server, proxy, type) {
|
|
|
248
247
|
pluginMgr.getTunnelRules(req, function (_rulesMgr) {
|
|
249
248
|
handlePluginRules(_rulesMgr);
|
|
250
249
|
policy = headers[config.WHISTLE_POLICY_HEADER];
|
|
250
|
+
var useSniAsTunnelDomain = util.isEnable(req, 'useSniAsTunnelDomain');
|
|
251
|
+
var noCapture;
|
|
251
252
|
if (!reqSocket._hasError && !req._authForbidden &&
|
|
252
|
-
!req.fromComposer && (req._forceCapture || isIntercept())) {
|
|
253
|
+
!req.fromComposer && (req._forceCapture || isIntercept() || (noCapture = useSniAsTunnelDomain))) {
|
|
253
254
|
reqSocket.rulesHeaders = req.rulesHeaders;
|
|
254
255
|
reqSocket.enable = req.enable;
|
|
255
256
|
reqSocket.disable = req.disable;
|
|
256
257
|
reqSocket.tunnelHostname = hostname;
|
|
258
|
+
reqSocket.tunnelPort = options.port;
|
|
257
259
|
reqSocket.rules = _rules;
|
|
258
260
|
reqSocket._pluginVars = req._pluginVars;
|
|
261
|
+
reqSocket._noCaptureW2 = noCapture;
|
|
262
|
+
reqSocket._useSniAsTunnelDomain = useSniAsTunnelDomain;
|
|
259
263
|
dispatch(
|
|
260
264
|
reqSocket,
|
|
261
265
|
function (chunk) {
|