mirror of
https://github.com/avwo/whistle.git
synced 2026-10-28 22:59:50 +08:00
feat: if the plugin (whistle.xxx) dose not implement server, then xxx://value is equals to whistle.xxx://value
This commit is contained in:
+116
-128
@@ -184,110 +184,128 @@ function resolveWebsocket(socket, wss) {
|
||||
var ua = util.getMatcherValue(_rules.ua);
|
||||
headers['user-agent'] = ua;
|
||||
}
|
||||
rules.getProxy(fullUrl, plugin ? null : socket, function(err, hostIp, hostPort) {
|
||||
var proxyUrl = !plugin && _rules.proxy ? util.rule.getMatcher(_rules.proxy) : null;
|
||||
options = util.parseUrl(fullUrl);
|
||||
if (proxyUrl) {
|
||||
if (!filter.hide) {
|
||||
data.abort = destroy;
|
||||
proxy.emit('request', reqEmitter);
|
||||
}
|
||||
if (response()) {
|
||||
return;
|
||||
}
|
||||
if (socket.enable.abort || filter.abort) {
|
||||
return destroy();
|
||||
}
|
||||
var isXProxy = X_RE.test(proxyUrl);
|
||||
var isSocks = SOCKS_PROXY_RE.test(proxyUrl);
|
||||
var isHttpsProxy = !isSocks && HTTPS_PROXY_RE.test(proxyUrl);
|
||||
isInternalProxy = INTERNAL_PROXY_RE.test(proxyUrl);
|
||||
var isHttps2HttpProxy = isInternalProxy || HS2H_PROXY_RE.test(proxyUrl);
|
||||
if (!isHttps2HttpProxy && !wss && H2HS_PROXY_RE.test(proxyUrl)) {
|
||||
wss = true;
|
||||
} else {
|
||||
wss = options.protocol === 'wss:';
|
||||
}
|
||||
proxyUrl = 'http:' + util.removeProtocol(proxyUrl);
|
||||
getServerIp(proxyUrl, function(ip) {
|
||||
var proxyOptions = url.parse(proxyUrl);
|
||||
proxyOptions.port = parseInt(proxyOptions.port, 10) || (isSocks ? 1080 : (isHttpsProxy ? 443 : 80));
|
||||
var isProxyPort = proxyOptions.port == config.port;
|
||||
if (isProxyPort && util.isLocalAddress(ip)) {
|
||||
return execCallback(new Error('Unable to proxy to itself (' + ip + ':' + config.port + ')'));
|
||||
}
|
||||
if (!filter.hide) {
|
||||
data.abort = destroy;
|
||||
proxy.emit('request', reqEmitter);
|
||||
}
|
||||
if (socket.enable.abort || filter.abort) {
|
||||
return destroy();
|
||||
}
|
||||
if (response()) {
|
||||
return;
|
||||
}
|
||||
pluginMgr.loadPlugin(plugin, function(err, ports) {
|
||||
if (err) {
|
||||
return execCallback(err);
|
||||
}
|
||||
|
||||
options.proxyHost = ip;
|
||||
resData.port = options.proxyPort = proxyOptions.port;
|
||||
options.host = options.hostname;
|
||||
if (!options.port) {
|
||||
options.port = wss ? 443 : 80;
|
||||
}
|
||||
|
||||
var handleProxy = function(proxySocket) {
|
||||
if (wss) {
|
||||
proxySocket = tls.connect({
|
||||
rejectUnauthorized: false,
|
||||
socket: proxySocket,
|
||||
servername: options.hostname
|
||||
}).on('error', execCallback);
|
||||
var port = ports && ports.port;
|
||||
if (!port) {
|
||||
plugin = null;
|
||||
rules.getProxy(fullUrl, plugin ? null : socket, function(err, hostIp, hostPort) {
|
||||
var proxyUrl = !plugin && _rules.proxy ? util.rule.getMatcher(_rules.proxy) : null;
|
||||
options = util.parseUrl(fullUrl);
|
||||
if (proxyUrl) {
|
||||
var isXProxy = X_RE.test(proxyUrl);
|
||||
var isSocks = SOCKS_PROXY_RE.test(proxyUrl);
|
||||
var isHttpsProxy = !isSocks && HTTPS_PROXY_RE.test(proxyUrl);
|
||||
isInternalProxy = INTERNAL_PROXY_RE.test(proxyUrl);
|
||||
var isHttps2HttpProxy = isInternalProxy || HS2H_PROXY_RE.test(proxyUrl);
|
||||
if (!isHttps2HttpProxy && !wss && H2HS_PROXY_RE.test(proxyUrl)) {
|
||||
wss = true;
|
||||
} else {
|
||||
wss = options.protocol === 'wss:';
|
||||
}
|
||||
|
||||
reqSocket = proxySocket;
|
||||
abortIfUnavailable(reqSocket);
|
||||
pipeData();
|
||||
};
|
||||
if (isSocks) {
|
||||
options.localDNS = false;
|
||||
options.auths = config.getAuths(proxyOptions);
|
||||
} else {
|
||||
var proxyHeaders = options.headers = socket.disable.proxyUA ? {} :
|
||||
{ 'user-agent': config.PROXY_UA };
|
||||
if (!util.isLocalAddress(clientIp)) {
|
||||
proxyHeaders[config.CLIENT_IP_HEAD] = clientIp;
|
||||
}
|
||||
if(isProxyPort) {
|
||||
proxyHeaders[config.WEBUI_HEAD] = 1;
|
||||
} else if (isHttps2HttpProxy) {
|
||||
if (isInternalProxy) {
|
||||
if (wss) {
|
||||
headers[config.HTTPS_FIELD] = 1;
|
||||
}
|
||||
proxyHeaders[config.WHISTLE_POLICY_HEADER] = 'intercept';
|
||||
proxyUrl = 'http:' + util.removeProtocol(proxyUrl);
|
||||
getServerIp(proxyUrl, function(ip) {
|
||||
var proxyOptions = url.parse(proxyUrl);
|
||||
proxyOptions.port = parseInt(proxyOptions.port, 10) || (isSocks ? 1080 : (isHttpsProxy ? 443 : 80));
|
||||
var isProxyPort = proxyOptions.port == config.port;
|
||||
if (isProxyPort && util.isLocalAddress(ip)) {
|
||||
return execCallback(new Error('Unable to proxy to itself (' + ip + ':' + config.port + ')'));
|
||||
}
|
||||
wss = false;
|
||||
}
|
||||
util.checkIfAddInterceptPolicy(proxyHeaders, headers);
|
||||
options.proxyAuth = proxyOptions.auth;
|
||||
}
|
||||
var netMgr = isSocks ? socks : config;
|
||||
var reqDelay = util.getMatcherValue(_rules.reqDelay);
|
||||
var proxyOpts = util.setProxyHost(socket, options);
|
||||
if (isHttpsProxy) {
|
||||
proxyOpts.proxyServername = proxyOptions.hostname;
|
||||
}
|
||||
var connectProxy = function() {
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
var s = netMgr.connect(proxyOpts, handleProxy);
|
||||
s.on('error', isXProxy ? directConnect : execCallback);
|
||||
};
|
||||
if (reqDelay > 0) {
|
||||
clearTimeout(timeout);
|
||||
setTimeout(function() {
|
||||
timeout = util.setTimeout(function() {
|
||||
destroy(new Error('Timeout'));
|
||||
});
|
||||
connectProxy();
|
||||
}, reqDelay);
|
||||
|
||||
options.proxyHost = ip;
|
||||
resData.port = options.proxyPort = proxyOptions.port;
|
||||
options.host = options.hostname;
|
||||
if (!options.port) {
|
||||
options.port = wss ? 443 : 80;
|
||||
}
|
||||
|
||||
var handleProxy = function(proxySocket) {
|
||||
if (wss) {
|
||||
proxySocket = tls.connect({
|
||||
rejectUnauthorized: false,
|
||||
socket: proxySocket,
|
||||
servername: options.hostname
|
||||
}).on('error', execCallback);
|
||||
}
|
||||
|
||||
reqSocket = proxySocket;
|
||||
abortIfUnavailable(reqSocket);
|
||||
pipeData();
|
||||
};
|
||||
if (isSocks) {
|
||||
options.localDNS = false;
|
||||
options.auths = config.getAuths(proxyOptions);
|
||||
} else {
|
||||
var proxyHeaders = options.headers = socket.disable.proxyUA ? {} :
|
||||
{ 'user-agent': config.PROXY_UA };
|
||||
if (!util.isLocalAddress(clientIp)) {
|
||||
proxyHeaders[config.CLIENT_IP_HEAD] = clientIp;
|
||||
}
|
||||
if(isProxyPort) {
|
||||
proxyHeaders[config.WEBUI_HEAD] = 1;
|
||||
} else if (isHttps2HttpProxy) {
|
||||
if (isInternalProxy) {
|
||||
if (wss) {
|
||||
headers[config.HTTPS_FIELD] = 1;
|
||||
}
|
||||
proxyHeaders[config.WHISTLE_POLICY_HEADER] = 'intercept';
|
||||
}
|
||||
wss = false;
|
||||
}
|
||||
util.checkIfAddInterceptPolicy(proxyHeaders, headers);
|
||||
options.proxyAuth = proxyOptions.auth;
|
||||
}
|
||||
var netMgr = isSocks ? socks : config;
|
||||
var reqDelay = util.getMatcherValue(_rules.reqDelay);
|
||||
var proxyOpts = util.setProxyHost(socket, options);
|
||||
if (isHttpsProxy) {
|
||||
proxyOpts.proxyServername = proxyOptions.hostname;
|
||||
}
|
||||
var connectProxy = function() {
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
var s = netMgr.connect(proxyOpts, handleProxy);
|
||||
s.on('error', isXProxy ? directConnect : execCallback);
|
||||
};
|
||||
if (reqDelay > 0) {
|
||||
clearTimeout(timeout);
|
||||
setTimeout(function() {
|
||||
timeout = util.setTimeout(function() {
|
||||
destroy(new Error('Timeout'));
|
||||
});
|
||||
connectProxy();
|
||||
}, reqDelay);
|
||||
} else {
|
||||
connectProxy();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
connectProxy();
|
||||
directConnect(hostIp, hostPort);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
directConnect(hostIp, hostPort);
|
||||
return;
|
||||
}
|
||||
options.port = port;
|
||||
data.realUrl = util.changePort(fullUrl, options.port);
|
||||
socket.customParser = util.getParserStatus(socket);
|
||||
pluginMgr.addRuleHeaders(socket, _rules);
|
||||
socketMgr.setPending(socket);
|
||||
options.protocol = 'ws:';
|
||||
connectServer();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -295,37 +313,7 @@ function resolveWebsocket(socket, wss) {
|
||||
if (typeof hostIp !== 'string') {
|
||||
hostIp = null;
|
||||
}
|
||||
if (!filter.hide) {
|
||||
data.abort = destroy;
|
||||
proxy.emit('request', reqEmitter);
|
||||
}
|
||||
if (response()) {
|
||||
return;
|
||||
}
|
||||
if (socket.enable.abort || filter.abort) {
|
||||
return destroy();
|
||||
}
|
||||
if (plugin) {
|
||||
pluginMgr.loadPlugin(plugin, function(err, ports) {
|
||||
if (err) {
|
||||
return execCallback(err);
|
||||
}
|
||||
|
||||
options.port = ports.port;
|
||||
if (!options.port) {
|
||||
plugin = null;
|
||||
return connectServer();
|
||||
}
|
||||
data.realUrl = util.changePort(fullUrl, options.port);
|
||||
socket.customParser = util.getParserStatus(socket);
|
||||
pluginMgr.addRuleHeaders(socket, _rules);
|
||||
socketMgr.setPending(socket);
|
||||
options.protocol = 'ws:';
|
||||
connectServer();
|
||||
});
|
||||
} else {
|
||||
connectServer(hostIp, hostPort);
|
||||
}
|
||||
connectServer(hostIp, hostPort);
|
||||
}
|
||||
var retryConnect;
|
||||
var auto2http;
|
||||
|
||||
Reference in New Issue
Block a user