feat: if the plugin (whistle.xxx) dose not implement server, then xxx://value is equals to whistle.xxx://value

This commit is contained in:
avwo
2019-03-14 18:09:01 +08:00
parent 409aee0fb8
commit 4450e3d561
+116 -128
View File
@@ -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;