代码格式调整:packages/mitmproxy/**/*.js

pull/391/head
王良 2024-11-15 12:09:33 +08:00
parent 48132c39b0
commit 3e586bfd9b
56 changed files with 431 additions and 369 deletions

View File

@ -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,
}

View File

@ -24,5 +24,5 @@ module.exports = {
return obj
}
}
}
},
}

View File

@ -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,
}

View File

@ -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) {

View File

@ -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

View File

@ -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]
}
}
},
}

View File

@ -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`

View File

@ -1,5 +1,4 @@
module.exports = {
lookup () {
}
},
}

View File

@ -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

View File

@ -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)

View File

@ -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
}
},
}

View File

@ -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
}
},
}

View File

@ -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
}
},
}

View File

@ -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,
}

View File

@ -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
}
},
}

View File

@ -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拦截的
}
},
}

View File

@ -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
}
},
}

View File

@ -19,5 +19,5 @@ module.exports = {
},
is (interceptOpt) {
return !!interceptOpt.sni && !interceptOpt.proxy // proxy生效时sni不需要生效因为proxy中也会使用sni覆盖 rOptions.servername
}
},
}

View File

@ -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
}
},
}

View File

@ -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
}
},
}

View File

@ -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
}
},
}

View File

@ -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
}
},
}

View File

@ -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 = {
}
}
}
}
},
}

View File

@ -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

View File

@ -1,4 +1,5 @@
const path = require('path')
const config = exports
config.defaultHost = '127.0.0.1'

View File

@ -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

View File

@ -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}`)
}
},
}

View File

@ -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,
}

View File

@ -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) {
// 尝试解析Base64https://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,
}

View File

@ -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 = []

View File

@ -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)

View File

@ -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,
})
}

View File

@ -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)) {

View File

@ -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)

View File

@ -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)
})
}
}
},
}

View File

@ -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)
}
},
}

View File

@ -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) => {

View File

@ -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)

View File

@ -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

View File

@ -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,
}
}

View File

@ -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 }

View File

@ -1,9 +1,9 @@
const config = {
notify () {},
dnsMap: {}
dnsMap: {},
}
module.exports = {
getConfig () {
return config
}
},
}

View File

@ -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,
}

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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,
}

View File

@ -8,5 +8,5 @@ module.exports = {
if (process.send) {
process.send({ type: 'status', event: status })
}
}
},
}

View File

@ -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)
})

View File

@ -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)
})

View File

@ -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',

View File

@ -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)

View File

@ -1,3 +1,4 @@
const monkey = require('../../../src/lib/monkey/index')
const scripts = monkey.load()
console.log(scripts[0])

View File

@ -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)

View File

@ -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)
})

View File

@ -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)