refactor: 修复关闭代理失败的bug
parent
a392b4c54d
commit
750e444af2
|
@ -22,7 +22,7 @@
|
|||
等你来提issue
|
||||
|
||||
## 快速开始
|
||||
|
||||
目前仅支持windows
|
||||
### 1、安装与启动
|
||||
```shell
|
||||
git clone https://gitee.com/docmirror/dev-sidecar.git
|
||||
|
|
|
@ -80,6 +80,12 @@ module.exports = {
|
|||
'downloads.openwrt.org': { '.*': { proxy: 'openwrt.proxy.ustclug.org' } },
|
||||
'secure.gravatar.com': { '.*': { proxy: 'gravatar.proxy.ustclug.org' } }
|
||||
},
|
||||
whiteList: {
|
||||
'alipay.com': true,
|
||||
'*.alipay.com': true,
|
||||
'pay.weixin.qq.com': true,
|
||||
'www.baidu.com': true
|
||||
},
|
||||
dns: {
|
||||
providers: {
|
||||
aliyun: {
|
||||
|
|
|
@ -87,7 +87,9 @@ module.exports = {
|
|||
plugins.push(close())
|
||||
}
|
||||
}
|
||||
await Promise.all(plugins)
|
||||
if (plugins.length > 0) {
|
||||
await Promise.all(plugins)
|
||||
}
|
||||
|
||||
if (status.proxy.enabled) {
|
||||
try {
|
||||
|
|
|
@ -20,7 +20,7 @@ const ProxyPlugin = function (context) {
|
|||
|
||||
async unsetProxy () {
|
||||
try {
|
||||
shell.setSystemProxy()
|
||||
await shell.setSystemProxy()
|
||||
event.fire('status', { key: 'proxy.enabled', vlaue: false })
|
||||
console.log('关闭系统代理成功')
|
||||
return true
|
||||
|
|
|
@ -52,7 +52,6 @@ const serverApi = {
|
|||
serverProcess.send({ type: 'action', event: { key: 'close' } })
|
||||
}
|
||||
}
|
||||
console.log('fork return pid: ' + serverProcess.pid)
|
||||
serverProcess.on('message', function (msg) {
|
||||
console.log('收到子进程消息', msg)
|
||||
if (msg.type === 'status') {
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
const interceptors = require('../../../lib/interceptor')
|
||||
const dnsUtil = require('../../../lib/dns')
|
||||
const lodash = require('lodash')
|
||||
function matchHostname (intercepts, hostname) {
|
||||
const interceptOpts = intercepts[hostname]
|
||||
if (interceptOpts) {
|
||||
return interceptOpts
|
||||
}
|
||||
if (!interceptOpts) {
|
||||
for (const target in intercepts) {
|
||||
if (target.indexOf('*') < 0) {
|
||||
continue
|
||||
}
|
||||
// 正则表达式匹配
|
||||
if (hostname.match(target)) {
|
||||
return intercepts[target]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isMatched (url, regexp) {
|
||||
return url.match(regexp)
|
||||
}
|
||||
|
||||
function domainRegexply (target) {
|
||||
return target.replace(/\./g, '\\.').replace(/\*/g, '.*')
|
||||
}
|
||||
|
||||
module.exports = (config) => {
|
||||
const regexpIntercepts = {}
|
||||
lodash.each(config.intercepts, (value, domain) => {
|
||||
if (domain.indexOf('*') >= 0) {
|
||||
const regDomain = domainRegexply(domain)
|
||||
regexpIntercepts[regDomain] = value
|
||||
} else {
|
||||
regexpIntercepts[domain] = value
|
||||
}
|
||||
})
|
||||
|
||||
const intercepts = regexpIntercepts
|
||||
const dnsMapping = config.dns.mapping
|
||||
const serverConfig = config
|
||||
|
||||
return {
|
||||
port: serverConfig.port,
|
||||
dnsConfig: {
|
||||
providers: dnsUtil.initDNS(serverConfig.dns.providers),
|
||||
mapping: dnsMapping
|
||||
},
|
||||
sslConnectInterceptor: (req, cltSocket, head) => {
|
||||
const hostname = req.url.split(':')[0]
|
||||
return !!matchHostname(intercepts, hostname) // 配置了拦截的域名,将会被代理
|
||||
},
|
||||
requestInterceptor: (rOptions, req, res, ssl, next) => {
|
||||
const hostname = rOptions.hostname
|
||||
const interceptOpts = matchHostname(intercepts, hostname)
|
||||
if (!interceptOpts) { // 该域名没有配置拦截器,直接过
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
for (const regexp in interceptOpts) { // 遍历拦截配置
|
||||
const interceptOpt = interceptOpts[regexp]
|
||||
if (regexp !== true) {
|
||||
if (!isMatched(req.url, regexp)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
for (const interceptImpl of interceptors) {
|
||||
// 根据拦截配置挑选合适的拦截器来处理
|
||||
if (!interceptImpl.is(interceptOpt) && interceptImpl.requestInterceptor) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
const result = interceptImpl.requestInterceptor(interceptOpt, rOptions, req, res, ssl)
|
||||
if (result) { // 拦截成功,其他拦截器就不处理了
|
||||
return
|
||||
}
|
||||
} catch (err) {
|
||||
// 拦截失败
|
||||
console.error('拦截处理失败',err)
|
||||
}
|
||||
}
|
||||
}
|
||||
next()
|
||||
},
|
||||
responseInterceptor: (req, res, proxyReq, proxyRes, ssl, next) => {
|
||||
next()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
const mitmproxy = require('../../../lib/proxy')
|
||||
const ProxyOptions = require('./options')
|
||||
|
||||
function fireError (e) {
|
||||
process.send({ type: 'error', event: e })
|
||||
}
|
||||
function fireStatus (status) {
|
||||
process.send({ type: 'status', event: status })
|
||||
}
|
||||
|
||||
let server
|
||||
function start () {
|
||||
const config = JSON.parse(process.argv[2])
|
||||
const proxyOptions = ProxyOptions(config)
|
||||
const newServer = mitmproxy.createProxy(proxyOptions, () => {
|
||||
fireStatus(true)
|
||||
console.log('代理服务已启动:127.0.0.1:' + proxyOptions.port)
|
||||
})
|
||||
newServer.on('close', () => {
|
||||
if (server === newServer) {
|
||||
server = null
|
||||
fireStatus(false)
|
||||
}
|
||||
})
|
||||
newServer.on('error', (e) => {
|
||||
console.log('server error', e)
|
||||
// newServer = null
|
||||
fireError(e)
|
||||
})
|
||||
}
|
||||
|
||||
const api = {
|
||||
async close () {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (server) {
|
||||
server.close((err) => {
|
||||
if (err) {
|
||||
console.log('close error', err, ',', err.code, ',', err.message, ',', err.errno)
|
||||
if (err.code === 'ERR_SERVER_NOT_RUNNING') {
|
||||
console.log('代理服务关闭成功')
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
reject(err)
|
||||
} else {
|
||||
console.log('代理服务关闭成功')
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('server is null')
|
||||
fireStatus(false)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
process.on('message', function (msg) {
|
||||
console.log('child get msg: ' + JSON.stringify(msg))
|
||||
if (msg.type === 'action') {
|
||||
api[msg.event.key](msg.event.params)
|
||||
}
|
||||
})
|
||||
|
||||
// 启动服务
|
||||
start()
|
|
@ -42,8 +42,9 @@ async function _winUnsetProxy (exec) {
|
|||
_winAsyncRegSet(regKey, 'ProxyEnable', Registry.REG_DWORD, 0),
|
||||
_winAsyncRegSet(regKey, 'ProxyServer', Registry.REG_SZ, '')
|
||||
])
|
||||
|
||||
await exec([refreshInternetPs], { type: 'ps' })
|
||||
console.log('代理关闭成功,等待refresh')
|
||||
await exec(refreshInternetPs, { type: 'ps' })
|
||||
console.log('代理关闭refresh完成')
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -66,7 +67,7 @@ async function _winSetProxy (exec, ip, port) {
|
|||
_winAsyncRegSet(regKey, 'ProxyOverride', Registry.REG_SZ, lanIpStr)
|
||||
])
|
||||
console.log('代理设置成功,等待refresh')
|
||||
await exec([refreshInternetPs])
|
||||
await exec(refreshInternetPs)
|
||||
console.log('代理设置refresh完成')
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class WindowsSystemShell extends SystemShell {
|
|||
static async exec (cmds, args = { }) {
|
||||
let { type } = args
|
||||
type = type || 'ps'
|
||||
if (cmds instanceof String) {
|
||||
if (typeof cmds === 'string') {
|
||||
cmds = [cmds]
|
||||
}
|
||||
if (type === 'ps') {
|
||||
|
|
|
@ -30,7 +30,7 @@ function registerProcessListener () {
|
|||
// console.error(err.errno)
|
||||
return
|
||||
}
|
||||
console.error(err)
|
||||
console.error('uncaughtException:', err)
|
||||
})
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
const interceptors = require('./lib/interceptor')
|
||||
const dnsUtil = require('./lib/dns')
|
||||
const lodash = require('lodash')
|
||||
function matchHostname (intercepts, hostname) {
|
||||
const interceptOpts = intercepts[hostname]
|
||||
if (interceptOpts) {
|
||||
return interceptOpts
|
||||
function matchHostname (hostMap, hostname) {
|
||||
const value = hostMap[hostname]
|
||||
if (value) {
|
||||
return value
|
||||
}
|
||||
if (!interceptOpts) {
|
||||
for (const target in intercepts) {
|
||||
if (!value) {
|
||||
for (const target in hostMap) {
|
||||
if (target.indexOf('*') < 0) {
|
||||
continue
|
||||
}
|
||||
// 正则表达式匹配
|
||||
if (hostname.match(target)) {
|
||||
return intercepts[target]
|
||||
return hostMap[target]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,18 +27,23 @@ function domainRegexply (target) {
|
|||
return target.replace(/\./g, '\\.').replace(/\*/g, '.*')
|
||||
}
|
||||
|
||||
module.exports = (config) => {
|
||||
const regexpIntercepts = {}
|
||||
lodash.each(config.intercepts, (value, domain) => {
|
||||
function domainMapRegexply (hostMap) {
|
||||
const regexpMap = {}
|
||||
lodash.each(hostMap, (value, domain) => {
|
||||
if (domain.indexOf('*') >= 0) {
|
||||
const regDomain = domainRegexply(domain)
|
||||
regexpIntercepts[regDomain] = value
|
||||
regexpMap[regDomain] = value
|
||||
} else {
|
||||
regexpIntercepts[domain] = value
|
||||
regexpMap[domain] = value
|
||||
}
|
||||
})
|
||||
return regexpMap
|
||||
}
|
||||
|
||||
module.exports = (config) => {
|
||||
const intercepts = domainMapRegexply(config.intercepts)
|
||||
const whiteList = domainMapRegexply(config.whiteList)
|
||||
|
||||
const intercepts = regexpIntercepts
|
||||
const dnsMapping = config.dns.mapping
|
||||
const serverConfig = config
|
||||
|
||||
|
@ -50,6 +55,11 @@ module.exports = (config) => {
|
|||
},
|
||||
sslConnectInterceptor: (req, cltSocket, head) => {
|
||||
const hostname = req.url.split(':')[0]
|
||||
const inWhiteList = matchHostname(whiteList, hostname) != null
|
||||
if (inWhiteList) {
|
||||
console.log('白名单域名,不拦截', hostname)
|
||||
return false
|
||||
}
|
||||
return !!matchHostname(intercepts, hostname) // 配置了拦截的域名,将会被代理
|
||||
},
|
||||
requestInterceptor: (rOptions, req, res, ssl, next) => {
|
||||
|
|
Loading…
Reference in New Issue