日志优化

pull/287/head
王良 2024-04-02 12:35:39 +08:00
parent 148bfa0769
commit e40bf546d0
31 changed files with 160 additions and 151 deletions

View File

@ -17,6 +17,7 @@ function get () {
const getDefaultConfigBasePath = function () { const getDefaultConfigBasePath = function () {
return get().server.setting.userBasePath return get().server.setting.userBasePath
} }
function _getRemoteSavePath (prefix = '') { function _getRemoteSavePath (prefix = '') {
const dir = getDefaultConfigBasePath() const dir = getDefaultConfigBasePath()
if (!fs.existsSync(dir)) { if (!fs.existsSync(dir)) {
@ -24,6 +25,7 @@ function _getRemoteSavePath (prefix = '') {
} }
return path.join(dir, prefix + 'remote_config.json5') return path.join(dir, prefix + 'remote_config.json5')
} }
function _getConfigPath () { function _getConfigPath () {
const dir = getDefaultConfigBasePath() const dir = getDefaultConfigBasePath()
if (!fs.existsSync(dir)) { if (!fs.existsSync(dir)) {
@ -106,7 +108,7 @@ const configApi = {
log.warn('远程配置文件不存在:', path) log.warn('远程配置文件不存在:', path)
} }
} catch (e) { } catch (e) {
log.warn('远程配置读取失败:', path, ', error:', e) log.error('远程配置读取失败:', path, ', error:', e)
} }
return {} return {}
@ -183,6 +185,7 @@ const configApi = {
get, get,
set (newConfig) { set (newConfig) {
if (newConfig == null) { if (newConfig == null) {
log.warn('newConfig 为空,不做任何操作')
return configTarget return configTarget
} }

View File

@ -65,7 +65,7 @@ async function startup ({ mitmproxyPath }) {
await plugin[key].start() await plugin[key].start()
log.info(`插件【${key}】已启动`) log.info(`插件【${key}】已启动`)
} catch (err) { } catch (err) {
log.error(`插件【${key}】启动失败`, err) log.error(`插件【${key}】启动失败:`, err)
} }
} }
plugins.push(start()) plugins.push(start())
@ -89,7 +89,7 @@ async function shutdown () {
await plugin[key].close() await plugin[key].close()
log.info(`插件【${key}】已关闭`) log.info(`插件【${key}】已关闭`)
} catch (err) { } catch (err) {
log.info(`插件【${key}】关闭失败`, err) log.error(`插件【${key}】关闭失败:`, err)
} }
} }
plugins.push(close()) plugins.push(close())
@ -99,7 +99,7 @@ async function shutdown () {
await Promise.all(plugins) await Promise.all(plugins)
} }
} catch (error) { } catch (error) {
log.error('插件关闭失败', error) log.error('插件关闭失败:', error)
} }
if (status.proxy.enabled) { if (status.proxy.enabled) {
@ -107,7 +107,7 @@ async function shutdown () {
await proxy.close() await proxy.close()
log.info('系统代理已关闭') log.info('系统代理已关闭')
} catch (err) { } catch (err) {
log.error('系统代理关闭失败', err) log.error('系统代理关闭失败:', err)
} }
} }
if (status.server.enabled) { if (status.server.enabled) {
@ -115,7 +115,7 @@ async function shutdown () {
await server.close() await server.close()
log.info('代理服务已关闭') log.info('代理服务已关闭')
} catch (err) { } catch (err) {
log.error('代理服务关闭失败', err) log.error('代理服务关闭失败:', err)
} }
} }
} }

View File

@ -8,11 +8,11 @@ process.on('uncaughtException', function (err) {
// console.error(err.errno) // console.error(err.errno)
return return
} }
log.error('uncaughtException', err) log.error('Process Uncaught Exception:', err)
}) })
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
log.error('Unhandled Rejection at: Promise', p, 'reason:', reason) log.error('Process Unhandled Rejection at: Promise:', p, ', reason:', reason)
// application specific logging, throwing an error, or other logic here // application specific logging, throwing an error, or other logic here
}) })

View File

@ -1,4 +1,3 @@
const expect = require('chai').expect
const https = require('https') const https = require('https')
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1' process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1'
function request () { function request () {

View File

@ -1,4 +1,4 @@
var expect = require('chai').expect const expect = require('chai').expect
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
describe('test', function () { describe('test', function () {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef

View File

@ -1,4 +1,3 @@
!macro customUnInit !macro customUnInit
MessageBox MB_OK "卸载前请务必手动退出DevSidecar之后,再进行下一步(如果已经退出请忽略)"
ExecWait '"$INSTDIR\resources\extra\sysproxy.exe" set 1' ExecWait '"$INSTDIR\resources\extra\sysproxy.exe" set 1'
!macroend !macroend

View File

@ -205,7 +205,7 @@ function createWindow (startHideWindow) {
}) })
win.on('session-end', async (e) => { win.on('session-end', async (e) => {
log.info('session-end', e) log.info('session-end:', e)
await quit() await quit()
}) })
} }
@ -241,12 +241,12 @@ if (process.argv) {
startHideWindow = true startHideWindow = true
} }
log.info('start args', args) log.info('start args:', args)
} }
if (app.getLoginItemSettings().wasOpenedAsHidden) { if (app.getLoginItemSettings().wasOpenedAsHidden) {
startHideWindow = true startHideWindow = true
} }
log.info('start hide window', startHideWindow, app.getLoginItemSettings()) log.info('start hide window:', startHideWindow, app.getLoginItemSettings())
// 禁止双开 // 禁止双开
const isFirstInstance = app.requestSingleInstanceLock() const isFirstInstance = app.requestSingleInstanceLock()
@ -263,7 +263,7 @@ if (!isFirstInstance) {
} }
}) })
app.on('second-instance', (event, commandLine, workingDirectory) => { app.on('second-instance', (event, commandLine, workingDirectory) => {
log.info('new app started', commandLine) log.info('new app started, command:', commandLine)
if (win) { if (win) {
showWin() showWin()
win.focus() win.focus()
@ -309,14 +309,14 @@ if (!isFirstInstance) {
const context = { win, app, beforeQuit, quit, ipcMain, dialog, log, api: DevSidecar.api, changeAppConfig } const context = { win, app, beforeQuit, quit, ipcMain, dialog, log, api: DevSidecar.api, changeAppConfig }
backend.install(context) // 模块安装 backend.install(context) // 模块安装
} catch (err) { } catch (err) {
log.info('err', err) log.info('error:', err)
} }
try { try {
// 最小化到托盘 // 最小化到托盘
tray = setTray() tray = setTray()
} catch (err) { } catch (err) {
log.info('err', err) log.info('error:', err)
} }
powerMonitor.on('shutdown', async (e) => { powerMonitor.on('shutdown', async (e) => {

View File

@ -145,11 +145,11 @@ export default {
}) })
// 注册从core里来的事件并转发给view // 注册从core里来的事件并转发给view
DevSidecar.api.event.register('status', (event) => { DevSidecar.api.event.register('status', (event) => {
log.info('bridge on status', event) log.info('bridge on status, event:', event)
win.webContents.send('status', { ...event }) win.webContents.send('status', { ...event })
}) })
DevSidecar.api.event.register('error', (event) => { DevSidecar.api.event.register('error', (event) => {
log.error('bridge on error', event) log.error('bridge on error, event:', event)
win.webContents.send('error.core', event) win.webContents.send('error.core', event)
}) })
DevSidecar.api.event.register('speed', (event) => { DevSidecar.api.event.register('speed', (event) => {

View File

@ -13,7 +13,7 @@ export default {
event.sender.send('file-selector', { key: 'selected', value: result.filePaths }) event.sender.send('file-selector', { key: 'selected', value: result.filePaths })
} }
}).catch(err => { }).catch(err => {
log.error('选择文件失败', err) log.error('选择文件失败:', err)
}) })
} }
}) })

View File

@ -96,7 +96,7 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
}) })
} }
async function updatePart (app, api, value, partPackagePath, quit) { async function updatePart (app, api, value, partPackagePath) {
const appPath = appPathUtil.getAppRootPath(app) const appPath = appPathUtil.getAppRootPath(app)
const platform = api.shell.getSystemPlatform() const platform = api.shell.getSystemPlatform()
let target = path.join(appPath, 'resources') let target = path.join(appPath, 'resources')
@ -106,7 +106,7 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
const length = fs.statSync(partPackagePath) const length = fs.statSync(partPackagePath)
log.info('安装包大小:', length) log.info('安装包大小:', length)
log.info('开始解压缩,安装升级包', partPackagePath, target) log.info('开始解压缩,安装升级包:', partPackagePath, target)
try { try {
await beforeQuit() await beforeQuit()
@ -121,7 +121,7 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
} }
autoUpdater.on('error', function (error) { autoUpdater.on('error', function (error) {
log.info('autoUpdater error', error) log.warn('autoUpdater error:', error)
sendUpdateMessage({ key: 'error', value: error, error: error }) sendUpdateMessage({ key: 'error', value: error, error: error })
// dialog.showErrorBox('Error: ', error == null ? 'unknown' : (error.stack || error).toString()) // dialog.showErrorBox('Error: ', error == null ? 'unknown' : (error.stack || error).toString())
}) })
@ -133,7 +133,7 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
log.info('autoUpdater update-available') log.info('autoUpdater update-available')
sendUpdateMessage({ key: 'available', value: info }) sendUpdateMessage({ key: 'available', value: info })
}) })
autoUpdater.on('update-not-available', function (info) { autoUpdater.on('update-not-available', function () {
log.info('autoUpdater update-not-available') log.info('autoUpdater update-not-available')
sendUpdateMessage({ key: 'notAvailable', value: message.updateNotAva }) sendUpdateMessage({ key: 'notAvailable', value: message.updateNotAva })
}) })
@ -144,7 +144,7 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
}) })
// 更新完成,重启应用 // 更新完成,重启应用
autoUpdater.on('update-downloaded', function (info) { autoUpdater.on('update-downloaded', function (info) {
log.info('download complete', info.version) log.info('download complete, version:', info.version)
win.webContents.send('update', { win.webContents.send('update', {
key: 'downloaded', key: 'downloaded',
value: info value: info

View File

@ -2,7 +2,7 @@ const path = require('path')
const webpack = require('webpack') const webpack = require('webpack')
const publishUrl = process.env.VUE_APP_PUBLISH_URL const publishUrl = process.env.VUE_APP_PUBLISH_URL
const publishProvider = process.env.VUE_APP_PUBLISH_PROVIDER const publishProvider = process.env.VUE_APP_PUBLISH_PROVIDER
console.log('publish url', publishUrl) console.log('Publish url:', publishUrl)
module.exports = { module.exports = {
pages: { pages: {
index: { index: {

View File

@ -8,7 +8,7 @@ let server
function registerProcessListener () { function registerProcessListener () {
process.on('message', function (msg) { process.on('message', function (msg) {
log.info('child get msg: ' + JSON.stringify(msg)) log.info('child get msg:', JSON.stringify(msg))
if (msg.type === 'action') { if (msg.type === 'action') {
api[msg.event.key](msg.event.params) api[msg.event.key](msg.event.params)
} else if (msg.type === 'speed') { } else if (msg.type === 'speed') {
@ -27,15 +27,15 @@ function registerProcessListener () {
// log.error(err.errno) // log.error(err.errno)
return return
} }
log.error('uncaughtException:', err) log.error('Process uncaughtException:', err)
}) })
process.on('unhandledRejection', (err, p) => { process.on('unhandledRejection', (err, p) => {
log.info('Unhandled Rejection at: Promise', p, 'err:', err) log.info('Process unhandledRejection at: Promise', p, 'err:', err)
// application specific logging, throwing an error, or other logic here // application specific logging, throwing an error, or other logic here
}) })
process.on('uncaughtExceptionMonitor', (err, origin) => { process.on('uncaughtExceptionMonitor', (err, origin) => {
log.info('uncaughtExceptionMonitor:', err, origin) log.info('Process uncaughtExceptionMonitor:', err, origin)
}) })
process.on('exit', function (code, signal) { process.on('exit', function (code, signal) {
log.info('代理服务进程被关闭:', code, signal) log.info('代理服务进程被关闭:', code, signal)
@ -63,6 +63,7 @@ const api = {
} else { } else {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1' process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1'
} }
// log.info('启动代理服务时的配置:', JSON.stringify(proxyOptions, null, '\t'))
const newServer = mitmproxy.createProxy(proxyOptions, () => { const newServer = mitmproxy.createProxy(proxyOptions, () => {
fireStatus(true) fireStatus(true)
log.info(`代理服务已启动:${proxyOptions.host}:${proxyOptions.port}`) log.info(`代理服务已启动:${proxyOptions.host}:${proxyOptions.port}`)
@ -87,21 +88,22 @@ const api = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (server) { if (server) {
server.close((err) => { server.close((err) => {
if (err) { if (err && err.code !== 'ERR_SERVER_NOT_RUNNING') {
log.info('close error', err, ',', err.code, ',', err.message, ',', err.errno)
if (err.code === 'ERR_SERVER_NOT_RUNNING') { if (err.code === 'ERR_SERVER_NOT_RUNNING') {
log.info('代理服务关闭成功') log.info('代理服务未运行,无需关闭')
resolve() resolve()
} else {
log.error('代理服务关闭失败:', err)
reject(err)
}
return return
} }
reject(err)
} else {
log.info('代理服务关闭成功') log.info('代理服务关闭成功')
resolve() resolve()
}
}) })
} else { } else {
log.info('server is null') log.info('server is null, no need to close.')
fireStatus(false) fireStatus(false)
resolve() resolve()
} }

View File

@ -10,12 +10,12 @@ class ChoiceCache {
return this.cache.get(key) return this.cache.get(key)
} }
getOrCreate (key, backups) { getOrCreate (key, backupList) {
log.info('get counter:', key) log.info('get counter:', key)
let item = this.cache.get(key) let item = this.cache.get(key)
if (item == null) { if (item == null) {
item = new DynamicChoice(key) item = new DynamicChoice(key)
item.setBackupList(backups) item.setBackupList(backupList)
this.cache.set(key, item) this.cache.set(key, item)
} }
return item return item

View File

@ -15,12 +15,12 @@ module.exports = class DNSOverHTTPS extends BaseDNS {
const result = await dohQueryAsync({ url: this.dnsServer }, [{ type: 'A', name: hostname }]) const result = await dohQueryAsync({ url: this.dnsServer }, [{ type: 'A', name: hostname }])
if (result.answers.length === 0) { if (result.answers.length === 0) {
// 说明没有获取到ip // 说明没有获取到ip
log.info('该域名没有ip地址解析', hostname) log.info('该域名没有ip地址解析:', hostname)
return [] return []
} }
const ret = result.answers.filter(item => { return item.type === 'A' }).map(item => { return item.data }) const ret = result.answers.filter(item => { return item.type === 'A' }).map(item => { return item.data })
if (ret.length === 0) { if (ret.length === 0) {
log.info('该域名没有ipv4地址解析', hostname) log.info('该域名没有IPv4地址解析:', hostname)
} else { } else {
log.info('获取到域名地址:', hostname, JSON.stringify(ret)) log.info('获取到域名地址:', hostname, JSON.stringify(ret))
} }

View File

@ -1,9 +1,6 @@
const dnstls = require('dns-over-tls')
const BaseDNS = require('./base') const BaseDNS = require('./base')
const axios = require('axios') const axios = require('axios')
const log = require('../../utils/util.log') const log = require('../../utils/util.log')
const fs = require('fs')
const path = require('path')
module.exports = class DNSOverIpAddress extends BaseDNS { module.exports = class DNSOverIpAddress extends BaseDNS {
async _lookup (hostname) { async _lookup (hostname) {
const url = `https://${hostname}.ipaddress.com` const url = `https://${hostname}.ipaddress.com`

View File

@ -7,7 +7,7 @@ module.exports = class DNSOverTLS extends BaseDNS {
const answer = answers.find(answer => answer.type === 'A' && answer.class === 'IN') const answer = answers.find(answer => answer.type === 'A' && answer.class === 'IN')
log.info('dns lookup', hostname, answer) log.info('DNS lookup', hostname, answer)
if (answer) { if (answer) {
return answer.data return answer.data
} }

View File

@ -56,16 +56,16 @@ function loadScript (content) {
} }
function readFile (rootDir, script) { function readFile (rootDir, script) {
log.info('script root location', path.resolve('./')) log.info('read script, script root location:', path.resolve('./'))
const location = path.join(rootDir, './' + script) const location = path.join(rootDir, './' + script)
log.info('script location:', location) log.info('read script, the script location:', location)
return fs.readFileSync(location).toString() return fs.readFileSync(location).toString()
} }
const api = { const api = {
get (rootDir) { get (rootDir) {
if (scripts == null) { if (scripts == null) {
api.load(rootDir) return api.load(rootDir)
} }
return scripts return scripts
}, },

View File

@ -57,7 +57,7 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null) => {
try { try {
externalProxyUrl = externalProxy(req, ssl) externalProxyUrl = externalProxy(req, ssl)
} catch (e) { } catch (e) {
log.error('externalProxy', e) log.error('externalProxy error:', e)
} }
} }
} }
@ -86,8 +86,9 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null) => {
// 初始化options // 初始化options
const options = { const options = {
protocol: protocol, protocol: protocol,
hostname: arr[0],
method: req.method, method: req.method,
url: req.url,
hostname: arr[0],
port: arr[1] || defaultPort, port: arr[1] || defaultPort,
path: urlObject.path, path: urlObject.path,
headers: req.headers, headers: req.headers,
@ -154,7 +155,7 @@ util.getTunnelAgent = (requestIsSSL, externalProxyUrl) => {
// host: hostname, // host: hostname,
// port: port // port: port
// } // }
// }); // })
// } // }
return false return false
} else { } else {

View File

@ -64,7 +64,7 @@ module.exports = function createOverWallIntercept (overWallConfig) {
count.doRank() count.doRank()
} }
if (count.value == null) { if (count.value == null) {
log.error('count value is null', count) log.error('`count.value` is null, the count:', count)
} else { } else {
count.doCount(count.value) count.doCount(count.value)
proxyServer = count.value proxyServer = count.value

View File

@ -9,12 +9,10 @@ const speedTest = require('../../speed/index.js')
function isSslConnect (sslConnectInterceptors, req, cltSocket, head) { function isSslConnect (sslConnectInterceptors, req, cltSocket, head) {
for (const intercept of sslConnectInterceptors) { for (const intercept of sslConnectInterceptors) {
const ret = intercept(req, cltSocket, head) const ret = intercept(req, cltSocket, head)
if (ret === false) { if (ret === false || ret === true) {
return false return ret
}
if (ret === true) {
return true
} }
// continue
} }
return false return false
} }
@ -30,14 +28,13 @@ module.exports = function createConnectHandler (sslConnectInterceptor, middlewar
} }
} }
console.log('sni config', sniConfig) // log.info('sni config:', sniConfig)
// const sniRegexpMap = matchUtil.domainMapRegexply(sniConfig) // const sniRegexpMap = matchUtil.domainMapRegexply(sniConfig)
return function connectHandler (req, cltSocket, head) { return function connectHandler (req, cltSocket, head) {
// eslint-disable-next-line node/no-deprecated-api // eslint-disable-next-line node/no-deprecated-api
const srvUrl = url.parse(`https://${req.url}`) const { hostname, port } = url.parse(`https://${req.url}`)
const hostname = srvUrl.hostname
if (isSslConnect(sslConnectInterceptors, req, cltSocket, head)) { if (isSslConnect(sslConnectInterceptors, req, cltSocket, head)) {
fakeServerCenter.getServerPromise(hostname, srvUrl.port).then((serverObj) => { fakeServerCenter.getServerPromise(hostname, port).then((serverObj) => {
log.info('--- fakeServer connect', hostname) log.info('--- fakeServer connect', hostname)
connect(req, cltSocket, head, localIP, serverObj.port) connect(req, cltSocket, head, localIP, serverObj.port)
}, (e) => { }, (e) => {
@ -45,7 +42,7 @@ module.exports = function createConnectHandler (sslConnectInterceptor, middlewar
}) })
} else { } else {
log.info('不拦截请求:', hostname) log.info('不拦截请求:', hostname)
connect(req, cltSocket, head, hostname, srvUrl.port, dnsConfig/*, sniRegexpMap */) connect(req, cltSocket, head, hostname, port, dnsConfig/*, sniRegexpMap */)
} }
} }
} }
@ -55,6 +52,7 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig/*, sniRegexpMa
// log.info('connect:', hostname, port) // log.info('connect:', hostname, port)
const start = new Date().getTime() const start = new Date().getTime()
let isDnsIntercept = null let isDnsIntercept = null
const hostport = `${hostname}:${port}`
// const replaceSni = matchUtil.matchHostname(sniRegexpMap, hostname, 'sni') // const replaceSni = matchUtil.matchHostname(sniRegexpMap, hostname, 'sni')
try { try {
const options = { const options = {
@ -91,17 +89,17 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig/*, sniRegexpMa
cltSocket.write('HTTP/1.1 200 Connection Established\r\n' + cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: dev-sidecar\r\n' + 'Proxy-agent: dev-sidecar\r\n' +
'\r\n') '\r\n')
log.info('proxy connect start', hostname) log.info('Proxy connect start:', hostport)
proxySocket.write(head) proxySocket.write(head)
proxySocket.pipe(cltSocket) proxySocket.pipe(cltSocket)
cltSocket.pipe(proxySocket) cltSocket.pipe(proxySocket)
}) })
cltSocket.on('timeout', (e) => { cltSocket.on('timeout', (e) => {
log.error('cltSocket timeout', e.message, hostname) log.error(`cltSocket timeout: ${hostport}, errorMsg: ${e.message}`)
}) })
cltSocket.on('error', (e) => { cltSocket.on('error', (e) => {
log.error('cltSocket error', e.message, hostname) log.error(`cltSocket error: ${hostport}, errorMsg: ${e.message}`)
}) })
proxySocket.on('timeout', () => { proxySocket.on('timeout', () => {
const end = new Date().getTime() const end = new Date().getTime()
@ -119,7 +117,7 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig/*, sniRegexpMa
} }
}) })
return proxySocket return proxySocket
} catch (error) { } catch (e) {
log.error('connect err', error) log.error(`Proxy connect error: ${hostport}, exception:`, e)
} }
} }

View File

@ -1,7 +1,6 @@
const fs = require('fs') const fs = require('fs')
const forge = require('node-forge') const forge = require('node-forge')
const FakeServersCenter = require('../tls/FakeServersCenter') const FakeServersCenter = require('../tls/FakeServersCenter')
const colors = require('colors')
const log = require('../../../utils/util.log') const log = require('../../../utils/util.log')
module.exports = function createFakeServerCenter ({ module.exports = function createFakeServerCenter ({
caCertPath, caCertPath,
@ -20,7 +19,7 @@ module.exports = function createFakeServerCenter ({
caCert = forge.pki.certificateFromPem(caCertPem) caCert = forge.pki.certificateFromPem(caCertPem)
caKey = forge.pki.privateKeyFromPem(caKeyPem) caKey = forge.pki.privateKeyFromPem(caKeyPem)
} catch (e) { } catch (e) {
log.info(colors.red('Can not find `CA certificate` or `CA key`.'), e) log.error('Can not find `CA certificate` or `CA key`:', e)
process.exit(1) process.exit(1)
} }

View File

@ -80,16 +80,16 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
}) })
} }
function countSlow (isDnsIntercept, type) { function countSlow (isDnsIntercept, reason) {
if (isDnsIntercept) { if (isDnsIntercept) {
const { dns, ip, hostname } = isDnsIntercept const { dns, ip, hostname } = isDnsIntercept
dns.count(hostname, ip, true) dns.count(hostname, ip, true)
log.error('记录ip失败次数,用于优选ip', hostname, ip, type) log.error('记录ip失败次数,用于优选ip', hostname, ip, reason)
} }
const counter = context.requestCount const counter = context.requestCount
if (counter != null) { if (counter != null) {
counter.count.doCount(counter.value, true) counter.count.doCount(counter.value, true)
log.error('记录proxy失败次数', counter.value, type) log.error('记录proxy失败次数', counter.value, reason)
} }
} }
@ -220,6 +220,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
await requestInterceptorPromise() await requestInterceptorPromise()
if (res.writableEnded) { if (res.writableEnded) {
// log.info('res is writableEnded, return false')
return false return false
} }
@ -230,7 +231,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
// }) // })
proxyRes.on('error', (error) => { proxyRes.on('error', (error) => {
countSlow(null, 'error: ' + error.message) countSlow(null, 'error: ' + error.message)
log.error('proxy res error', error) log.error('proxy res error:', error)
}) })
const responseInterceptorPromise = new Promise((resolve, reject) => { const responseInterceptorPromise = new Promise((resolve, reject) => {
@ -252,13 +253,19 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
let body = '' let body = ''
for (const resIncpt of resIncpts) { for (const resIncpt of resIncpts) {
const append = resIncpt.responseIntercept(context, req, res, proxyReq, proxyRes, ssl) const append = resIncpt.responseIntercept(context, req, res, proxyReq, proxyRes, ssl)
if (append && append.head) { if (append) {
if (append.head) {
head += append.head head += append.head
} }
if (append && append.body) { if (append.body) {
body += append.body body += append.body
} }
} }
if (res.writableEnded) {
next()
return
}
}
InsertScriptMiddleware.responseInterceptor(req, res, proxyReq, proxyRes, ssl, next, { InsertScriptMiddleware.responseInterceptor(req, res, proxyReq, proxyRes, ssl, next, {
head, head,
body body
@ -288,7 +295,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
}) })
if (proxyRes.statusCode >= 400) { if (proxyRes.statusCode >= 400) {
countSlow(null, 'status return :' + proxyRes.statusCode) countSlow(null, 'Status return: ' + proxyRes.statusCode)
} }
res.writeHead(proxyRes.statusCode) res.writeHead(proxyRes.statusCode)
proxyRes.pipe(res) proxyRes.pipe(res)
@ -302,7 +309,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
目标地址${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}` 目标地址${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`
) )
res.end() res.end()
log.error('request error', e.message) log.error('Request error:', e)
} }
}) })
} }

View File

@ -11,7 +11,7 @@ module.exports = function createUpgradeHandler () {
const clientOptions = util.getOptionsFromRequest(req, ssl) const clientOptions = util.getOptionsFromRequest(req, ssl)
const proxyReq = (ssl ? https : http).request(clientOptions) const proxyReq = (ssl ? https : http).request(clientOptions)
proxyReq.on('error', (e) => { proxyReq.on('error', (e) => {
log.error('upgradeHandler', e) log.error('upgradeHandler error:', e)
}) })
proxyReq.on('response', function (res) { proxyReq.on('response', function (res) {
// if upgrade event isn't going to happen, close the socket // if upgrade event isn't going to happen, close the socket
@ -20,11 +20,11 @@ module.exports = function createUpgradeHandler () {
proxyReq.on('upgrade', function (proxyRes, proxySocket, proxyHead) { proxyReq.on('upgrade', function (proxyRes, proxySocket, proxyHead) {
proxySocket.on('error', (e) => { proxySocket.on('error', (e) => {
log.error('on upgrade:', e) log.error('upgrade error:', e)
}) })
cltSocket.on('error', function (e) { cltSocket.on('error', function (e) {
log.error('upgrade socket ', e) log.error('upgrade socket error:', e)
proxySocket.end() proxySocket.end()
}) })

View File

@ -1,14 +1,11 @@
const tlsUtils = require('../tls/tlsUtils') const tlsUtils = require('../tls/tlsUtils')
const http = require('http') const http = require('http')
const https = require('https')
const config = require('../common/config') const config = require('../common/config')
const log = require('../../../utils/util.log') const log = require('../../../utils/util.log')
const createRequestHandler = require('./createRequestHandler') const createRequestHandler = require('./createRequestHandler')
const createConnectHandler = require('./createConnectHandler') const createConnectHandler = require('./createConnectHandler')
const createFakeServerCenter = require('./createFakeServerCenter') const createFakeServerCenter = require('./createFakeServerCenter')
const createUpgradeHandler = require('./createUpgradeHandler') const createUpgradeHandler = require('./createUpgradeHandler')
const DnsUtil = require('../../dns/index')
const defaultDns = require('dns')
const speedTest = require('../../speed/index.js') const speedTest = require('../../speed/index.js')
module.exports = { module.exports = {
createProxy ({ createProxy ({
@ -18,7 +15,7 @@ module.exports = {
caKeyPath, caKeyPath,
sslConnectInterceptor, sslConnectInterceptor,
createIntercepts, createIntercepts,
getCertSocketTimeout = 1 * 1000, getCertSocketTimeout = 1000,
middlewares = [], middlewares = [],
externalProxy, externalProxy,
dnsConfig, dnsConfig,
@ -85,7 +82,7 @@ module.exports = {
server.listen(port, host, () => { server.listen(port, host, () => {
log.info(`dev-sidecar启动端口: ${port}`) log.info(`dev-sidecar启动端口: ${port}`)
server.on('error', (e) => { server.on('error', (e) => {
log.error('server error', e) log.error('server error:', e)
}) })
server.on('request', (req, res) => { server.on('request', (req, res) => {
const ssl = false const ssl = false
@ -103,7 +100,7 @@ module.exports = {
upgradeHandler(req, socket, head, ssl) upgradeHandler(req, socket, head, ssl)
}) })
server.on('clientError', (err, socket) => { server.on('clientError', (err, socket) => {
log.error('client error', err) log.error('client error:', err)
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n') socket.end('HTTP/1.1 400 Bad Request\r\n\r\n')
}) })

View File

@ -23,10 +23,10 @@ module.exports = class FakeServersCenter {
if (this.queue.length >= this.maxLength) { if (this.queue.length >= this.maxLength) {
const delServerObj = this.queue.shift() const delServerObj = this.queue.shift()
try { try {
log.info('超过最大服务数量,删除旧服务', delServerObj) log.info('超过最大服务数量,删除旧服务。delServerObj:', delServerObj)
delServerObj.serverObj.server.close() delServerObj.serverObj.server.close()
} catch (e) { } catch (e) {
log.info(e) log.info('`delServerObj.serverObj.server.close()` error:', e)
} }
} }
this.queue.push(serverPromiseObj) this.queue.push(serverPromiseObj)
@ -87,7 +87,7 @@ module.exports = class FakeServersCenter {
this.requestHandler(req, res, ssl) this.requestHandler(req, res, ssl)
}) })
fakeServer.on('error', (e) => { fakeServer.on('error', (e) => {
log.error(e) log.error('fakeServer error:', e)
}) })
fakeServer.on('listening', () => { fakeServer.on('listening', () => {
const mappingHostNames = tlsUtils.getMappingHostNamesFromCert(certObj.cert) const mappingHostNames = tlsUtils.getMappingHostNamesFromCert(certObj.cert)

View File

@ -51,10 +51,10 @@ module.exports = function extractSNI (data) {
} ClientHello; } ClientHello;
*/ */
var end = data.length let end = data.length
// skip the record header // skip the record header
var pos = 5 let pos = 5
// skip HandshakeType (you should already have verified this) // skip HandshakeType (you should already have verified this)
pos += 1 pos += 1
@ -70,26 +70,26 @@ module.exports = function extractSNI (data) {
// skip SessionID // skip SessionID
if (pos > end - 1) return null if (pos > end - 1) return null
var sessionIdLength = data[pos] const sessionIdLength = data[pos]
pos += 1 + sessionIdLength pos += 1 + sessionIdLength
// skip CipherSuite // skip CipherSuite
if (pos > end - 2) return null if (pos > end - 2) return null
var cipherSuiteLength = data[pos] << 8 | data[pos + 1] const cipherSuiteLength = data[pos] << 8 | data[pos + 1]
pos += 2 + cipherSuiteLength pos += 2 + cipherSuiteLength
// skip CompressionMethod // skip CompressionMethod
if (pos > end - 1) return null if (pos > end - 1) return null
var compressionMethodLength = data[pos] const compressionMethodLength = data[pos]
pos += 1 + compressionMethodLength pos += 1 + compressionMethodLength
// verify extensions exist // verify extensions exist
if (pos > end - 2) return null if (pos > end - 2) return null
var extensionsLength = data[pos] << 8 | data[pos + 1] const extensionsLength = data[pos] << 8 | data[pos + 1]
pos += 2 pos += 2
// verify the extensions fit // verify the extensions fit
var extensionsEnd = pos + extensionsLength const extensionsEnd = pos + extensionsLength
if (extensionsEnd > end) return null if (extensionsEnd > end) return null
end = extensionsEnd end = extensionsEnd
@ -124,22 +124,22 @@ module.exports = function extractSNI (data) {
*/ */
while (pos <= end - 4) { while (pos <= end - 4) {
var extensionType = data[pos] << 8 | data[pos + 1] const extensionType = data[pos] << 8 | data[pos + 1]
var extensionSize = data[pos + 2] << 8 | data[pos + 3] const extensionSize = data[pos + 2] << 8 | data[pos + 3]
pos += 4 pos += 4
if (extensionType === 0) { // ExtensionType was server_name(0) if (extensionType === 0) { // ExtensionType was server_name(0)
// read ServerNameList length // read ServerNameList length
if (pos > end - 2) return null if (pos > end - 2) return null
var nameListLength = data[pos] << 8 | data[pos + 1] const nameListLength = data[pos] << 8 | data[pos + 1]
pos += 2 pos += 2
// verify we have enough bytes and loop over SeverNameList // verify we have enough bytes and loop over SeverNameList
var n = pos let n = pos
pos += nameListLength pos += nameListLength
if (pos > end) return null if (pos > end) return null
while (n < pos - 3) { while (n < pos - 3) {
var nameType = data[n] const nameType = data[n]
var nameLength = data[n + 1] << 8 | data[n + 2] const nameLength = data[n + 1] << 8 | data[n + 2]
n += 3 n += 3
// check if NameType is host_name(0) // check if NameType is host_name(0)

View File

@ -1,5 +1,6 @@
const forge = require('node-forge') const forge = require('node-forge')
const fs = require('fs') const fs = require('fs')
const log = require('../../../utils/util.log')
const path = require('path') const path = require('path')
const config = require('../common/config') const config = require('../common/config')
const _ = require('lodash') const _ = require('lodash')
@ -262,6 +263,7 @@ utils.initCA = function ({ caCertPath, caKeyPath }) {
mkdirp.sync(path.dirname(caCertPath)) mkdirp.sync(path.dirname(caCertPath))
fs.writeFileSync(caCertPath, certPem) fs.writeFileSync(caCertPath, certPem)
fs.writeFileSync(caKeyPath, keyPem) fs.writeFileSync(caKeyPath, keyPem)
log.info('生成证书文件成功共2个文件:', caCertPath, caKeyPath)
} }
return { return {
caCertPath, caCertPath,

View File

@ -58,11 +58,12 @@ class SpeedTester {
async getIpListFromDns (dnsMap) { async getIpListFromDns (dnsMap) {
const ips = {} const ips = {}
const promiseList = [] const promiseList = []
for (const key in dnsMap) { for (const dnsKey in dnsMap) {
const one = this.getFromOneDns(dnsMap[key]).then(ipList => { const dns = dnsMap[dnsKey]
const one = this.getFromOneDns(dns).then(ipList => {
if (ipList) { if (ipList) {
for (const ip of ipList) { for (const ip of ipList) {
ips[ip] = 1 ips[ip] = { dns: dnsKey }
} }
} }
}) })
@ -71,7 +72,7 @@ class SpeedTester {
await Promise.all(promiseList) await Promise.all(promiseList)
const items = [] const items = []
for (const ip in ips) { for (const ip in ips) {
items.push({ host: ip, port: 443 }) items.push({ host: ip, port: 443, dns: ips[ip].dns })
} }
return items return items
} }
@ -86,7 +87,7 @@ class SpeedTester {
this.backupList = _.unionBy(newBackupList, 'host') this.backupList = _.unionBy(newBackupList, 'host')
this.testCount++ this.testCount++
log.info('[speed]', this.hostname, ' ips:', this.backupList) log.info('[speed]', this.hostname, ' ips:', this.backupList)
await this.testBackups() await this.testBackups()
if (config.notify) { if (config.notify) {
config.notify({ key: 'test' }) config.notify({ key: 'test' })
@ -112,13 +113,15 @@ class SpeedTester {
aliveList.sort((a, b) => a.time - b.time) aliveList.sort((a, b) => a.time - b.time)
this.backupList.sort((a, b) => a.time - b.time) this.backupList.sort((a, b) => a.time - b.time)
} catch (e) { } catch (e) {
log.error('[speed] test error', this.hostname, item.host, e.message) if (e.message !== 'timeout') {
log.warn('[speed] test error: ', this.hostname, `${item.host}:${item.port} from DNS '${item.dns}'`, ', errorMsg:', e.message)
}
} }
} }
testOne (item) { testOne (item) {
const timeout = 5000 const timeout = 5000
const { host, port } = item const { host, port, dns } = item
const startTime = Date.now() const startTime = Date.now()
let isOver = false let isOver = false
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -133,18 +136,20 @@ class SpeedTester {
}) })
client.on('end', () => { client.on('end', () => {
}) })
client.on('error', (error) => { client.on('error', (e) => {
log.error('[speed]test error', this.hostname, host, error.message) if (e.message !== 'timeout') {
log.warn('[speed] test error: ', this.hostname, `${host}:${port} from DNS '${dns}', cost: ${Date.now() - startTime} ms, errorMsg:`, e.message)
}
isOver = true isOver = true
clearTimeout(timeoutId) clearTimeout(timeoutId)
reject(error) reject(e)
}) })
timeoutId = setTimeout(() => { timeoutId = setTimeout(() => {
if (isOver) { if (isOver) {
return return
} }
log.error('[speed] test timeout', this.hostname, host) log.warn('[speed] test timeout:', this.hostname, `${host}:${port} from DNS '${dns}', cost: ${Date.now() - startTime} ms`)
reject(new Error('timeout')) reject(new Error('timeout'))
client.end() client.end()
}, timeout) }, timeout)

View File

@ -1,4 +1,4 @@
const os = require('os') // const os = require('os')
const log = require('util.log') const log = require('util.log')
const util = { const util = {
getNodeVersion () { getNodeVersion () {

View File

@ -1,6 +1,6 @@
const http = require('http') const http = require('http')
var options = { const options = {
headers: { 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'
}, },
@ -11,7 +11,7 @@ var options = {
} }
} }
var request = http.get('http://test.target/', options, function (response) { const request = http.get('http://test.target/', options, function (response) {
response.on('data', function (data) { response.on('data', function (data) {
process.stdout.write(data) process.stdout.write(data)
}) })

View File

@ -10,9 +10,9 @@
// } // }
// ) // )
// var process = require('child_process') // const process = require('child_process')
// //
// var cmd = 'set' // const cmd = 'set'
// process.exec(cmd, function (error, stdout, stderr) { // process.exec(cmd, function (error, stdout, stderr) {
// console.log('error:' + error) // console.log('error:' + error)
// console.log('stdout:' + stdout) // console.log('stdout:' + stdout)
@ -22,34 +22,34 @@
// const fs = require('fs') // const fs = require('fs')
// const content = fs.readFileSync('C:\\Users\\Administrator\\.dev-sidecar\\dev-sidecar.ca.crt') // const content = fs.readFileSync('C:\\Users\\Administrator\\.dev-sidecar\\dev-sidecar.ca.crt')
// console.log('content:',JSON.stringify(content.toString().replace(new RegExp('\r\n','g'),'\n'))); // console.log('content:',JSON.stringify(content.toString().replace(new RegExp('\r\n','g'),'\n')))
function testCa() { // function testCa() {
const https = require('https') // const https = require('https')
const fs = require('fs') // const fs = require('fs')
const content = fs.readFileSync('C:\\Users\\Administrator\\.dev-sidecar\\dev-sidecar.ca.crt') // process.env.NODE_EXTRA_CA_CERTS = 'C:\\Users\\Administrator\\.dev-sidecar\\dev-sidecar.ca.crt'
process.env.NODE_EXTRA_CA_CERTS = 'C:\\Users\\Administrator\\.dev-sidecar\\dev-sidecar.ca.crt' // process.env.GLOBAL_AGENT_HTTP_PROXY = "http://127.0.0.1:1181"
process.env.GLOBAL_AGENT_HTTP_PROXY = "http://127.0.0.1:1181" // process.env.GLOBAL_AGENT_HTTPS_PROXY = "http://127.0.0.1:1181"
process.env.GLOBAL_AGENT_HTTPS_PROXY = "http://127.0.0.1:1181" // fs.readFileSync(process.env.NODE_EXTRA_CA_CERTS)
//
const options = { // const options = {
agent : new https.Agent({ // agent : new https.Agent({
proxy: "http://127.0.0.1:1181" // proxy: "http://127.0.0.1:1181"
}) // })
} // }
console.log('options', options) // console.log('options', options)
//
https.get('https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js',options, (res) => { // https.get('https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js',options, (res) => {
console.log('状态码:', res.statusCode) // console.log('状态码:', res.statusCode)
console.log('请求头:', res.headers) // console.log('请求头:', res.headers)
//
res.on('data', (d) => { // res.on('data', (d) => {
process.stdout.write(d) // process.stdout.write(d)
}) // })
}).on('error', (e) => { // }).on('error', (e) => {
console.error(e) // console.error(e)
}) // })
} // }
function testRequest(){ function testRequest(){
// process.env.NODE_EXTRA_CA_CERTS='C:\\Users\\Administrator\\.dev-sidecar\\dev-sidecar.ca.crt' // process.env.NODE_EXTRA_CA_CERTS='C:\\Users\\Administrator\\.dev-sidecar\\dev-sidecar.ca.crt'