代码格式调整:packages/mitmproxy/**/*.js
parent
48132c39b0
commit
3e586bfd9b
|
@ -1,13 +1,14 @@
|
|||
const mitmproxy = require('./lib/proxy')
|
||||
const ProxyOptions = require('./options')
|
||||
const proxyConfig = require('./lib/proxy/common/config')
|
||||
const speedTest = require('./lib/speed/index.js')
|
||||
const ProxyOptions = require('./options')
|
||||
const log = require('./utils/util.log')
|
||||
const { fireError, fireStatus } = require('./utils/util.process')
|
||||
const speedTest = require('./lib/speed/index.js')
|
||||
|
||||
let servers = []
|
||||
|
||||
function registerProcessListener () {
|
||||
process.on('message', function (msg) {
|
||||
process.on('message', (msg) => {
|
||||
log.info('child get msg:', JSON.stringify(msg))
|
||||
if (msg.type === 'action') {
|
||||
api[msg.event.key](msg.event.params)
|
||||
|
@ -22,7 +23,7 @@ function registerProcessListener () {
|
|||
})
|
||||
|
||||
// 避免异常崩溃
|
||||
process.on('uncaughtException', function (err) {
|
||||
process.on('uncaughtException', (err) => {
|
||||
if (err.code === 'ECONNABORTED') {
|
||||
// log.error(err.errno)
|
||||
return
|
||||
|
@ -37,7 +38,7 @@ function registerProcessListener () {
|
|||
process.on('uncaughtExceptionMonitor', (err, origin) => {
|
||||
log.info('Process uncaughtExceptionMonitor:', err, origin)
|
||||
})
|
||||
process.on('exit', function (code, signal) {
|
||||
process.on('exit', (code, signal) => {
|
||||
log.info('代理服务进程被关闭:', code, signal)
|
||||
})
|
||||
process.on('beforeExit', (code, signal) => {
|
||||
|
@ -115,12 +116,12 @@ const api = {
|
|||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
...api,
|
||||
config: proxyConfig,
|
||||
log,
|
||||
speedTest
|
||||
speedTest,
|
||||
}
|
||||
|
|
|
@ -24,5 +24,5 @@ module.exports = {
|
|||
return obj
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
const LRU = require('lru-cache')
|
||||
const cacheSize = 1024
|
||||
const log = require('../../utils/util.log')
|
||||
|
||||
const cacheSize = 1024
|
||||
|
||||
class ChoiceCache {
|
||||
constructor () {
|
||||
this.cache = new LRU(cacheSize)
|
||||
|
@ -126,5 +128,5 @@ class DynamicChoice {
|
|||
|
||||
module.exports = {
|
||||
DynamicChoice,
|
||||
ChoiceCache
|
||||
ChoiceCache,
|
||||
}
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
const LRU = require('lru-cache')
|
||||
// const { isIP } = require('validator')
|
||||
const log = require('../../utils/util.log')
|
||||
const { DynamicChoice } = require('../choice/index')
|
||||
|
||||
const cacheSize = 1024
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// function _isIP (v) {
|
||||
// return v && isIP(v)
|
||||
// }
|
||||
|
||||
class IpCache extends DynamicChoice {
|
||||
constructor (hostname) {
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
const { promisify } = require('util')
|
||||
const doh = require('dns-over-http')
|
||||
const BaseDNS = require('./base')
|
||||
const log = require('../../utils/util.log')
|
||||
const dohQueryAsync = promisify(doh.query)
|
||||
const matchUtil = require('../../utils/util.match')
|
||||
const BaseDNS = require('./base')
|
||||
|
||||
const dohQueryAsync = promisify(doh.query)
|
||||
|
||||
function mapToList (ipMap) {
|
||||
const ipList = []
|
||||
for (const key in ipMap) {
|
||||
if (!ipMap[key]) continue
|
||||
if (!ipMap[key]) {
|
||||
continue
|
||||
}
|
||||
ipList.push(ipMap[key])
|
||||
}
|
||||
return ipList
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const DNSOverTLS = require('./tls.js')
|
||||
const matchUtil = require('../../utils/util.match')
|
||||
const DNSOverHTTPS = require('./https.js')
|
||||
const DNSOverIpAddress = require('./ipaddress.js')
|
||||
const DNSOverPreSetIpList = require('./preset.js')
|
||||
const matchUtil = require('../../utils/util.match')
|
||||
const DNSOverTLS = require('./tls.js')
|
||||
|
||||
module.exports = {
|
||||
initDNS (dnsProviders, preSetIpList) {
|
||||
|
@ -50,5 +50,5 @@ module.exports = {
|
|||
if (providerName) {
|
||||
return dnsConfig.dnsMap[providerName]
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const BaseDNS = require('./base')
|
||||
const axios = require('axios')
|
||||
const log = require('../../utils/util.log')
|
||||
const BaseDNS = require('./base')
|
||||
|
||||
module.exports = class DNSOverIpAddress extends BaseDNS {
|
||||
async _lookup (hostname) {
|
||||
const url = `https://${hostname}.ipaddress.com`
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
module.exports = {
|
||||
lookup () {
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
const BaseDNS = require('./base')
|
||||
const matchUtil = require('../../utils/util.match')
|
||||
const BaseDNS = require('./base')
|
||||
|
||||
function mapToList (ipMap) {
|
||||
const ipList = []
|
||||
for (const key in ipMap) {
|
||||
if (!ipMap[key]) continue
|
||||
if (!ipMap[key]) {
|
||||
continue
|
||||
}
|
||||
ipList.push(ipMap[key])
|
||||
}
|
||||
return ipList
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const dnstls = require('dns-over-tls')
|
||||
const BaseDNS = require('./base')
|
||||
const log = require('../../utils/util.log')
|
||||
const BaseDNS = require('./base')
|
||||
|
||||
module.exports = class DNSOverTLS extends BaseDNS {
|
||||
async _lookup (hostname) {
|
||||
const { answers } = await dnstls.query(hostname)
|
||||
|
|
|
@ -34,7 +34,7 @@ module.exports = {
|
|||
'Access-Control-Allow-Headers': allowHeaders,
|
||||
'Access-Control-Allow-Methods': allowMethods,
|
||||
'Access-Control-Max-Age': interceptOpt.optionsMaxAge > 0 ? interceptOpt.optionsMaxAge : 2592000, // 默认有效一个月
|
||||
Date: new Date().toUTCString()
|
||||
'Date': new Date().toUTCString(),
|
||||
}
|
||||
|
||||
// 判断是否允许
|
||||
|
@ -50,5 +50,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.options
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ module.exports = {
|
|||
|
||||
res.writeHead(403, {
|
||||
'Content-Type': 'text/plain; charset=utf-8',
|
||||
'DS-Interceptor': 'abort'
|
||||
'DS-Interceptor': 'abort',
|
||||
})
|
||||
res.write(
|
||||
'DevSidecar 403: Request abort.\r\n\r\n' +
|
||||
' This request is matched by abort intercept.\r\n' +
|
||||
' 因配置abort拦截器,本请求直接返回403禁止访问。'
|
||||
'DevSidecar 403: Request abort.\n\n'
|
||||
+ ' This request is matched by abort intercept.\n'
|
||||
+ ' 因配置abort拦截器,本请求直接返回403禁止访问。',
|
||||
)
|
||||
res.end()
|
||||
|
||||
|
@ -21,5 +21,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.abort
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -22,13 +22,13 @@ function getTomorrow () {
|
|||
// }
|
||||
|
||||
const AipOcrClient = require('baidu-aip-sdk').ocr
|
||||
|
||||
const AipOcrClientMap = {}
|
||||
const apis = [
|
||||
'accurateBasic', // 调用通用文字识别(高精度版)
|
||||
'accurate', // 调用通用文字识别(含位置高精度版)
|
||||
'handwriting' // 手写文字识别
|
||||
'handwriting', // 手写文字识别
|
||||
]
|
||||
|
||||
const limitMap = {}
|
||||
|
||||
function createBaiduOcrClient (config) {
|
||||
|
@ -57,7 +57,9 @@ function getConfig (interceptOpt, tryCount, log) {
|
|||
}
|
||||
|
||||
// 避免count值过大,造成问题
|
||||
if (count >= 100000) count = 0
|
||||
if (count >= 100000) {
|
||||
count = 0
|
||||
}
|
||||
} else {
|
||||
config = interceptOpt.baiduOcr
|
||||
tryCount = null // 将tryCount设置为null代表只有一个配置
|
||||
|
@ -95,13 +97,13 @@ function getConfig (interceptOpt, tryCount, log) {
|
|||
}
|
||||
|
||||
function limitConfig (id, api) {
|
||||
const key = id + '_' + api
|
||||
const key = `${id}_${api}`
|
||||
limitMap[key] = getTomorrow()
|
||||
// limitMap[key] = Date.now() + 5000 // 测试用,5秒后解禁
|
||||
}
|
||||
|
||||
function checkIsLimitConfig (id, api) {
|
||||
const key = id + '_' + api
|
||||
const key = `${id}_${api}`
|
||||
const limitTime = limitMap[key]
|
||||
return limitTime && limitTime > Date.now()
|
||||
}
|
||||
|
@ -114,7 +116,7 @@ module.exports = {
|
|||
|
||||
const headers = {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'Access-Control-Allow-Origin': '*'
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
|
@ -151,10 +153,10 @@ module.exports = {
|
|||
detect_direction: 'false',
|
||||
paragraph: 'false',
|
||||
probability: 'false',
|
||||
...(config.options || {})
|
||||
...(config.options || {}),
|
||||
}
|
||||
log.info('发起百度ocr请求', req.hostname)
|
||||
client[config.api || apis[0]](imageBase64, options).then(function (result) {
|
||||
client[config.api || apis[0]](imageBase64, options).then((result) => {
|
||||
if (result.error_code != null) {
|
||||
log.error('baiduOcr error:', result)
|
||||
if (result.error_code === 17) {
|
||||
|
@ -170,12 +172,14 @@ module.exports = {
|
|||
res.write(JSON.stringify(result)) // 格式如:{"words_result":[{"words":"6525"}],"words_result_num":1,"log_id":1818877093747960000}
|
||||
res.end()
|
||||
if (next) next() // 异步执行完继续next
|
||||
}).catch(function (err) {
|
||||
}).catch((err) => {
|
||||
log.info('baiduOcr error:', err)
|
||||
res.writeHead(200, headers)
|
||||
res.write('{"error_code": 999500, "error_msg": "' + err + '"}') // 格式如:{"words_result":[{"words":"6525"}],"words_result_num":1,"log_id":1818877093747960000}
|
||||
res.write(`{"error_code": 999500, "error_msg": "${err}"}`) // 格式如:{"words_result":[{"words":"6525"}],"words_result_num":1,"log_id":1818877093747960000}
|
||||
res.end()
|
||||
if (next) next() // 异步执行完继续next
|
||||
if (next) {
|
||||
next() // 异步执行完继续next
|
||||
}
|
||||
})
|
||||
|
||||
log.info('proxy baiduOcr: hostname:', req.hostname)
|
||||
|
@ -184,5 +188,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.baiduOcr
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ function getLastModifiedTimeFromIfModifiedSince (rOptions, log) {
|
|||
return new Date(lastModified).getTime()
|
||||
} catch (e) {
|
||||
// 为数字时,直接返回
|
||||
if (/\\d+/g.test(lastModified)) {
|
||||
if (/\\d+/.test(lastModified)) {
|
||||
return lastModified - 0
|
||||
}
|
||||
|
||||
|
@ -66,12 +66,12 @@ module.exports = {
|
|||
|
||||
// 获取 Cache-Control 用于判断是否禁用缓存
|
||||
const cacheControl = rOptions.headers['cache-control']
|
||||
if (cacheControl && (cacheControl.indexOf('no-cache') >= 0 || cacheControl.indexOf('no-store') >= 0)) {
|
||||
if (cacheControl && (cacheControl.includes('no-cache') || cacheControl.includes('no-store'))) {
|
||||
return // 当前请求指定要禁用缓存,跳过当前拦截器
|
||||
}
|
||||
// 获取 Pragma 用于判断是否禁用缓存
|
||||
const pragma = rOptions.headers.pragma
|
||||
if (pragma && (pragma.indexOf('no-cache') >= 0 || pragma.indexOf('no-store') >= 0)) {
|
||||
if (pragma && (pragma.includes('no-cache') || pragma.includes('no-store'))) {
|
||||
return // 当前请求指定要禁用缓存,跳过当前拦截器
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ module.exports = {
|
|||
|
||||
// 缓存未过期,直接拦截请求并响应304
|
||||
res.writeHead(304, {
|
||||
'DS-Interceptor': 'cache: ' + maxAge
|
||||
'DS-Interceptor': `cache: ${maxAge}`,
|
||||
})
|
||||
res.end()
|
||||
|
||||
|
@ -103,5 +103,5 @@ module.exports = {
|
|||
const maxAge = getMaxAge(interceptOpt)
|
||||
return maxAge != null && maxAge > 0
|
||||
},
|
||||
getMaxAge
|
||||
getMaxAge,
|
||||
}
|
||||
|
|
|
@ -3,21 +3,20 @@ const lodash = require('lodash')
|
|||
|
||||
// 替换占位符
|
||||
function replacePlaceholder (url, rOptions, matched) {
|
||||
if (url.indexOf('${') >= 0) {
|
||||
// eslint-disable-next-line
|
||||
if (url.includes('${')) {
|
||||
// no-template-curly-in-string
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
url = url.replace('${host}', rOptions.hostname)
|
||||
|
||||
if (matched && url.indexOf('${') >= 0) {
|
||||
if (matched && url.includes('${')) {
|
||||
for (let i = 0; i < matched.length; i++) {
|
||||
url = url.replace('${m[' + i + ']}', matched[i] == null ? '' : matched[i])
|
||||
url = url.replace(`\${m[${i}]}`, matched[i] == null ? '' : matched[i])
|
||||
}
|
||||
}
|
||||
|
||||
// 移除多余的占位符
|
||||
if (url.indexOf('${') >= 0) {
|
||||
url = url.replace(/\$\{[^}]+}/g, '')
|
||||
if (url.includes('${')) {
|
||||
url = url.replace(/\$\{[^}]+\}/g, '')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +44,7 @@ function buildTargetUrl (rOptions, urlConf, interceptOpt, matched) {
|
|||
targetUrl = replacePlaceholder(targetUrl, rOptions, matched)
|
||||
|
||||
// 拼接协议
|
||||
targetUrl = targetUrl.indexOf('http:') === 0 || targetUrl.indexOf('https:') === 0 ? targetUrl : rOptions.protocol + '//' + targetUrl
|
||||
targetUrl = targetUrl.indexOf('http:') === 0 || targetUrl.indexOf('https:') === 0 ? targetUrl : `${rOptions.protocol}//${targetUrl}`
|
||||
|
||||
return targetUrl
|
||||
}
|
||||
|
@ -90,7 +89,7 @@ module.exports = {
|
|||
for (const bk of interceptOpt.backup) {
|
||||
backupList.push(bk)
|
||||
}
|
||||
const key = rOptions.hostname + '/' + interceptOpt.key
|
||||
const key = `${rOptions.hostname}/${interceptOpt.key}`
|
||||
const count = RequestCounter.getOrCreate(key, backupList)
|
||||
if (count.value == null) {
|
||||
count.doRank()
|
||||
|
@ -103,7 +102,7 @@ module.exports = {
|
|||
context.requestCount = {
|
||||
key,
|
||||
value: count.value,
|
||||
count
|
||||
count,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,5 +134,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.proxy
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ module.exports = {
|
|||
const redirect = proxyApi.buildTargetUrl(rOptions, interceptOpt.redirect, interceptOpt, matched)
|
||||
|
||||
res.writeHead(302, {
|
||||
Location: redirect,
|
||||
'DS-Interceptor': 'redirect'
|
||||
'Location': redirect,
|
||||
'DS-Interceptor': 'redirect',
|
||||
})
|
||||
res.end()
|
||||
|
||||
|
@ -21,5 +21,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return interceptOpt.redirect // 如果配置中有redirect,那么这个配置是需要redirect拦截的
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ module.exports = {
|
|||
// 替换请求头
|
||||
if (requestReplaceConfig.headers) {
|
||||
replaceRequestHeaders(rOptions, requestReplaceConfig.headers, log)
|
||||
actions += (actions ? ',' : '') + 'headers'
|
||||
actions += `${actions ? ',' : ''}headers`
|
||||
}
|
||||
|
||||
// 替换下载文件请求的请求地址(此功能主要是为了方便拦截配置)
|
||||
|
@ -40,7 +40,7 @@ module.exports = {
|
|||
if (requestReplaceConfig.doDownload && rOptions.path.match(/DS_DOWNLOAD/i)) {
|
||||
rOptions.doDownload = true
|
||||
rOptions.path = rOptions.path.replace(/[?&/]?DS_DOWNLOAD(=[^?&/]+)?$/gi, '')
|
||||
actions += (actions ? ',' : '') + 'path:remove-DS_DOWNLOAD'
|
||||
actions += `${actions ? ',' : ''}path:remove-DS_DOWNLOAD`
|
||||
}
|
||||
|
||||
res.setHeader('DS-RequestReplace-Interceptor', actions)
|
||||
|
@ -50,5 +50,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.requestReplace
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -19,5 +19,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.sni && !interceptOpt.proxy // proxy生效时,sni不需要生效,因为proxy中也会使用sni覆盖 rOptions.servername
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ module.exports = {
|
|||
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/plain; charset=utf-8',
|
||||
'DS-Interceptor': 'success'
|
||||
'DS-Interceptor': 'success',
|
||||
})
|
||||
res.write(
|
||||
'DevSidecar 200: Request success.\n\n' +
|
||||
' This request is matched by success intercept.\n\n' +
|
||||
' 因配置success拦截器,本请求直接返回200成功。'
|
||||
'DevSidecar 200: Request success.\n\n'
|
||||
+ ' This request is matched by success intercept.\n\n'
|
||||
+ ' 因配置success拦截器,本请求直接返回200成功。',
|
||||
)
|
||||
res.end()
|
||||
|
||||
|
@ -21,5 +21,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.success
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
const headers = {
|
||||
'Access-Control-Allow-Origin': rOptions.headers.origin
|
||||
'Access-Control-Allow-Origin': rOptions.headers.origin,
|
||||
}
|
||||
|
||||
// 替换响应头
|
||||
|
@ -23,5 +23,5 @@ module.exports = {
|
|||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.options
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
// 判断当前响应码是否不使用缓存
|
||||
if (interceptOpt.cacheExcludeStatusCodeList && interceptOpt.cacheExcludeStatusCodeList[proxyRes.statusCode + '']) {
|
||||
if (interceptOpt.cacheExcludeStatusCodeList && interceptOpt.cacheExcludeStatusCodeList[`${proxyRes.statusCode}`]) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ module.exports = {
|
|||
// 获取maxAge配置
|
||||
let maxAge = cacheReq.getMaxAge(interceptOpt)
|
||||
// public 或 private
|
||||
const cacheControlType = (interceptOpt.cacheControlType || 'public') + ', '
|
||||
const cacheControlType = `${interceptOpt.cacheControlType || 'public'}, `
|
||||
// immutable属性
|
||||
const cacheImmutable = interceptOpt.cacheImmutable !== false ? ', immutable' : ''
|
||||
|
||||
|
@ -41,7 +41,7 @@ module.exports = {
|
|||
cacheControl: null,
|
||||
lastModified: null,
|
||||
expires: null,
|
||||
etag: null
|
||||
etag: null,
|
||||
}
|
||||
for (let i = 0; i < proxyRes.rawHeaders.length; i += 2) {
|
||||
// 尝试修改rawHeaders中的cache-control、last-modified、expires
|
||||
|
@ -65,7 +65,7 @@ module.exports = {
|
|||
if (originalHeaders.cacheControl) {
|
||||
const maxAgeMatch = originalHeaders.cacheControl.value.match(/max-age=(\d+)/)
|
||||
if (maxAgeMatch && maxAgeMatch[1] > maxAge) {
|
||||
if (interceptOpt.cacheImmutable !== false && originalHeaders.cacheControl.value.indexOf('immutable') < 0) {
|
||||
if (interceptOpt.cacheImmutable !== false && !originalHeaders.cacheControl.value.includes('immutable')) {
|
||||
maxAge = maxAgeMatch[1]
|
||||
} else {
|
||||
const url = `${rOptions.method} ➜ ${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${req.url}`
|
||||
|
@ -81,7 +81,7 @@ module.exports = {
|
|||
const replaceHeaders = {
|
||||
cacheControl: `${cacheControlType}max-age=${maxAge + 1}${cacheImmutable}`,
|
||||
lastModified: now.toUTCString(),
|
||||
expires: new Date(now.getTime() + maxAge * 1000).toUTCString()
|
||||
expires: new Date(now.getTime() + maxAge * 1000).toUTCString(),
|
||||
}
|
||||
// 开始替换
|
||||
// 替换cache-control
|
||||
|
@ -108,5 +108,5 @@ module.exports = {
|
|||
is (interceptOpt) {
|
||||
const maxAge = cacheReq.getMaxAge(interceptOpt)
|
||||
return maxAge != null && maxAge > 0
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const lodash = require('lodash')
|
||||
const cacheReq = require('../req/cacheReq')
|
||||
|
||||
const REMOVE = '[remove]'
|
||||
|
||||
// 替换响应头
|
||||
|
@ -96,20 +97,20 @@ module.exports = {
|
|||
replaceHeaders.expires = '[remove]'
|
||||
}
|
||||
|
||||
actions += (actions ? ',' : '') + 'download:' + filename
|
||||
actions += `${actions ? ',' : ''}download:${filename}`
|
||||
}
|
||||
|
||||
// 替换响应头
|
||||
if (replaceResponseHeaders(replaceHeaders, res, proxyRes)) {
|
||||
actions += (actions ? ',' : '') + 'headers'
|
||||
actions += `${actions ? ',' : ''}headers`
|
||||
}
|
||||
|
||||
if (actions) {
|
||||
res.setHeader('DS-ResponseReplace-Interceptor', actions)
|
||||
log.info('response intercept: ' + actions)
|
||||
log.info(`response intercept: ${actions}`)
|
||||
}
|
||||
},
|
||||
is (interceptOpt) {
|
||||
return !!interceptOpt.responseReplace
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
// 如果没有响应头 'content-type',或其值不是 'text/html',则不处理
|
||||
if (!proxyRes.headers['content-type'] || proxyRes.headers['content-type'].indexOf('text/html') < 0) {
|
||||
if (!proxyRes.headers['content-type'] || !proxyRes.headers['content-type'].includes('text/html')) {
|
||||
res.setHeader('DS-Script-Interceptor', 'Not text/html')
|
||||
return
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ module.exports = {
|
|||
|
||||
let scriptTag
|
||||
|
||||
if (key.indexOf('/') >= 0) {
|
||||
if (key.includes('/')) {
|
||||
scriptTag = getScriptByUrlOrPath(key) // 1.绝对地址或相对地址(注意:当目标站点限制跨域脚本时,可使用相对地址,再结合proxy拦截器进行代理,可规避掉限制跨域脚本问题。)
|
||||
} else {
|
||||
const script = scripts[key]
|
||||
|
@ -60,7 +60,7 @@ module.exports = {
|
|||
scriptTag = getScript(key, script.script) // 2.DS内置脚本
|
||||
}
|
||||
|
||||
tags += '\r\n\t' + scriptTag
|
||||
tags += `\r\n\t${scriptTag}`
|
||||
}
|
||||
|
||||
// 如果脚本为空,则不插入
|
||||
|
@ -70,15 +70,15 @@ module.exports = {
|
|||
|
||||
// 插入油猴脚本浏览器扩展
|
||||
if (typeof interceptOpt.tampermonkeyScript === 'string') {
|
||||
tags = '\r\n\t' + getScriptByUrlOrPath(interceptOpt.tampermonkeyScript) + tags
|
||||
tags = `\r\n\t${getScriptByUrlOrPath(interceptOpt.tampermonkeyScript)}${tags}`
|
||||
} else {
|
||||
tags = '\r\n\t' + getScript('tampermonkey', scripts.tampermonkey.script) + tags
|
||||
tags = `\r\n\t${getScript('tampermonkey', scripts.tampermonkey.script)}${tags}`
|
||||
}
|
||||
|
||||
res.setHeader('DS-Script-Interceptor', 'true')
|
||||
log.info(`script response intercept: insert script ${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`, ', head:', tags)
|
||||
return {
|
||||
head: tags + '\r\n'
|
||||
head: `${tags}\r\n`,
|
||||
}
|
||||
} catch (err) {
|
||||
try {
|
||||
|
@ -102,10 +102,12 @@ module.exports = {
|
|||
const handleScriptUrl = (scriptUrl, name, replaceScriptUrlFun) => {
|
||||
if (scriptUrl.indexOf('https:') === 0 || scriptUrl.indexOf('http:') === 0) {
|
||||
// 绝对地址
|
||||
const scriptKey = SCRIPT_PROXY_URL_PRE + scriptUrl.replace('.js', '').replace(/[\W_]+/g, '_') + '.js' // 伪脚本地址:移除 script 中可能存在的特殊字符,并转为相对地址
|
||||
const scriptKey = `${SCRIPT_PROXY_URL_PRE + scriptUrl.replace('.js', '').replace(/[\W_]+/g, '_')}.js` // 伪脚本地址:移除 script 中可能存在的特殊字符,并转为相对地址
|
||||
scriptProxy[scriptKey] = scriptUrl
|
||||
log.info(`替换${name}配置值:'${scriptUrl}' -> '${scriptKey}'`)
|
||||
if (typeof replaceScriptUrlFun === 'function') replaceScriptUrlFun(scriptKey)
|
||||
if (typeof replaceScriptUrlFun === 'function') {
|
||||
replaceScriptUrlFun(scriptKey)
|
||||
}
|
||||
} else if (scriptUrl.indexOf('/') === 0) {
|
||||
// 相对地址
|
||||
scriptProxy[scriptUrl] = scriptUrl
|
||||
|
@ -154,19 +156,19 @@ module.exports = {
|
|||
headers: {
|
||||
host: REMOVE,
|
||||
referer: REMOVE,
|
||||
cookie: REMOVE
|
||||
}
|
||||
cookie: REMOVE,
|
||||
},
|
||||
},
|
||||
// 替换和移除部分响应头,避免触发目标站点的阻止脚本加载策略
|
||||
responseReplace: {
|
||||
headers: {
|
||||
'content-type': 'application/javascript; charset=utf-8',
|
||||
'set-cookie': REMOVE,
|
||||
server: REMOVE
|
||||
}
|
||||
'server': REMOVE,
|
||||
},
|
||||
},
|
||||
cacheDays: 7,
|
||||
desc: "为伪脚本文件设置代理地址,并设置响应头 `content-type: 'application/javascript; charset=utf-8'`,同时缓存7天。"
|
||||
desc: '为伪脚本文件设置代理地址,并设置响应头 `content-type: \'application/javascript; charset=utf-8\'`,同时缓存7天。',
|
||||
}
|
||||
|
||||
const obj = {}
|
||||
|
@ -181,11 +183,11 @@ module.exports = {
|
|||
hostnameConfig[scriptKey] = {
|
||||
responseReplace: {
|
||||
headers: {
|
||||
'content-type': 'application/javascript; charset=utf-8'
|
||||
}
|
||||
'content-type': 'application/javascript; charset=utf-8',
|
||||
},
|
||||
},
|
||||
cacheDays: 7,
|
||||
desc: "为脚本设置响应头 `content-type: 'application/javascript; charset=utf-8'`,同时缓存7天。"
|
||||
desc: '为脚本设置响应头 `content-type: \'application/javascript; charset=utf-8\'`,同时缓存7天。',
|
||||
}
|
||||
|
||||
const obj = {}
|
||||
|
@ -195,5 +197,5 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const log = require('../../utils/util.log')
|
||||
|
||||
let scripts
|
||||
|
||||
function buildScript (sc, content, scriptName) {
|
||||
const scriptKey = `ds_${scriptName}${sc.version ? ('_' + sc.version) : ''}:`
|
||||
const scriptKey = `ds_${scriptName}${sc.version ? (`_${sc.version}`) : ''}:`
|
||||
|
||||
// 代码1:监听事件
|
||||
const runAt = sc['run-at'] || 'document-end'
|
||||
|
@ -19,7 +20,7 @@ function buildScript (sc, content, scriptName) {
|
|||
const options = {
|
||||
name: sc.name,
|
||||
version: sc.version,
|
||||
icon: sc.icon
|
||||
icon: sc.icon,
|
||||
}
|
||||
const initStr = `
|
||||
const DS_init = (window.__ds_global__ || {})['DS_init']
|
||||
|
@ -45,21 +46,21 @@ if (!((window.__ds_global__ || {}).GM_getValue || (() => true))("ds_enabled", tr
|
|||
}
|
||||
|
||||
if (item.indexOf('.') > 0) {
|
||||
grantStr += item + ' = (window.__ds_global__ || {})[\'' + item + '\'];'
|
||||
grantStr += `${item} = (window.__ds_global__ || {})['${item}'];`
|
||||
} else {
|
||||
grantStr += 'const ' + item + ' = (window.__ds_global__ || {})[\'' + item + '\'] || (() => {});'
|
||||
grantStr += `const ${item} = (window.__ds_global__ || {})['${item}'] || (() => {});`
|
||||
}
|
||||
}
|
||||
|
||||
// 拼接脚本
|
||||
return eventStr + ', () => {' +
|
||||
initStr + '\r\n' +
|
||||
checkEnabledStr + '\r\n\r\n' +
|
||||
(grantStr ? (grantStr + '\r\n\r\n') : '') +
|
||||
content +
|
||||
`\r\nconsole.log("${scriptKey} completed")` +
|
||||
'\r\n})' +
|
||||
`\r\nconsole.log("${scriptKey} loaded")`
|
||||
return `${eventStr}, () => {${
|
||||
initStr}\r\n${
|
||||
checkEnabledStr}\r\n\r\n${
|
||||
grantStr ? (`${grantStr}\r\n\r\n`) : ''
|
||||
}${content
|
||||
}\r\nconsole.log("${scriptKey} completed")`
|
||||
+ `\r\n})`
|
||||
+ `\r\nconsole.log("${scriptKey} loaded")`
|
||||
}
|
||||
|
||||
function loadScript (content, scriptName) {
|
||||
|
@ -78,10 +79,10 @@ function loadScript (content, scriptName) {
|
|||
const sc = {
|
||||
grant: [],
|
||||
match: [],
|
||||
script: ''
|
||||
script: '',
|
||||
}
|
||||
for (const string of confItemArr) {
|
||||
const reg = new RegExp('.*@([^\\s]+)\\s(.+)')
|
||||
const reg = new RegExp('.*@(\\S+)\\s(.+)')
|
||||
const ret = string.match(reg)
|
||||
if (ret) {
|
||||
const key = ret[1].trim()
|
||||
|
@ -103,7 +104,7 @@ function loadScript (content, scriptName) {
|
|||
|
||||
function readFile (rootDir, script) {
|
||||
log.info('read script, script root location:', path.resolve('./'))
|
||||
const location = path.join(rootDir, './' + script)
|
||||
const location = path.join(rootDir, `./${script}`)
|
||||
log.info('read script, the script location:', location)
|
||||
return fs.readFileSync(location).toString()
|
||||
}
|
||||
|
@ -123,7 +124,7 @@ const api = {
|
|||
scripts.tampermonkey = { script: readFile(rootDir, 'tampermonkey.script') }
|
||||
return scripts
|
||||
},
|
||||
loadScript
|
||||
loadScript,
|
||||
}
|
||||
|
||||
module.exports = api
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const path = require('path')
|
||||
|
||||
const config = exports
|
||||
|
||||
config.defaultHost = '127.0.0.1'
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
const url = require('url')
|
||||
const Agent = require('./ProxyHttpAgent')
|
||||
const HttpsAgent = require('./ProxyHttpsAgent')
|
||||
const tunnelAgent = require('tunnel-agent')
|
||||
const log = require('../../../utils/util.log')
|
||||
const matchUtil = require('../../../utils/util.match')
|
||||
const Agent = require('./ProxyHttpAgent')
|
||||
const HttpsAgent = require('./ProxyHttpsAgent')
|
||||
|
||||
const util = exports
|
||||
|
||||
const httpsAgentCache = {}
|
||||
|
@ -25,7 +26,7 @@ function getTimeoutConfig (hostname, serverSetting) {
|
|||
}
|
||||
|
||||
function createHttpsAgent (timeoutConfig, verifySsl) {
|
||||
const key = timeoutConfig.timeout + '-' + timeoutConfig.keepAliveTimeout
|
||||
const key = `${timeoutConfig.timeout}-${timeoutConfig.keepAliveTimeout}`
|
||||
if (!httpsAgentCache[key]) {
|
||||
verifySsl = !!verifySsl
|
||||
|
||||
|
@ -39,7 +40,7 @@ function createHttpsAgent (timeoutConfig, verifySsl) {
|
|||
timeout: timeoutConfig.timeout,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout,
|
||||
checkServerIdentity,
|
||||
rejectUnauthorized: verifySsl
|
||||
rejectUnauthorized: verifySsl,
|
||||
})
|
||||
|
||||
agent.unVerifySslAgent = new HttpsAgent({
|
||||
|
@ -47,7 +48,7 @@ function createHttpsAgent (timeoutConfig, verifySsl) {
|
|||
timeout: timeoutConfig.timeout,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout,
|
||||
checkServerIdentity,
|
||||
rejectUnauthorized: false
|
||||
rejectUnauthorized: false,
|
||||
})
|
||||
|
||||
httpsAgentCache[key] = agent
|
||||
|
@ -57,12 +58,12 @@ function createHttpsAgent (timeoutConfig, verifySsl) {
|
|||
}
|
||||
|
||||
function createHttpAgent (timeoutConfig) {
|
||||
const key = timeoutConfig.timeout + '-' + timeoutConfig.keepAliveTimeout
|
||||
const key = `${timeoutConfig.timeout}-${timeoutConfig.keepAliveTimeout}`
|
||||
if (!httpAgentCache[key]) {
|
||||
httpAgentCache[key] = new Agent({
|
||||
keepAlive: true,
|
||||
timeout: timeoutConfig.timeout,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout,
|
||||
})
|
||||
log.info('创建 HttpAgent 成功, timeoutConfig:', timeoutConfig)
|
||||
}
|
||||
|
@ -80,12 +81,12 @@ util.parseHostnameAndPort = (host, defaultPort) => {
|
|||
if (arr) {
|
||||
arr = arr.slice(1)
|
||||
if (arr[1]) {
|
||||
arr[1] = parseInt(arr[1], 10)
|
||||
arr[1] = Number.parseInt(arr[1], 10)
|
||||
}
|
||||
} else {
|
||||
arr = host.split(':')
|
||||
if (arr.length > 1) {
|
||||
arr[1] = parseInt(arr[1], 10)
|
||||
arr[1] = Number.parseInt(arr[1], 10)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +150,7 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null, serverSetting, com
|
|||
path: urlObject.path,
|
||||
headers: req.headers,
|
||||
agent,
|
||||
compatibleConfig
|
||||
compatibleConfig,
|
||||
}
|
||||
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
|
@ -188,8 +189,8 @@ util.getTunnelAgent = (requestIsSSL, externalProxyUrl) => {
|
|||
httpsOverHttpAgent = tunnelAgent.httpsOverHttp({
|
||||
proxy: {
|
||||
host: hostname,
|
||||
port: port
|
||||
}
|
||||
port,
|
||||
},
|
||||
})
|
||||
}
|
||||
return httpsOverHttpAgent
|
||||
|
@ -198,8 +199,8 @@ util.getTunnelAgent = (requestIsSSL, externalProxyUrl) => {
|
|||
httpsOverHttpsAgent = tunnelAgent.httpsOverHttps({
|
||||
proxy: {
|
||||
host: hostname,
|
||||
port: port
|
||||
}
|
||||
port,
|
||||
},
|
||||
})
|
||||
}
|
||||
return httpsOverHttpsAgent
|
||||
|
@ -220,8 +221,8 @@ util.getTunnelAgent = (requestIsSSL, externalProxyUrl) => {
|
|||
httpOverHttpsAgent = tunnelAgent.httpOverHttps({
|
||||
proxy: {
|
||||
host: hostname,
|
||||
port: port
|
||||
}
|
||||
port,
|
||||
},
|
||||
})
|
||||
}
|
||||
return httpOverHttpsAgent
|
||||
|
|
|
@ -25,7 +25,7 @@ const defaultConfig = {
|
|||
// 'xxx.xxx.xxx.xxx:443': {
|
||||
// rejectUnauthorized: false
|
||||
// }
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const config = _loadFromFile(defaultConfig)
|
||||
|
@ -63,8 +63,12 @@ function _loadFromFile (defaultConfig) {
|
|||
log.info('读取 automaticCompatibleConfig.json 成功:', configPath)
|
||||
const fileStr = file.toString()
|
||||
config = fileStr && fileStr.length > 2 ? jsonApi.parse(fileStr) : defaultConfig
|
||||
if (config.connect == null) config.connect = defaultConfig.connect
|
||||
if (config.request == null) config.request = defaultConfig.request
|
||||
if (config.connect == null) {
|
||||
config.connect = defaultConfig.connect
|
||||
}
|
||||
if (config.request == null) {
|
||||
config.request = defaultConfig.request
|
||||
}
|
||||
}
|
||||
|
||||
return config
|
||||
|
@ -108,7 +112,9 @@ module.exports = {
|
|||
}
|
||||
|
||||
// 配置保存到文件
|
||||
if (autoSave) _saveConfigToFile()
|
||||
if (autoSave) {
|
||||
_saveConfigToFile()
|
||||
}
|
||||
|
||||
log.info(`【自动兼容程序】${hostname}:${port}: 设置 connect.ssl = ${ssl}`)
|
||||
},
|
||||
|
@ -138,8 +144,10 @@ module.exports = {
|
|||
}
|
||||
|
||||
// 配置保存到文件
|
||||
if (autoSave) _saveConfigToFile()
|
||||
if (autoSave) {
|
||||
_saveConfigToFile()
|
||||
}
|
||||
|
||||
log.info(`【自动兼容程序】${rOptions.hostname}:${rOptions.port}: 设置 request.rejectUnauthorized = ${rejectUnauthorized}`)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
const log = require('../../../utils/util.log')
|
||||
const through = require('through2')
|
||||
const zlib = require('zlib')
|
||||
const through = require('through2')
|
||||
const log = require('../../../utils/util.log')
|
||||
|
||||
// 编解码器
|
||||
const codecMap = {
|
||||
gzip: {
|
||||
createCompressor: () => zlib.createGzip(),
|
||||
createDecompressor: () => zlib.createGunzip()
|
||||
createDecompressor: () => zlib.createGunzip(),
|
||||
},
|
||||
deflate: {
|
||||
createCompressor: () => zlib.createDeflate(),
|
||||
createDecompressor: () => zlib.createInflate()
|
||||
createDecompressor: () => zlib.createInflate(),
|
||||
},
|
||||
br: {
|
||||
createCompressor: () => zlib.createBrotliCompress(),
|
||||
createDecompressor: () => zlib.createBrotliDecompress()
|
||||
}
|
||||
createDecompressor: () => zlib.createBrotliDecompress(),
|
||||
},
|
||||
}
|
||||
const supportedEncodings = Object.keys(codecMap)
|
||||
const supportedEncodingsStr = supportedEncodings.join(', ')
|
||||
|
@ -41,7 +41,7 @@ const httpUtil = {
|
|||
isHtml (res) {
|
||||
const contentType = res.headers['content-type']
|
||||
return (typeof contentType !== 'undefined') && /text\/html|application\/xhtml\+xml/.test(contentType)
|
||||
}
|
||||
},
|
||||
}
|
||||
const HEAD = Buffer.from('</head>')
|
||||
const HEAD_UP = Buffer.from('</HEAD>')
|
||||
|
@ -84,7 +84,7 @@ function injectScriptIntoHtml (tags, chunk, script) {
|
|||
}
|
||||
|
||||
function handleResponseHeaders (res, proxyRes) {
|
||||
Object.keys(proxyRes.headers).forEach(function (key) {
|
||||
Object.keys(proxyRes.headers).forEach((key) => {
|
||||
if (proxyRes.headers[key] !== undefined) {
|
||||
// let newkey = key.replace(/^[a-z]|-[a-z]/g, (match) => {
|
||||
// return match.toUpperCase()
|
||||
|
@ -100,7 +100,7 @@ function handleResponseHeaders (res, proxyRes) {
|
|||
const reg = /script-src ([^:]*);/i
|
||||
const matched = policy.match(reg)
|
||||
if (matched) {
|
||||
if (matched[1].indexOf('self') < 0) {
|
||||
if (!matched[1].includes('self')) {
|
||||
policy = policy.replace('script-src', 'script-src \'self\' ')
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,7 @@ function handleResponseHeaders (res, proxyRes) {
|
|||
|
||||
const contextPath = '/____ds_script____/'
|
||||
const monkey = require('../../monkey')
|
||||
|
||||
module.exports = {
|
||||
requestIntercept (context, req, res, ssl, next) {
|
||||
const { rOptions, log, setting } = context
|
||||
|
@ -141,8 +142,8 @@ module.exports = {
|
|||
'Content-Type': 'application/javascript; charset=utf-8',
|
||||
'Cache-Control': 'public, max-age=86401, immutable', // 缓存1天
|
||||
'Last-Modified': now.toUTCString(),
|
||||
Expires: new Date(now.getTime() + 86400000).toUTCString(), // 缓存1天
|
||||
Date: new Date().toUTCString()
|
||||
'Expires': new Date(now.getTime() + 86400000).toUTCString(), // 缓存1天
|
||||
'Date': new Date().toUTCString(),
|
||||
})
|
||||
res.write(script.script)
|
||||
res.end()
|
||||
|
@ -194,5 +195,5 @@ module.exports = {
|
|||
next()
|
||||
},
|
||||
httpUtil,
|
||||
handleResponseHeaders
|
||||
handleResponseHeaders,
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
const url = require('url')
|
||||
const request = require('request')
|
||||
const lodash = require('lodash')
|
||||
const pac = require('./source/pac')
|
||||
const matchUtil = require('../../../utils/util.match')
|
||||
const log = require('../../../utils/util.log')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const { Buffer } = require('buffer')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const url = require('url')
|
||||
const lodash = require('lodash')
|
||||
const request = require('request')
|
||||
const log = require('../../../utils/util.log')
|
||||
const matchUtil = require('../../../utils/util.match')
|
||||
const pac = require('./source/pac')
|
||||
|
||||
let pacClient = null
|
||||
|
||||
function matched (hostname, overWallTargetMap) {
|
||||
|
@ -23,7 +24,7 @@ function matched (hostname, overWallTargetMap) {
|
|||
if (pacClient == null) {
|
||||
return null
|
||||
}
|
||||
const ret = pacClient.FindProxyForURL('https://' + hostname, hostname)
|
||||
const ret = pacClient.FindProxyForURL(`https://${hostname}`, hostname)
|
||||
if (ret && ret.indexOf('PROXY ') === 0) {
|
||||
log.info(`matchHostname: matched overwall: '${hostname}' -> '${ret}' in pac.txt`)
|
||||
return 'in pac.txt'
|
||||
|
@ -113,12 +114,12 @@ async function downloadPacAsync (pacConfig) {
|
|||
// 尝试解析Base64(注:https://gitlab.com/gfwlist/gfwlist/raw/master/gfwlist.txt 下载下来的是Base64格式)
|
||||
let pacTxt = body
|
||||
try {
|
||||
if (pacTxt.indexOf('!---------------------EOF') < 0) {
|
||||
if (!pacTxt.includes('!---------------------EOF')) {
|
||||
pacTxt = Buffer.from(pacTxt, 'base64').toString('utf8')
|
||||
// log.debug('解析 base64 后的 pax:', pacTxt)
|
||||
}
|
||||
} catch (e) {
|
||||
if (pacTxt.indexOf('!---------------------EOF') < 0) {
|
||||
if (!pacTxt.includes('!---------------------EOF')) {
|
||||
log.error(`远程 pac.txt 文件内容即不是base64格式,也不是要求的格式,url: ${remotePacFileUrl},body: ${body}`)
|
||||
return
|
||||
}
|
||||
|
@ -181,7 +182,7 @@ function createOverwallMiddleware (overWallConfig) {
|
|||
context.requestCount = {
|
||||
key: cacheKey,
|
||||
value: count.value,
|
||||
count
|
||||
count,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,10 +191,10 @@ function createOverwallMiddleware (overWallConfig) {
|
|||
const port = server[domain].port
|
||||
const path = server[domain].path
|
||||
const password = server[domain].password
|
||||
const proxyTarget = domain + '/' + path + '/' + hostname + req.url
|
||||
const proxyTarget = `${domain}/${path}/${hostname}${req.url}`
|
||||
|
||||
// const backup = interceptOpt.backup
|
||||
const proxy = proxyTarget.indexOf('http:') === 0 || proxyTarget.indexOf('https:') === 0 ? proxyTarget : (rOptions.protocol + '//' + proxyTarget)
|
||||
const proxy = proxyTarget.indexOf('http:') === 0 || proxyTarget.indexOf('https:') === 0 ? proxyTarget : (`${rOptions.protocol}//${proxyTarget}`)
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
const URL = url.parse(proxy)
|
||||
rOptions.origional = lodash.cloneDeep(rOptions) // 备份原始请求参数
|
||||
|
@ -218,12 +219,12 @@ function createOverwallMiddleware (overWallConfig) {
|
|||
res.setHeader('DS-Overwall', matchedResult)
|
||||
|
||||
return true
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getTmpPacFilePath,
|
||||
downloadPacAsync,
|
||||
createOverwallMiddleware
|
||||
createOverwallMiddleware,
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ function createPacClient (pacFilePath) {
|
|||
|
||||
const getRules = function (pacFilePath) {
|
||||
let text = readFile(pacFilePath)
|
||||
if (text.indexOf('!---------------------EOF') < 0) {
|
||||
if (!text.includes('!---------------------EOF')) {
|
||||
text = Buffer.from(text, 'base64').toString()
|
||||
}
|
||||
const rules = []
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
const net = require('net')
|
||||
const url = require('url')
|
||||
const jsonApi = require('../../../json')
|
||||
const log = require('../../../utils/util.log')
|
||||
const DnsUtil = require('../../dns/index')
|
||||
const localIP = '127.0.0.1'
|
||||
const dnsLookup = require('./dnsLookup')
|
||||
const jsonApi = require('../../../json')
|
||||
|
||||
const localIP = '127.0.0.1'
|
||||
|
||||
function isSslConnect (sslConnectInterceptors, req, cltSocket, head) {
|
||||
for (const intercept of sslConnectInterceptors) {
|
||||
|
@ -32,7 +33,7 @@ module.exports = function createConnectHandler (sslConnectInterceptor, middlewar
|
|||
return function connectHandler (req, cltSocket, head, ssl) {
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
let { hostname, port } = url.parse(`${ssl ? 'https' : 'http'}://${req.url}`)
|
||||
port = parseInt(port)
|
||||
port = Number.parseInt(port)
|
||||
|
||||
if (isSslConnect(sslConnectInterceptors, req, cltSocket, head)) {
|
||||
// 需要拦截,代替目标服务器,让客户端连接DS在本地启动的代理服务
|
||||
|
@ -104,7 +105,7 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig = null, isDire
|
|||
const options = {
|
||||
port,
|
||||
host: hostname,
|
||||
connectTimeout: 10000
|
||||
connectTimeout: 10000,
|
||||
}
|
||||
if (dnsConfig && dnsConfig.dnsMap) {
|
||||
const dns = DnsUtil.hasDnsLookup(dnsConfig, hostname)
|
||||
|
@ -114,12 +115,15 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig = null, isDire
|
|||
}
|
||||
// 代理连接事件监听
|
||||
const proxySocket = net.connect(options, () => {
|
||||
if (!isDirect) log.info('Proxy connect start:', hostport)
|
||||
else log.debug('Direct connect start:', hostport)
|
||||
if (!isDirect) {
|
||||
log.info('Proxy connect start:', hostport)
|
||||
} else {
|
||||
log.debug('Direct connect start:', hostport)
|
||||
}
|
||||
|
||||
cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
|
||||
'Proxy-agent: dev-sidecar\r\n' +
|
||||
'\r\n')
|
||||
cltSocket.write('HTTP/1.1 200 Connection Established\r\n'
|
||||
+ 'Proxy-agent: dev-sidecar\r\n'
|
||||
+ '\r\n')
|
||||
proxySocket.write(head)
|
||||
proxySocket.pipe(cltSocket)
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
const fs = require('fs')
|
||||
const forge = require('node-forge')
|
||||
const FakeServersCenter = require('../tls/FakeServersCenter')
|
||||
const log = require('../../../utils/util.log')
|
||||
const FakeServersCenter = require('../tls/FakeServersCenter')
|
||||
|
||||
module.exports = function createFakeServerCenter ({
|
||||
maxLength,
|
||||
caCertPath,
|
||||
caKeyPath,
|
||||
requestHandler,
|
||||
upgradeHandler,
|
||||
getCertSocketTimeout
|
||||
getCertSocketTimeout,
|
||||
}) {
|
||||
let caCert
|
||||
let caKey
|
||||
|
@ -30,6 +31,6 @@ module.exports = function createFakeServerCenter ({
|
|||
maxLength,
|
||||
requestHandler,
|
||||
upgradeHandler,
|
||||
getCertSocketTimeout
|
||||
getCertSocketTimeout,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
const http = require('http')
|
||||
const https = require('https')
|
||||
const commonUtil = require('../common/util')
|
||||
const jsonApi = require('../../../json')
|
||||
// const upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i
|
||||
const DnsUtil = require('../../dns/index')
|
||||
const log = require('../../../utils/util.log')
|
||||
const RequestCounter = require('../../choice/RequestCounter')
|
||||
const commonUtil = require('../common/util')
|
||||
// const upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i
|
||||
const DnsUtil = require('../../dns/index')
|
||||
const compatible = require('../compatible/compatible')
|
||||
const InsertScriptMiddleware = require('../middleware/InsertScriptMiddleware')
|
||||
const dnsLookup = require('./dnsLookup')
|
||||
const compatible = require('../compatible/compatible')
|
||||
|
||||
const MAX_SLOW_TIME = 8000 // 超过此时间 则认为太慢了
|
||||
|
||||
// create requestHandler function
|
||||
|
@ -31,16 +32,16 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
rOptions,
|
||||
log,
|
||||
RequestCounter,
|
||||
setting
|
||||
setting,
|
||||
}
|
||||
let interceptors = createIntercepts(context)
|
||||
if (interceptors == null) {
|
||||
interceptors = []
|
||||
}
|
||||
const reqIncpts = interceptors.filter(item => {
|
||||
const reqIncpts = interceptors.filter((item) => {
|
||||
return item.requestIntercept != null
|
||||
})
|
||||
const resIncpts = interceptors.filter(item => {
|
||||
const resIncpts = interceptors.filter((item) => {
|
||||
return item.responseIntercept != null
|
||||
})
|
||||
|
||||
|
@ -63,7 +64,9 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
}
|
||||
const goNext = reqIncpt.requestIntercept(context, req, res, ssl, next)
|
||||
if (goNext) {
|
||||
if (goNext !== 'no-next') next()
|
||||
if (goNext !== 'no-next') {
|
||||
next()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +110,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
function onFree () {
|
||||
url = `${rOptions.method} ➜ ${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`
|
||||
const start = new Date()
|
||||
log.info('发起代理请求:', url, (rOptions.servername ? ', sni: ' + rOptions.servername : ''), ', headers:', jsonApi.stringify2(rOptions.headers))
|
||||
log.info('发起代理请求:', url, (rOptions.servername ? `, sni: ${rOptions.servername}` : ''), ', headers:', jsonApi.stringify2(rOptions.headers))
|
||||
|
||||
const isDnsIntercept = {}
|
||||
if (dnsConfig && dnsConfig.dnsMap) {
|
||||
|
@ -181,7 +184,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
proxyReq.on('error', (e) => {
|
||||
const cost = new Date() - start
|
||||
log.error(`代理请求错误: ${url}, cost: ${cost} ms, error:`, e, ', rOptions:', jsonApi.stringify2(rOptions))
|
||||
countSlow(isDnsIntercept, '代理请求错误: ' + e.message)
|
||||
countSlow(isDnsIntercept, `代理请求错误: ${e.message}`)
|
||||
reject(e)
|
||||
|
||||
// 自动兼容程序:2
|
||||
|
@ -205,7 +208,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
})
|
||||
|
||||
// 原始请求的事件监听
|
||||
req.on('aborted', function () {
|
||||
req.on('aborted', () => {
|
||||
const cost = new Date() - start
|
||||
const errorMsg = `请求被取消: ${url}, cost: ${cost} ms`
|
||||
log.error(errorMsg, ', rOptions:', jsonApi.stringify2(rOptions))
|
||||
|
@ -215,7 +218,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
}
|
||||
reject(new Error(errorMsg))
|
||||
})
|
||||
req.on('error', function (e, req, res) {
|
||||
req.on('error', (e, req, res) => {
|
||||
const cost = new Date() - start
|
||||
log.error(`请求错误: ${url}, cost: ${cost} ms, error:`, e, ', rOptions:', jsonApi.stringify2(rOptions))
|
||||
reject(e)
|
||||
|
@ -246,7 +249,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
// // console.log('BODY: ')
|
||||
// })
|
||||
proxyRes.on('error', (error) => {
|
||||
countSlow(null, 'error: ' + error.message)
|
||||
countSlow(null, `error: ${error.message}`)
|
||||
log.error(`proxy res error: ${url}, error:`, error)
|
||||
})
|
||||
|
||||
|
@ -287,7 +290,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
}
|
||||
InsertScriptMiddleware.responseInterceptor(req, res, proxyReq, proxyRes, ssl, next, {
|
||||
head,
|
||||
body
|
||||
body,
|
||||
})
|
||||
} else {
|
||||
next()
|
||||
|
@ -300,7 +303,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
await responseInterceptorPromise
|
||||
|
||||
if (!res.headersSent) { // prevent duplicate set headers
|
||||
Object.keys(proxyRes.headers).forEach(function (key) {
|
||||
Object.keys(proxyRes.headers).forEach((key) => {
|
||||
if (proxyRes.headers[key] !== undefined) {
|
||||
// https://github.com/nodejitsu/node-http-proxy/issues/362
|
||||
if (/^www-authenticate$/i.test(key)) {
|
||||
|
@ -314,19 +317,19 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
})
|
||||
|
||||
if (proxyRes.statusCode >= 400) {
|
||||
countSlow(null, 'Status return: ' + proxyRes.statusCode)
|
||||
countSlow(null, `Status return: ${proxyRes.statusCode}`)
|
||||
}
|
||||
res.writeHead(proxyRes.statusCode)
|
||||
proxyRes.pipe(res)
|
||||
}
|
||||
})().catch(e => {
|
||||
})().catch((e) => {
|
||||
if (!res.writableEnded) {
|
||||
try {
|
||||
const status = e.status || 500
|
||||
res.writeHead(status, { 'Content-Type': 'text/html;charset=UTF8' })
|
||||
res.write(`DevSidecar Error:<br/>
|
||||
目标网站请求错误:【${e.code}】 ${e.message}<br/>
|
||||
目标地址:${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`
|
||||
目标地址:${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`,
|
||||
)
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
|
@ -343,7 +346,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
const ignoreErrors = [
|
||||
'代理请求错误: ',
|
||||
'代理请求超时: ',
|
||||
'代理请求被取消: '
|
||||
'代理请求被取消: ',
|
||||
]
|
||||
for (const ignoreError of ignoreErrors) {
|
||||
if (e.message.startsWith(ignoreError)) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
const http = require('http')
|
||||
const https = require('https')
|
||||
const util = require('../common/util')
|
||||
const log = require('../../../utils/util.log')
|
||||
const util = require('../common/util')
|
||||
|
||||
// copy from node-http-proxy. ^_^
|
||||
|
||||
// create connectHandler function
|
||||
|
@ -13,17 +14,19 @@ module.exports = function createUpgradeHandler (serverSetting) {
|
|||
proxyReq.on('error', (e) => {
|
||||
log.error('upgradeHandler error:', e)
|
||||
})
|
||||
proxyReq.on('response', function (res) {
|
||||
proxyReq.on('response', (res) => {
|
||||
// if upgrade event isn't going to happen, close the socket
|
||||
if (!res.upgrade) cltSocket.end()
|
||||
if (!res.upgrade) {
|
||||
cltSocket.end()
|
||||
}
|
||||
})
|
||||
|
||||
proxyReq.on('upgrade', function (proxyRes, proxySocket, proxyHead) {
|
||||
proxyReq.on('upgrade', (proxyRes, proxySocket, proxyHead) => {
|
||||
proxySocket.on('error', (e) => {
|
||||
log.error('upgrade error:', e)
|
||||
})
|
||||
|
||||
cltSocket.on('error', function (e) {
|
||||
cltSocket.on('error', (e) => {
|
||||
log.error('upgrade socket error:', e)
|
||||
proxySocket.end()
|
||||
})
|
||||
|
@ -33,23 +36,24 @@ module.exports = function createUpgradeHandler (serverSetting) {
|
|||
|
||||
proxySocket.setKeepAlive(true, 0)
|
||||
|
||||
if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead)
|
||||
if (proxyHead && proxyHead.length) {
|
||||
proxySocket.unshift(proxyHead)
|
||||
}
|
||||
|
||||
cltSocket.write(
|
||||
Object.keys(proxyRes.headers).reduce(function (head, key) {
|
||||
`${Object.keys(proxyRes.headers).reduce((head, key) => {
|
||||
const value = proxyRes.headers[key]
|
||||
|
||||
if (!Array.isArray(value)) {
|
||||
head.push(key + ': ' + value)
|
||||
head.push(`${key}: ${value}`)
|
||||
return head
|
||||
}
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
head.push(key + ': ' + value[i])
|
||||
head.push(`${key}: ${value[i]}`)
|
||||
}
|
||||
return head
|
||||
}, ['HTTP/1.1 101 Switching Protocols'])
|
||||
.join('\r\n') + '\r\n\r\n'
|
||||
}, ['HTTP/1.1 101 Switching Protocols']).join('\r\n')}\r\n\r\n`,
|
||||
)
|
||||
|
||||
proxySocket.pipe(cltSocket).pipe(proxySocket)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const speedTest = require('../../speed')
|
||||
const log = require('../../../utils/util.log')
|
||||
const defaultDns = require('dns')
|
||||
const log = require('../../../utils/util.log')
|
||||
const speedTest = require('../../speed')
|
||||
|
||||
module.exports = {
|
||||
createLookupFunc: function (res, dns, action, target, isDnsIntercept) {
|
||||
target = target ? (', target: ' + target) : ''
|
||||
createLookupFunc (res, dns, action, target, isDnsIntercept) {
|
||||
target = target ? (`, target: ${target}`) : ''
|
||||
|
||||
return (hostname, options, callback) => {
|
||||
const tester = speedTest.getSpeedTester(hostname)
|
||||
|
@ -12,14 +12,16 @@ module.exports = {
|
|||
const aliveIpObj = tester.pickFastAliveIpObj()
|
||||
if (aliveIpObj) {
|
||||
log.info(`----- ${action}: ${hostname}, use alive ip from dns '${aliveIpObj.dns}': ${aliveIpObj.host}${target} -----`)
|
||||
if (res) res.setHeader('DS-DNS-Lookup', `IpTester: ${aliveIpObj.host} ${aliveIpObj.dns === '预设IP' ? 'PreSet' : aliveIpObj.dns}`)
|
||||
if (res) {
|
||||
res.setHeader('DS-DNS-Lookup', `IpTester: ${aliveIpObj.host} ${aliveIpObj.dns === '预设IP' ? 'PreSet' : aliveIpObj.dns}`)
|
||||
}
|
||||
callback(null, aliveIpObj.host, 4)
|
||||
return
|
||||
} else {
|
||||
log.info(`----- ${action}: ${hostname}, no alive ip${target}, tester: { "ready": ${tester.ready}, "backupList": ${JSON.stringify(tester.backupList)} }`)
|
||||
}
|
||||
}
|
||||
dns.lookup(hostname).then(ip => {
|
||||
dns.lookup(hostname).then((ip) => {
|
||||
if (isDnsIntercept) {
|
||||
isDnsIntercept.dns = dns
|
||||
isDnsIntercept.hostname = hostname
|
||||
|
@ -42,7 +44,9 @@ module.exports = {
|
|||
}
|
||||
if (isTestFailedIp === false) {
|
||||
log.info(`----- ${action}: ${hostname}, use ip from dns '${dns.name}': ${ip}${target} -----`)
|
||||
if (res) res.setHeader('DS-DNS-Lookup', `DNS: ${ip} ${dns.name === '预设IP' ? 'PreSet' : dns.name}`)
|
||||
if (res) {
|
||||
res.setHeader('DS-DNS-Lookup', `DNS: ${ip} ${dns.name === '预设IP' ? 'PreSet' : dns.name}`)
|
||||
}
|
||||
callback(null, ip, 4)
|
||||
return
|
||||
} else {
|
||||
|
@ -56,5 +60,5 @@ module.exports = {
|
|||
defaultDns.lookup(hostname, options, callback)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
const tlsUtils = require('../tls/tlsUtils')
|
||||
const http = require('http')
|
||||
const config = require('../common/config')
|
||||
const log = require('../../../utils/util.log')
|
||||
const createRequestHandler = require('./createRequestHandler')
|
||||
const speedTest = require('../../speed/index.js')
|
||||
const config = require('../common/config')
|
||||
const tlsUtils = require('../tls/tlsUtils')
|
||||
const createConnectHandler = require('./createConnectHandler')
|
||||
const createFakeServerCenter = require('./createFakeServerCenter')
|
||||
const createRequestHandler = require('./createRequestHandler')
|
||||
const createUpgradeHandler = require('./createUpgradeHandler')
|
||||
const speedTest = require('../../speed/index.js')
|
||||
|
||||
module.exports = {
|
||||
createProxy ({
|
||||
host = config.defaultHost,
|
||||
|
@ -21,7 +22,7 @@ module.exports = {
|
|||
externalProxy,
|
||||
dnsConfig,
|
||||
setting,
|
||||
compatibleConfig
|
||||
compatibleConfig,
|
||||
}, callback) {
|
||||
// Don't reject unauthorized
|
||||
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
||||
|
@ -59,7 +60,7 @@ module.exports = {
|
|||
externalProxy,
|
||||
dnsConfig,
|
||||
setting,
|
||||
compatibleConfig
|
||||
compatibleConfig,
|
||||
)
|
||||
|
||||
const upgradeHandler = createUpgradeHandler(setting)
|
||||
|
@ -70,7 +71,7 @@ module.exports = {
|
|||
caKeyPath,
|
||||
requestHandler,
|
||||
upgradeHandler,
|
||||
getCertSocketTimeout
|
||||
getCertSocketTimeout,
|
||||
})
|
||||
|
||||
const connectHandler = createConnectHandler(
|
||||
|
@ -78,7 +79,7 @@ module.exports = {
|
|||
middlewares,
|
||||
fakeServersCenter,
|
||||
dnsConfig,
|
||||
compatibleConfig
|
||||
compatibleConfig,
|
||||
)
|
||||
|
||||
// 创建监听方法,用于监听 http 和 https 两个端口
|
||||
|
@ -87,16 +88,20 @@ module.exports = {
|
|||
server.listen(port, host, () => {
|
||||
log.info(`dev-sidecar启动 ${ssl ? 'https' : 'http'} 端口: ${host}:${port}`)
|
||||
server.on('request', (req, res) => {
|
||||
if (printDebugLog) log.debug(`【server request, ssl: ${ssl}】\r\n----- req -----\r\n`, req, '\r\n----- res -----\r\n', res)
|
||||
if (printDebugLog) {
|
||||
log.debug(`【server request, ssl: ${ssl}】\r\n----- req -----\r\n`, req, '\r\n----- res -----\r\n', res)
|
||||
}
|
||||
requestHandler(req, res, ssl)
|
||||
})
|
||||
// tunneling for https
|
||||
server.on('connect', (req, cltSocket, head) => {
|
||||
if (printDebugLog) log.debug(`【server connect, ssl: ${ssl}】\r\n----- req -----\r\n`, req, '\r\n----- cltSocket -----\r\n', cltSocket, '\r\n----- head -----\r\n', head)
|
||||
if (printDebugLog) {
|
||||
log.debug(`【server connect, ssl: ${ssl}】\r\n----- req -----\r\n`, req, '\r\n----- cltSocket -----\r\n', cltSocket, '\r\n----- head -----\r\n', head)
|
||||
}
|
||||
connectHandler(req, cltSocket, head, ssl)
|
||||
})
|
||||
// TODO: handler WebSocket
|
||||
server.on('upgrade', function (req, cltSocket, head) {
|
||||
server.on('upgrade', (req, cltSocket, head) => {
|
||||
if (printDebugLog) {
|
||||
log.debug(`【server upgrade, ssl: ${ssl}】\r\n----- req -----\r\n`, req)
|
||||
} else {
|
||||
|
@ -154,5 +159,5 @@ module.exports = {
|
|||
},
|
||||
createCA (caPaths) {
|
||||
return tlsUtils.initCA(caPaths)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ module.exports = class CertAndKeyContainer {
|
|||
maxLength = 1000,
|
||||
getCertSocketTimeout = 2 * 1000,
|
||||
caCert,
|
||||
caKey
|
||||
caKey,
|
||||
}) {
|
||||
this.queue = []
|
||||
this.maxLength = maxLength
|
||||
|
@ -50,7 +50,7 @@ module.exports = class CertAndKeyContainer {
|
|||
|
||||
const certPromiseObj = {
|
||||
port,
|
||||
mappingHostNames: [hostname] // temporary hostname
|
||||
mappingHostNames: [hostname], // temporary hostname
|
||||
}
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
const https = require('https')
|
||||
const http = require('http')
|
||||
const tlsUtils = require('./tlsUtils')
|
||||
const CertAndKeyContainer = require('./CertAndKeyContainer')
|
||||
const https = require('https')
|
||||
const forge = require('node-forge')
|
||||
const CertAndKeyContainer = require('./CertAndKeyContainer')
|
||||
const tlsUtils = require('./tlsUtils')
|
||||
|
||||
const pki = forge.pki
|
||||
// const colors = require('colors')
|
||||
const tls = require('tls')
|
||||
|
@ -27,7 +28,7 @@ module.exports = class FakeServersCenter {
|
|||
this.certAndKeyContainer = new CertAndKeyContainer({
|
||||
getCertSocketTimeout,
|
||||
caCert,
|
||||
caKey
|
||||
caKey,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -76,7 +77,7 @@ module.exports = class FakeServersCenter {
|
|||
const serverPromiseObj = {
|
||||
port,
|
||||
ssl,
|
||||
mappingHostNames: [hostname] // temporary hostname
|
||||
mappingHostNames: [hostname], // temporary hostname
|
||||
}
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
|
@ -99,10 +100,10 @@ module.exports = class FakeServersCenter {
|
|||
log.info(`fakeServer SNICallback: ${hostname}:${port}`)
|
||||
done(null, tls.createSecureContext({
|
||||
key: pki.privateKeyToPem(certObj.key),
|
||||
cert: pki.certificateToPem(certObj.cert)
|
||||
cert: pki.certificateToPem(certObj.cert),
|
||||
}))
|
||||
})()
|
||||
}
|
||||
},
|
||||
})
|
||||
} else {
|
||||
fakeServer = new http.Server()
|
||||
|
@ -111,7 +112,7 @@ module.exports = class FakeServersCenter {
|
|||
cert,
|
||||
key,
|
||||
server: fakeServer,
|
||||
port: 0 // if port === 0 ,should listen server's `listening` event.
|
||||
port: 0, // if port === 0 ,should listen server's `listening` event.
|
||||
}
|
||||
serverPromiseObj.serverObj = serverObj
|
||||
|
||||
|
@ -121,12 +122,16 @@ module.exports = class FakeServersCenter {
|
|||
serverObj.port = address.port
|
||||
})
|
||||
fakeServer.on('request', (req, res) => {
|
||||
if (printDebugLog) log.debug(`【fakeServer request - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- res -----\r\n', res)
|
||||
if (printDebugLog) {
|
||||
log.debug(`【fakeServer request - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- res -----\r\n', res)
|
||||
}
|
||||
this.requestHandler(req, res, ssl)
|
||||
})
|
||||
let once = true
|
||||
fakeServer.on('listening', () => {
|
||||
if (printDebugLog) log.debug(`【fakeServer listening - ${hostname}:${port}】no arguments...`)
|
||||
if (printDebugLog) {
|
||||
log.debug(`【fakeServer listening - ${hostname}:${port}】no arguments...`)
|
||||
}
|
||||
if (cert && once) {
|
||||
once = false
|
||||
let newMappingHostNames = tlsUtils.getMappingHostNamesFromCert(cert)
|
||||
|
|
|
@ -69,28 +69,38 @@ module.exports = function extractSNI (data) {
|
|||
pos += 32
|
||||
|
||||
// skip SessionID
|
||||
if (pos > end - 1) return null
|
||||
if (pos > end - 1) {
|
||||
return null
|
||||
}
|
||||
const sessionIdLength = data[pos]
|
||||
pos += 1 + sessionIdLength
|
||||
|
||||
// skip CipherSuite
|
||||
if (pos > end - 2) return null
|
||||
if (pos > end - 2) {
|
||||
return null
|
||||
}
|
||||
const cipherSuiteLength = data[pos] << 8 | data[pos + 1]
|
||||
pos += 2 + cipherSuiteLength
|
||||
|
||||
// skip CompressionMethod
|
||||
if (pos > end - 1) return null
|
||||
if (pos > end - 1) {
|
||||
return null
|
||||
}
|
||||
const compressionMethodLength = data[pos]
|
||||
pos += 1 + compressionMethodLength
|
||||
|
||||
// verify extensions exist
|
||||
if (pos > end - 2) return null
|
||||
if (pos > end - 2) {
|
||||
return null
|
||||
}
|
||||
const extensionsLength = data[pos] << 8 | data[pos + 1]
|
||||
pos += 2
|
||||
|
||||
// verify the extensions fit
|
||||
const extensionsEnd = pos + extensionsLength
|
||||
if (extensionsEnd > end) return null
|
||||
if (extensionsEnd > end) {
|
||||
return null
|
||||
}
|
||||
end = extensionsEnd
|
||||
|
||||
/*
|
||||
|
@ -129,14 +139,18 @@ module.exports = function extractSNI (data) {
|
|||
pos += 4
|
||||
if (extensionType === 0) { // ExtensionType was server_name(0)
|
||||
// read ServerNameList length
|
||||
if (pos > end - 2) return null
|
||||
if (pos > end - 2) {
|
||||
return null
|
||||
}
|
||||
const nameListLength = data[pos] << 8 | data[pos + 1]
|
||||
pos += 2
|
||||
|
||||
// verify we have enough bytes and loop over SeverNameList
|
||||
let n = pos
|
||||
pos += nameListLength
|
||||
if (pos > end) return null
|
||||
if (pos > end) {
|
||||
return null
|
||||
}
|
||||
while (n < pos - 3) {
|
||||
const nameType = data[n]
|
||||
const nameLength = data[n + 1] << 8 | data[n + 2]
|
||||
|
@ -145,7 +159,9 @@ module.exports = function extractSNI (data) {
|
|||
// check if NameType is host_name(0)
|
||||
if (nameType === 0) {
|
||||
// verify we have enough bytes
|
||||
if (n > end - nameLength) return null
|
||||
if (n > end - nameLength) {
|
||||
return null
|
||||
}
|
||||
|
||||
// decode as ascii and return
|
||||
|
||||
|
@ -154,7 +170,7 @@ module.exports = function extractSNI (data) {
|
|||
sniName,
|
||||
start: n,
|
||||
end: n + nameLength,
|
||||
length: nameLength
|
||||
length: nameLength,
|
||||
}
|
||||
} else {
|
||||
n += nameLength
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const forge = require('node-forge')
|
||||
const fs = require('fs')
|
||||
const log = require('../../../utils/util.log')
|
||||
const path = require('path')
|
||||
const config = require('../common/config')
|
||||
const _ = require('lodash')
|
||||
const mkdirp = require('mkdirp')
|
||||
const forge = require('node-forge')
|
||||
const log = require('../../../utils/util.log')
|
||||
const config = require('../common/config')
|
||||
// const colors = require('colors')
|
||||
|
||||
const utils = exports
|
||||
|
@ -23,43 +23,41 @@ utils.createCA = function (CN) {
|
|||
const keys = pki.rsa.generateKeyPair(2048)
|
||||
const cert = pki.createCertificate()
|
||||
cert.publicKey = keys.publicKey
|
||||
cert.serialNumber = (new Date()).getTime() + ''
|
||||
cert.serialNumber = `${(new Date()).getTime()}`
|
||||
cert.validity.notBefore = new Date(new Date() - (60 * 60 * 1000))
|
||||
cert.validity.notAfter = new Date()
|
||||
cert.validity.notAfter.setFullYear(cert.validity.notAfter.getFullYear() + 20)
|
||||
const attrs = [{
|
||||
name: 'commonName',
|
||||
value: CN
|
||||
value: CN,
|
||||
}, {
|
||||
name: 'countryName',
|
||||
value: 'CN'
|
||||
value: 'CN',
|
||||
}, {
|
||||
shortName: 'ST',
|
||||
value: 'GuangDong'
|
||||
value: 'GuangDong',
|
||||
}, {
|
||||
name: 'localityName',
|
||||
value: 'ShenZhen'
|
||||
value: 'ShenZhen',
|
||||
}, {
|
||||
name: 'organizationName',
|
||||
value: 'dev-sidecar'
|
||||
value: 'dev-sidecar',
|
||||
}, {
|
||||
shortName: 'OU',
|
||||
value: 'https://github.com/docmirror/dev-sidecar'
|
||||
value: 'https://github.com/docmirror/dev-sidecar',
|
||||
}]
|
||||
cert.setSubject(attrs)
|
||||
cert.setIssuer(attrs)
|
||||
cert.setExtensions([{
|
||||
name: 'basicConstraints',
|
||||
critical: true,
|
||||
cA: true
|
||||
},
|
||||
{
|
||||
cA: true,
|
||||
}, {
|
||||
name: 'keyUsage',
|
||||
critical: true,
|
||||
keyCertSign: true
|
||||
},
|
||||
{
|
||||
name: 'subjectKeyIdentifier'
|
||||
keyCertSign: true,
|
||||
}, {
|
||||
name: 'subjectKeyIdentifier',
|
||||
}])
|
||||
|
||||
// self-sign certificate
|
||||
|
@ -67,7 +65,7 @@ utils.createCA = function (CN) {
|
|||
|
||||
return {
|
||||
key: keys.privateKey,
|
||||
cert: cert
|
||||
cert,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,29 +79,29 @@ utils.createFakeCertificateByDomain = function (caKey, caCert, domain) {
|
|||
const cert = pki.createCertificate()
|
||||
cert.publicKey = keys.publicKey
|
||||
|
||||
cert.serialNumber = (new Date()).getTime() + ''
|
||||
cert.serialNumber = `${(new Date()).getTime()}`
|
||||
cert.validity.notBefore = new Date()
|
||||
cert.validity.notBefore.setFullYear(cert.validity.notBefore.getFullYear() - 1)
|
||||
cert.validity.notAfter = new Date()
|
||||
cert.validity.notAfter.setFullYear(cert.validity.notAfter.getFullYear() + 1)
|
||||
const attrs = [{
|
||||
name: 'commonName',
|
||||
value: domain
|
||||
value: domain,
|
||||
}, {
|
||||
name: 'countryName',
|
||||
value: 'CN'
|
||||
value: 'CN',
|
||||
}, {
|
||||
shortName: 'ST',
|
||||
value: 'GuangDong'
|
||||
value: 'GuangDong',
|
||||
}, {
|
||||
name: 'localityName',
|
||||
value: 'ShenZhen'
|
||||
value: 'ShenZhen',
|
||||
}, {
|
||||
name: 'organizationName',
|
||||
value: 'dev-sidecar'
|
||||
value: 'dev-sidecar',
|
||||
}, {
|
||||
shortName: 'OU',
|
||||
value: 'https://github.com/docmirror/dev-sidecar'
|
||||
value: 'https://github.com/docmirror/dev-sidecar',
|
||||
}]
|
||||
|
||||
cert.setIssuer(caCert.subject.attributes)
|
||||
|
@ -112,7 +110,7 @@ utils.createFakeCertificateByDomain = function (caKey, caCert, domain) {
|
|||
cert.setExtensions([{
|
||||
name: 'basicConstraints',
|
||||
critical: true,
|
||||
cA: false
|
||||
cA: false,
|
||||
},
|
||||
// {
|
||||
// name: 'keyUsage',
|
||||
|
@ -131,28 +129,25 @@ utils.createFakeCertificateByDomain = function (caKey, caCert, domain) {
|
|||
name: 'subjectAltName',
|
||||
altNames: [{
|
||||
type: 2,
|
||||
value: domain
|
||||
}]
|
||||
},
|
||||
{
|
||||
name: 'subjectKeyIdentifier'
|
||||
},
|
||||
{
|
||||
value: domain,
|
||||
}],
|
||||
}, {
|
||||
name: 'subjectKeyIdentifier',
|
||||
}, {
|
||||
name: 'extKeyUsage',
|
||||
serverAuth: true,
|
||||
clientAuth: true,
|
||||
codeSigning: true,
|
||||
emailProtection: true,
|
||||
timeStamping: true
|
||||
},
|
||||
{
|
||||
name: 'authorityKeyIdentifier'
|
||||
timeStamping: true,
|
||||
}, {
|
||||
name: 'authorityKeyIdentifier',
|
||||
}])
|
||||
cert.sign(caKey, forge.md.sha256.create())
|
||||
|
||||
return {
|
||||
key: keys.privateKey,
|
||||
cert: cert
|
||||
cert,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,9 +173,8 @@ utils.createFakeCertificateByCA = function (caKey, caCert, originCertificate) {
|
|||
cert.setExtensions([{
|
||||
name: 'basicConstraints',
|
||||
critical: true,
|
||||
cA: false
|
||||
},
|
||||
{
|
||||
cA: false,
|
||||
}, {
|
||||
name: 'keyUsage',
|
||||
critical: true,
|
||||
digitalSignature: true,
|
||||
|
@ -191,31 +185,27 @@ utils.createFakeCertificateByCA = function (caKey, caCert, originCertificate) {
|
|||
keyCertSign: true,
|
||||
cRLSign: true,
|
||||
encipherOnly: true,
|
||||
decipherOnly: true
|
||||
},
|
||||
{
|
||||
decipherOnly: true,
|
||||
}, {
|
||||
name: 'subjectAltName',
|
||||
altNames: subjectAltName.altNames
|
||||
},
|
||||
{
|
||||
name: 'subjectKeyIdentifier'
|
||||
},
|
||||
{
|
||||
altNames: subjectAltName.altNames,
|
||||
}, {
|
||||
name: 'subjectKeyIdentifier',
|
||||
}, {
|
||||
name: 'extKeyUsage',
|
||||
serverAuth: true,
|
||||
clientAuth: true,
|
||||
codeSigning: true,
|
||||
emailProtection: true,
|
||||
timeStamping: true
|
||||
},
|
||||
{
|
||||
name: 'authorityKeyIdentifier'
|
||||
timeStamping: true,
|
||||
}, {
|
||||
name: 'authorityKeyIdentifier',
|
||||
}])
|
||||
cert.sign(caKey, forge.md.sha256.create())
|
||||
|
||||
return {
|
||||
key: keys.privateKey,
|
||||
cert: cert
|
||||
cert,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,7 +221,7 @@ utils.isMappingHostName = function (DNSName, hostname) {
|
|||
}
|
||||
|
||||
let reg = DNSName.replace(/\./g, '\\.').replace(/\*/g, '[^.]+')
|
||||
reg = '^' + reg + '$'
|
||||
reg = `^${reg}$`
|
||||
return (new RegExp(reg)).test(hostname)
|
||||
}
|
||||
|
||||
|
@ -253,7 +243,7 @@ utils.initCA = function ({ caCertPath, caKeyPath }) {
|
|||
return {
|
||||
caCertPath,
|
||||
caKeyPath,
|
||||
create: false
|
||||
create: false,
|
||||
}
|
||||
} catch (e) {
|
||||
const caObj = utils.createCA(config.caName)
|
||||
|
@ -272,6 +262,6 @@ utils.initCA = function ({ caCertPath, caKeyPath }) {
|
|||
return {
|
||||
caCertPath,
|
||||
caKeyPath,
|
||||
create: true
|
||||
create: true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// 1个小时不访问,取消获取
|
||||
const _ = require('lodash')
|
||||
const net = require('net')
|
||||
const config = require('./config.js')
|
||||
const _ = require('lodash')
|
||||
const log = require('../../utils/util.log.js')
|
||||
const config = require('./config.js')
|
||||
|
||||
const DISABLE_TIMEOUT = 60 * 60 * 1000
|
||||
class SpeedTester {
|
||||
constructor ({ hostname }) {
|
||||
|
@ -60,7 +61,7 @@ class SpeedTester {
|
|||
const promiseList = []
|
||||
for (const dnsKey in dnsMap) {
|
||||
const dns = dnsMap[dnsKey]
|
||||
const one = this.getFromOneDns(dns).then(ipList => {
|
||||
const one = this.getFromOneDns(dns).then((ipList) => {
|
||||
if (ipList) {
|
||||
for (const ip of ipList) {
|
||||
ips[ip] = { dns: ipList.isPreSet === true ? '预设IP' : dnsKey }
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const config = {
|
||||
notify () {},
|
||||
dnsMap: {}
|
||||
dnsMap: {},
|
||||
}
|
||||
module.exports = {
|
||||
getConfig () {
|
||||
return config
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
const SpeedTester = require('./SpeedTester.js')
|
||||
const _ = require('lodash')
|
||||
const config = require('./config')
|
||||
const log = require('../../utils/util.log.js')
|
||||
const SpeedTestPool = {
|
||||
const config = require('./config')
|
||||
const SpeedTester = require('./SpeedTester.js')
|
||||
|
||||
const SpeedTestPool = {
|
||||
}
|
||||
|
||||
function initSpeedTest (runtimeConfig) {
|
||||
const { enabled, hostnameList } = runtimeConfig
|
||||
const conf = config.getConfig()
|
||||
|
@ -27,7 +28,7 @@ function getAllSpeedTester () {
|
|||
allSpeed[key] = {
|
||||
hostname: key,
|
||||
alive: item.alive,
|
||||
backupList: item.backupList
|
||||
backupList: item.backupList,
|
||||
}
|
||||
})
|
||||
return allSpeed
|
||||
|
@ -70,5 +71,5 @@ module.exports = {
|
|||
getAllSpeedTester,
|
||||
registerNotify,
|
||||
reSpeedTest,
|
||||
action
|
||||
action,
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
const interceptorImpls = require('./lib/interceptor')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const lodash = require('lodash')
|
||||
const jsonApi = require('./json')
|
||||
const dnsUtil = require('./lib/dns')
|
||||
const interceptorImpls = require('./lib/interceptor')
|
||||
const scriptInterceptor = require('./lib/interceptor/impl/res/script')
|
||||
const { getTmpPacFilePath, downloadPacAsync, createOverwallMiddleware } = require('./lib/proxy/middleware/overwall')
|
||||
const log = require('./utils/util.log')
|
||||
const matchUtil = require('./utils/util.match')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const lodash = require('lodash')
|
||||
const scriptInterceptor = require('./lib/interceptor/impl/res/script')
|
||||
const jsonApi = require('./json')
|
||||
|
||||
const { getTmpPacFilePath, downloadPacAsync, createOverwallMiddleware } = require('./lib/proxy/middleware/overwall')
|
||||
|
||||
// 处理拦截配置
|
||||
function buildIntercepts (intercepts) {
|
||||
|
@ -97,12 +96,12 @@ module.exports = (serverConfig) => {
|
|||
preSetIpList,
|
||||
dnsMap: dnsUtil.initDNS(serverConfig.dns.providers, preSetIpList),
|
||||
mapping: matchUtil.domainMapRegexply(dnsMapping),
|
||||
speedTest: serverConfig.dns.speedTest
|
||||
speedTest: serverConfig.dns.speedTest,
|
||||
},
|
||||
setting,
|
||||
compatibleConfig: {
|
||||
connect: serverConfig.compatible ? matchUtil.domainMapRegexply(serverConfig.compatible.connect) : {},
|
||||
request: serverConfig.compatible ? matchUtil.domainMapRegexply(serverConfig.compatible.request) : {}
|
||||
request: serverConfig.compatible ? matchUtil.domainMapRegexply(serverConfig.compatible.request) : {},
|
||||
},
|
||||
middlewares,
|
||||
sslConnectInterceptor: (req, cltSocket, head) => {
|
||||
|
@ -205,7 +204,7 @@ module.exports = (serverConfig) => {
|
|||
}
|
||||
matchInterceptsOpts[impl.name] = {
|
||||
order: interceptOpt.order || 0,
|
||||
index: matchIntercepts.length - 1
|
||||
index: matchIntercepts.length - 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +216,7 @@ module.exports = (serverConfig) => {
|
|||
// }
|
||||
|
||||
return matchIntercepts
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if (setting.rootCaFile) {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// const os = require('os')
|
||||
const log = require('util.log')
|
||||
|
||||
const util = {
|
||||
getNodeVersion () {
|
||||
const version = process.version
|
||||
log.info(version)
|
||||
}
|
||||
},
|
||||
}
|
||||
util.getNodeVersion()
|
||||
module.exports = util
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
const path = require('path')
|
||||
const log4js = require('log4js')
|
||||
const proxyConfig = require('../lib/proxy/common/config')
|
||||
|
||||
const level = process.env.NODE_ENV === 'development' ? 'debug' : 'info'
|
||||
const path = require('path')
|
||||
|
||||
const filename = path.join(proxyConfig.getDefaultCABasePath(), '/logs/server.log')
|
||||
log4js.configure({
|
||||
appenders: { std: { type: 'stdout', level: 'debug' }, file: { level: 'debug', type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename } },
|
||||
categories: { default: { appenders: ['file', 'std'], level } }
|
||||
categories: { default: { appenders: ['file', 'std'], level } },
|
||||
})
|
||||
const logger = log4js.getLogger('server')
|
||||
module.exports = logger
|
||||
|
|
|
@ -9,7 +9,7 @@ function isMatched (url, regexp) {
|
|||
try {
|
||||
let urlRegexp = regexp
|
||||
if (regexp[0] === '*' || regexp[0] === '?' || regexp[0] === '+') {
|
||||
urlRegexp = '.' + regexp
|
||||
urlRegexp = `.${regexp}`
|
||||
}
|
||||
return url.match(urlRegexp)
|
||||
} catch (e) {
|
||||
|
@ -22,7 +22,7 @@ function domainRegexply (target) {
|
|||
if (target === '.*' || target === '*' || target === 'true' || target === true) {
|
||||
return '^.*$'
|
||||
}
|
||||
return '^' + target.replace(/\./g, '\\.').replace(/\*/g, '.*') + '$'
|
||||
return `^${target.replace(/\./g, '\\.').replace(/\*/g, '.*')}$`
|
||||
}
|
||||
|
||||
function domainMapRegexply (hostMap) {
|
||||
|
@ -32,7 +32,7 @@ function domainMapRegexply (hostMap) {
|
|||
const regexpMap = {}
|
||||
const origin = {} // 用于快速匹配,见matchHostname、matchHostnameAll方法
|
||||
lodash.each(hostMap, (value, domain) => {
|
||||
if (domain.indexOf('*') >= 0 || domain[0] === '^') {
|
||||
if (domain.includes('*') || domain[0] === '^') {
|
||||
const regDomain = domain[0] !== '^' ? domainRegexply(domain) : domain
|
||||
regexpMap[regDomain] = value
|
||||
|
||||
|
@ -65,12 +65,12 @@ function matchHostname (hostMap, hostname, action) {
|
|||
log.info(`matchHostname: ${action}: '${hostname}' -> { "${hostname}": ${JSON.stringify(value)} }`)
|
||||
return value // 快速匹配成功
|
||||
}
|
||||
value = hostMap.origin['*' + hostname]
|
||||
value = hostMap.origin[`*${hostname}`]
|
||||
if (value != null) {
|
||||
log.info(`matchHostname: ${action}: '${hostname}' -> { "*${hostname}": ${JSON.stringify(value)} }`)
|
||||
return value // 快速匹配成功
|
||||
}
|
||||
value = hostMap.origin['*.' + hostname]
|
||||
value = hostMap.origin[`*.${hostname}`]
|
||||
if (value != null) {
|
||||
log.info(`matchHostname: ${action}: '${hostname}' -> { "*.${hostname}": ${JSON.stringify(value)} }`)
|
||||
return value // 快速匹配成功
|
||||
|
@ -94,7 +94,7 @@ function matchHostname (hostMap, hostname, action) {
|
|||
}
|
||||
|
||||
function merge (oldObj, newObj) {
|
||||
return lodash.mergeWith(oldObj, newObj, function (objValue, srcValue) {
|
||||
return lodash.mergeWith(oldObj, newObj, (objValue, srcValue) => {
|
||||
if (lodash.isArray(objValue)) {
|
||||
return srcValue
|
||||
}
|
||||
|
@ -146,13 +146,13 @@ function matchHostnameAll (hostMap, hostname, action) {
|
|||
|
||||
// 域名快速匹配:直接匹配 或者 两种前缀通配符匹配
|
||||
// 优先级:2
|
||||
value = hostMap.origin['*' + hostname]
|
||||
value = hostMap.origin[`*${hostname}`]
|
||||
if (value) {
|
||||
log.debug(`matchHostname-one: ${action}: '${hostname}' -> { "*${hostname}": ${JSON.stringify(value)} }`)
|
||||
values = merge(values, value)
|
||||
}
|
||||
// 优先级:3
|
||||
value = hostMap.origin['*.' + hostname]
|
||||
value = hostMap.origin[`*.${hostname}`]
|
||||
if (value) {
|
||||
log.debug(`matchHostname-one: ${action}: '${hostname}' -> { "*.${hostname}": ${JSON.stringify(value)} }`)
|
||||
values = merge(values, value)
|
||||
|
@ -178,5 +178,5 @@ module.exports = {
|
|||
domainRegexply,
|
||||
domainMapRegexply,
|
||||
matchHostname,
|
||||
matchHostnameAll
|
||||
matchHostnameAll,
|
||||
}
|
||||
|
|
|
@ -8,5 +8,5 @@ module.exports = {
|
|||
if (process.send) {
|
||||
process.send({ type: 'status', event: status })
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ options.paragraph = 'false'
|
|||
options.probability = 'false'
|
||||
|
||||
// 调用通用文字识别(高精度版)(异步)
|
||||
client.accurateBasic(imageBase64, options).then(function (result) {
|
||||
client.accurateBasic(imageBase64, options).then((result) => {
|
||||
console.log(JSON.stringify(result))
|
||||
}).catch(function (err) {
|
||||
}).catch((err) => {
|
||||
// 如果发生网络错误
|
||||
console.log(err)
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const SpeedTester = require('../src/lib/speed/SpeedTester.js')
|
||||
const SpeedTest = require('../src/lib/speed/index.js')
|
||||
const dns = require('../src/lib/dns/index.js')
|
||||
const SpeedTest = require('../src/lib/speed/index.js')
|
||||
const SpeedTester = require('../src/lib/speed/SpeedTester.js')
|
||||
|
||||
const dnsMap = dns.initDNS({
|
||||
// ipaddress: {
|
||||
|
@ -11,8 +11,8 @@ const dnsMap = dns.initDNS({
|
|||
cloudflare: {
|
||||
type: 'https',
|
||||
server: 'https://1.1.1.1/dns-query',
|
||||
cacheSize: 1000
|
||||
}
|
||||
cacheSize: 1000,
|
||||
},
|
||||
// py233: { //污染
|
||||
// type: 'https',
|
||||
// server: ' https://i.233py.com/dns-query',
|
||||
|
@ -33,6 +33,6 @@ const dnsMap = dns.initDNS({
|
|||
SpeedTest.initSpeedTest({ hostnameList: {}, dnsMap })
|
||||
|
||||
const tester = new SpeedTester({ hostname: 'github.com' })
|
||||
tester.test().then(ret => {
|
||||
tester.test().then((ret) => {
|
||||
console.log(tester.alive)
|
||||
})
|
||||
|
|
|
@ -4,33 +4,33 @@ const dnsProviders = dns.initDNS({
|
|||
aliyun: {
|
||||
type: 'https',
|
||||
server: 'https://dns.alidns.com/dns-query',
|
||||
cacheSize: 1000
|
||||
cacheSize: 1000,
|
||||
},
|
||||
cloudflare: {
|
||||
type: 'https',
|
||||
server: 'https://1.1.1.1/dns-query',
|
||||
cacheSize: 1000
|
||||
cacheSize: 1000,
|
||||
},
|
||||
ipaddress: {
|
||||
type: 'ipaddress',
|
||||
server: 'ipaddress',
|
||||
cacheSize: 1000
|
||||
cacheSize: 1000,
|
||||
},
|
||||
quad9: {
|
||||
type: 'https',
|
||||
server: 'https://9.9.9.9/dns-query',
|
||||
cacheSize: 1000
|
||||
cacheSize: 1000,
|
||||
},
|
||||
rubyfish: {
|
||||
type: 'https',
|
||||
server: 'https://rubyfish.cn/dns-query',
|
||||
cacheSize: 1000
|
||||
cacheSize: 1000,
|
||||
},
|
||||
py233: {
|
||||
type: 'https',
|
||||
server: ' https://i.233py.com/dns-query',
|
||||
cacheSize: 1000
|
||||
}
|
||||
cacheSize: 1000,
|
||||
},
|
||||
|
||||
// sb: {
|
||||
// type: 'https',
|
||||
|
|
|
@ -4,7 +4,7 @@ const headers = {}
|
|||
const res = {
|
||||
setHeader: (key, value) => {
|
||||
headers[key] = value
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const proxyRes = {
|
||||
|
@ -20,9 +20,9 @@ const proxyRes = {
|
|||
const newHeaders = {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'Content-Length': '3',
|
||||
xxx: 1,
|
||||
Date: '[remove]',
|
||||
yyy: '[remove]'
|
||||
'xxx': 1,
|
||||
'Date': '[remove]',
|
||||
'yyy': '[remove]',
|
||||
}
|
||||
|
||||
const result = responseReplace.replaceResponseHeaders(newHeaders, res, proxyRes)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const monkey = require('../../../src/lib/monkey/index')
|
||||
|
||||
const scripts = monkey.load()
|
||||
console.log(scripts[0])
|
||||
|
|
|
@ -5,7 +5,7 @@ const hostMap = matchUtil.domainMapRegexply({
|
|||
'*bbb.com': true,
|
||||
'*.ccc.com': true,
|
||||
'^.{1,3}ddd.com$': true,
|
||||
'*.cn': true
|
||||
'*.cn': true,
|
||||
})
|
||||
|
||||
console.log(hostMap)
|
||||
|
|
|
@ -2,21 +2,21 @@ const http = require('http')
|
|||
|
||||
const 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'
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
|
||||
},
|
||||
lookup (hostname, options, callback) {
|
||||
const ip = '106.52.191.148'
|
||||
console.log('lookup')
|
||||
callback(null, ip, 4)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const request = http.get('http://test.target/', options, function (response) {
|
||||
response.on('data', function (data) {
|
||||
const request = http.get('http://test.target/', options, (response) => {
|
||||
response.on('data', (data) => {
|
||||
process.stdout.write(data)
|
||||
})
|
||||
})
|
||||
|
||||
request.on('error', function (error) {
|
||||
request.on('error', (error) => {
|
||||
console.log(error)
|
||||
})
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const CryptoJs = require('crypto-js')
|
||||
|
||||
const ret = CryptoJs.SHA256('111111111111')
|
||||
console.log(ret.toString(CryptoJs.enc.Base64))
|
||||
console.log(1 / 2)
|
||||
|
|
Loading…
Reference in New Issue