refactor: 优化dns选择
parent
6125895ae6
commit
02ab38c299
|
@ -1,8 +1,9 @@
|
|||
# dev-sidecar
|
||||
开发者边车,命名取自service-mesh的service-sidecar,意为为开发者打辅助的边车工具
|
||||
通过本地代理的方式将请求代理到一些国内的加速通道上
|
||||
通过本地代理的方式将http请求代理到一些国内的加速通道上
|
||||
解决一些网站和库无法访问或访问速度慢的问题
|
||||
|
||||
|
||||
## 特性
|
||||
|
||||
### 1、 github的release、source、zip下载加速
|
||||
|
@ -144,6 +145,10 @@ const intercepts = {
|
|||
注意:暂时只支持IPv4的解析
|
||||
|
||||
## 感谢
|
||||
本项目使用lerna包管理工具
|
||||
|
||||
[](https://lerna.js.org/)
|
||||
|
||||
本项目参考如下开源项目
|
||||
* [node-mitmproxy](https://github.com/wuchangming/node-mitmproxy)
|
||||
* [ReplaceGoogleCDN](https://github.com/justjavac/ReplaceGoogleCDN)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
// eslint-disable-next-line no-unused-vars
|
||||
const start = require('./start/index.js')
|
|
@ -4,7 +4,7 @@ const fs = require('fs')
|
|||
// 启动服务
|
||||
const mitmproxyPath = './start/mitmproxy'
|
||||
async function startup () {
|
||||
const banner = fs.readFileSync('./banner.txt')
|
||||
const banner = fs.readFileSync('./start/banner.txt')
|
||||
console.log(banner.toString())
|
||||
|
||||
const configPath = './start/user_config.json5'
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
{
|
||||
server: {
|
||||
intercepts: {
|
||||
'notify3.note.youdao.com': {
|
||||
'/pushserver3/.*': {
|
||||
abort: true
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
plugin: {
|
||||
node: {
|
||||
enabled: true
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
module.exports = {
|
||||
requestInterceptor (interceptOpt, rOptions, req, res, ssl) {
|
||||
console.log('abort:', rOptions.hostname, req.url)
|
||||
req.destroy()
|
||||
res.writeHead(403)
|
||||
res.write('Dev-Sidecar 403: \n\n request abort, this request is matched by abort intercept.\n\n 因配置abort拦截器,本请求将取消')
|
||||
res.end()
|
||||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.abort
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
const url = require('url')
|
||||
module.exports = {
|
||||
requestInterceptor (interceptOpt, rOptions, req, res, ssl) {
|
||||
const proxy = interceptOpt.proxy.indexOf('http') === 0 ? interceptOpt.proxy : rOptions.protocol + '//' + interceptOpt.proxy
|
||||
requestInterceptor (interceptOpt, rOptions, req, res, ssl, next) {
|
||||
const proxyTarget = interceptOpt.proxy
|
||||
// const backup = interceptOpt.backup
|
||||
const proxy = proxyTarget.indexOf('http') === 0 ? proxyTarget : rOptions.protocol + '//' + proxyTarget
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
const URL = url.parse(proxy)
|
||||
rOptions.protocol = URL.protocol
|
||||
|
@ -12,7 +14,7 @@ module.exports = {
|
|||
rOptions.port = rOptions.protocol === 'https:' ? 443 : 80
|
||||
}
|
||||
|
||||
console.log('proxy:', rOptions.hostname, req.url, interceptOpt.proxy)
|
||||
console.log('proxy:', rOptions.hostname, req.url, proxyTarget)
|
||||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.proxy
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const proxy = require('./impl/proxy')
|
||||
const redirect = require('./impl/redirect')
|
||||
const abort = require('./impl/abort')
|
||||
|
||||
const modules = [proxy, redirect]
|
||||
const modules = [proxy, redirect, abort]
|
||||
|
||||
module.exports = modules
|
||||
|
|
|
@ -3,6 +3,7 @@ const url = require('url')
|
|||
// const colors = require('colors')
|
||||
const DnsUtil = require('../../dns/index')
|
||||
const localIP = '127.0.0.1'
|
||||
const defaultDns = require('dns')
|
||||
// create connectHandler function
|
||||
module.exports = function createConnectHandler (sslConnectInterceptor, fakeServerCenter, dnsConfig) {
|
||||
// return
|
||||
|
@ -17,25 +18,38 @@ module.exports = function createConnectHandler (sslConnectInterceptor, fakeServe
|
|||
console.error('getServerPromise', e)
|
||||
})
|
||||
} else {
|
||||
if (dnsConfig) {
|
||||
const dns = DnsUtil.hasDnsLookup(dnsConfig, hostname)
|
||||
if (dns) {
|
||||
dns.lookup(hostname).then(ip => {
|
||||
connect(req, cltSocket, head, ip, srvUrl.port, { dns, hostname, ip })
|
||||
})
|
||||
}
|
||||
}
|
||||
connect(req, cltSocket, head, hostname, srvUrl.port)
|
||||
connect(req, cltSocket, head, hostname, srvUrl.port, dnsConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function connect (req, cltSocket, head, hostname, port, isDnsIntercept) {
|
||||
function connect (req, cltSocket, head, hostname, port, dnsConfig) {
|
||||
// tunneling https
|
||||
// console.log('connect:', hostname, port)
|
||||
const start = new Date().getTime()
|
||||
let isDnsIntercept = null
|
||||
try {
|
||||
const proxySocket = net.connect({ port, host: hostname, connectTimeout: 5000 }, () => {
|
||||
const options = {
|
||||
port,
|
||||
host: hostname,
|
||||
connectTimeout: 10000
|
||||
}
|
||||
if (dnsConfig) {
|
||||
const dns = DnsUtil.hasDnsLookup(dnsConfig, hostname)
|
||||
if (dns) {
|
||||
options.lookup = (hostname, options, callback) => {
|
||||
dns.lookup(hostname).then(ip => {
|
||||
isDnsIntercept = { dns, hostname, ip }
|
||||
if (ip !== hostname) {
|
||||
callback(null, ip, 4)
|
||||
} else {
|
||||
defaultDns.lookup(hostname, options, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
const proxySocket = net.connect(options, () => {
|
||||
cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
|
||||
'Proxy-agent: dev-sidecar\r\n' +
|
||||
'\r\n')
|
||||
|
|
|
@ -18,6 +18,7 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
|
|||
} else {
|
||||
req.socket.setKeepAlive(true, 30000)
|
||||
}
|
||||
const context = {}
|
||||
|
||||
const requestInterceptorPromise = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -26,7 +27,7 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
|
|||
}
|
||||
try {
|
||||
if (typeof requestInterceptor === 'function') {
|
||||
requestInterceptor(rOptions, req, res, ssl, next)
|
||||
requestInterceptor(rOptions, req, res, ssl, next, context)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
|
@ -82,15 +83,11 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
|
|||
const end = new Date().getTime()
|
||||
console.error('代理请求错误', e.errno, rOptions.hostname, rOptions.path, (end - start) + 'ms')
|
||||
reject(e)
|
||||
if (res) {
|
||||
res.end()
|
||||
}
|
||||
})
|
||||
|
||||
proxyReq.on('aborted', () => {
|
||||
console.error('代理请求被取消', rOptions.hostname, rOptions.path)
|
||||
reject(new Error('代理请求被取消'))
|
||||
req.destroy()
|
||||
})
|
||||
|
||||
req.on('aborted', function () {
|
||||
|
@ -101,9 +98,6 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
|
|||
req.on('error', function (e, req, res) {
|
||||
console.error('请求错误:', e.errno, rOptions.hostname, rOptions.path)
|
||||
reject(e)
|
||||
if (res) {
|
||||
res.end()
|
||||
}
|
||||
})
|
||||
req.on('timeout', () => {
|
||||
console.error('请求超时', rOptions.hostname, rOptions.path)
|
||||
|
@ -130,7 +124,7 @@ module.exports = function createRequestHandler (requestInterceptor, responseInte
|
|||
}
|
||||
try {
|
||||
if (typeof responseInterceptor === 'function') {
|
||||
responseInterceptor(req, res, proxyReq, proxyRes, ssl, next)
|
||||
responseInterceptor(req, res, proxyReq, proxyRes, ssl, next, context)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ module.exports = (config) => {
|
|||
}
|
||||
return !!matchHostname(intercepts, hostname) // 配置了拦截的域名,将会被代理
|
||||
},
|
||||
requestInterceptor: (rOptions, req, res, ssl, next) => {
|
||||
requestInterceptor: (rOptions, req, res, ssl, next, context) => {
|
||||
const hostname = rOptions.hostname
|
||||
const interceptOpts = matchHostname(intercepts, hostname)
|
||||
if (!interceptOpts) { // 该域名没有配置拦截器,直接过
|
||||
|
@ -83,7 +83,7 @@ module.exports = (config) => {
|
|||
continue
|
||||
}
|
||||
try {
|
||||
const result = interceptImpl.requestInterceptor(interceptOpt, rOptions, req, res, ssl)
|
||||
const result = interceptImpl.requestInterceptor(interceptOpt, rOptions, req, res, ssl, context)
|
||||
if (result) { // 拦截成功,其他拦截器就不处理了
|
||||
return
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ module.exports = (config) => {
|
|||
}
|
||||
next()
|
||||
},
|
||||
responseInterceptor: (req, res, proxyReq, proxyRes, ssl, next) => {
|
||||
responseInterceptor: (req, res, proxyReq, proxyRes, ssl, next, context) => {
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
const https = require('https')
|
||||
|
||||
var options = {
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
|
||||
}
|
||||
}
|
||||
|
||||
var request = https.get('https://api.github.com/', options, function (response) {
|
||||
response.on('data', function (data) {
|
||||
process.stdout.write(data)
|
||||
})
|
||||
})
|
||||
|
||||
request.on('error', function (error) {
|
||||
console.log(error)
|
||||
})
|
Loading…
Reference in New Issue