From 4450e3d56117ea99eec1b40eb863f95a1b331c19 Mon Sep 17 00:00:00 2001 From: avwo Date: Thu, 14 Mar 2019 18:09:01 +0800 Subject: [PATCH] feat: if the plugin (whistle.xxx) dose not implement server, then xxx://value is equals to whistle.xxx://value --- lib/https/index.js | 244 +++++++++++++++++++++------------------------ 1 file changed, 116 insertions(+), 128 deletions(-) diff --git a/lib/https/index.js b/lib/https/index.js index 6d58d4ca1..c3e927c04 100644 --- a/lib/https/index.js +++ b/lib/https/index.js @@ -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;