feature: 指定域名的请求超时时间和连接超时时间可配置化。
parent
9d12aa4516
commit
497c199084
|
@ -44,8 +44,6 @@ module.exports = {
|
|||
setting: {
|
||||
NODE_TLS_REJECT_UNAUTHORIZED: true,
|
||||
verifySsl: true,
|
||||
timeout: 20000, // 代理请求超时时间
|
||||
keepAliveTimeout: 30000, // socket连接的超时时间
|
||||
script: {
|
||||
enabled: true,
|
||||
defaultDir: './extra/scripts/'
|
||||
|
@ -54,6 +52,18 @@ module.exports = {
|
|||
rootCaFile: {
|
||||
certPath: getRootCaCertPath(),
|
||||
keyPath: getRootCaKeyPath()
|
||||
},
|
||||
|
||||
// 默认超时时间配置
|
||||
defaultTimeout: 20000, // 请求超时时间
|
||||
defaultKeepAliveTimeout: 30000, // 连接超时时间
|
||||
|
||||
// 指定域名超时时间配置
|
||||
timeoutMapping: {
|
||||
'github.com': {
|
||||
timeout: 20000,
|
||||
keepAliveTimeout: 30000
|
||||
}
|
||||
}
|
||||
},
|
||||
intercept: {
|
||||
|
|
|
@ -37,13 +37,6 @@
|
|||
<div class="form-help">修改后需要重启应用</div>
|
||||
</a-form-item>
|
||||
<hr/>
|
||||
<a-form-item label="请求超时时间" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
<a-input-number v-model="config.server.setting.timeout" :step="1000" :min="1000"/> ms,对应 timeout 属性
|
||||
</a-form-item>
|
||||
<a-form-item label="连接超时时间" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
<a-input-number v-model="config.server.setting.keepAliveTimeout" :step="1000" :min="1000"/> ms,对应 keepAliveTimeout 属性
|
||||
</a-form-item>
|
||||
<hr/>
|
||||
<a-form-item label="全局校验SSL" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
<a-checkbox v-model="config.server.setting.NODE_TLS_REJECT_UNAUTHORIZED">
|
||||
NODE_TLS_REJECT_UNAUTHORIZED
|
||||
|
@ -81,7 +74,19 @@
|
|||
<vue-json-editor style="height:100%;" ref="editor" v-model="config.server.intercepts" mode="code"
|
||||
:show-btns="false" :expandedOnStart="true"></vue-json-editor>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="域名白名单" key="3">
|
||||
<a-tab-pane tab="超时时间设置" key="3">
|
||||
<div style="height:100%;display:flex;flex-direction:column;padding-right:10px">
|
||||
<a-form-item label="默认超时时间" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
请求:<a-input-number v-model="config.server.setting.defaultTimeout" :step="1000" :min="1000"/> ms,对应 timeout 属性<br/>
|
||||
连接:<a-input-number v-model="config.server.setting.defaultKeepAliveTimeout" :step="1000" :min="1000"/> ms,对应 keepAliveTimeout 属性
|
||||
</a-form-item>
|
||||
<hr/>
|
||||
<div>这里指定域名的超时时间:<span class="form-help">(以下github的配置为示例,预计将在 1.8.7 版本删除)</span></div>
|
||||
<vue-json-editor style="flex-grow:1;min-height:300px;margin-top:10px" ref="editor" v-model="config.server.setting.timeoutMapping" mode="code"
|
||||
:show-btns="false" :expandedOnStart="true"></vue-json-editor>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="域名白名单" key="4">
|
||||
<a-row style="margin-top:10px">
|
||||
<a-col span="19">
|
||||
<div>这里配置哪些域名不需要通过代理</div>
|
||||
|
@ -99,16 +104,18 @@
|
|||
</a-col>
|
||||
</a-row>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="IP预设置" key="4">
|
||||
<div>注意:IP预设置功能,需要与 `DNS设置` 或 `IP测速` 功能一起使用才会生效。</div>
|
||||
<vue-json-editor style="height:94%;margin-top:10px;" ref="editor" v-model="config.server.preSetIpList" mode="code"
|
||||
:show-btns="false" :expandedOnStart="true"></vue-json-editor>
|
||||
<a-tab-pane tab="IP预设置" key="5">
|
||||
<div style="height:100%;display:flex;flex-direction:column">
|
||||
<div>注意:IP预设置功能,需要与 `DNS设置` 或 `IP测速` 功能一起使用才会生效。</div>
|
||||
<vue-json-editor style="flex-grow:1;min-height:300px;margin-top:10px;" ref="editor" v-model="config.server.preSetIpList" mode="code"
|
||||
:show-btns="false" :expandedOnStart="true"></vue-json-editor>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="DNS服务管理" key="5">
|
||||
<a-tab-pane tab="DNS服务管理" key="6">
|
||||
<vue-json-editor style="height:100%;" ref="editor" v-model="config.server.dns.providers" mode="code"
|
||||
:show-btns="false" :expandedOnStart="true"></vue-json-editor>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="DNS设置" key="6">
|
||||
<a-tab-pane tab="DNS设置" key="7">
|
||||
<div>
|
||||
<a-row style="margin-top:10px">
|
||||
<a-col span="19">
|
||||
|
@ -136,7 +143,7 @@
|
|||
</a-row>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="IP测速" key="7">
|
||||
<a-tab-pane tab="IP测速" key="8">
|
||||
<div class="ip-tester" style="padding-right: 10px">
|
||||
<a-alert type="info" message="对从dns获取到的ip进行测速,使用速度最快的ip进行访问。(对使用增强功能的域名没啥用)"></a-alert>
|
||||
<a-form-item label="开启dns测速" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
|
@ -375,7 +382,7 @@ export default {
|
|||
}, 5000)
|
||||
},
|
||||
async handleTabChange (key) {
|
||||
if (key !== '2' && key !== '4' && key !== '5') {
|
||||
if (key !== '2' && key !== '3' && key !== '5' && key !== '6') {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -3,18 +3,9 @@ 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 util = exports
|
||||
const httpsAgent = new HttpsAgent({
|
||||
keepAlive: true,
|
||||
timeout: 20000,
|
||||
keepAliveTimeout: 30000, // free socket keepalive for 30 seconds
|
||||
rejectUnauthorized: false
|
||||
})
|
||||
const httpAgent = new Agent({
|
||||
keepAlive: true,
|
||||
timeout: 20000,
|
||||
keepAliveTimeout: 30000 // free socket keepalive for 30 seconds
|
||||
})
|
||||
|
||||
const httpsAgentCache = {}
|
||||
const httpAgentCache = {}
|
||||
|
||||
|
@ -22,41 +13,46 @@ let socketId = 0
|
|||
|
||||
let httpsOverHttpAgent, httpOverHttpsAgent, httpsOverHttpsAgent
|
||||
|
||||
function createHttpsAgent (serverSetting) {
|
||||
const key = (serverSetting.timeout || 20000) + '-' + (serverSetting.keepAliveTimeout || 30000)
|
||||
function getTimeoutConfig (hostname, serverSetting) {
|
||||
const timeoutMapping = serverSetting.timeoutMapping
|
||||
|
||||
const timeoutConfig = matchUtil.matchHostname(timeoutMapping, hostname, 'get timeoutConfig') || {}
|
||||
|
||||
return {
|
||||
timeout: timeoutConfig.timeout || serverSetting.defaultTimeout || 20000,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout || serverSetting.defaultKeepAliveTimeout || 30000
|
||||
}
|
||||
}
|
||||
|
||||
function createHttpsAgent (timeoutConfig) {
|
||||
const key = timeoutConfig.timeout + '-' + timeoutConfig.keepAliveTimeout
|
||||
if (!httpsAgentCache[key]) {
|
||||
httpsAgentCache[key] = new HttpsAgent({
|
||||
keepAlive: true,
|
||||
timeout: serverSetting.timeout || 20000,
|
||||
keepAliveTimeout: serverSetting.keepAliveTimeout || 30000,
|
||||
timeout: timeoutConfig.timeout,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout,
|
||||
rejectUnauthorized: false
|
||||
})
|
||||
}
|
||||
return httpsAgentCache[key]
|
||||
}
|
||||
|
||||
function createHttpAgent (serverSetting) {
|
||||
const key = (serverSetting.timeout || 20000) + '-' + (serverSetting.keepAliveTimeout || 30000)
|
||||
function createHttpAgent (timeoutConfig) {
|
||||
const key = timeoutConfig.timeout + '-' + timeoutConfig.keepAliveTimeout
|
||||
if (!httpAgentCache[key]) {
|
||||
httpAgentCache[key] = new Agent({
|
||||
keepAlive: true,
|
||||
timeout: serverSetting.timeout || 20000,
|
||||
keepAliveTimeout: serverSetting.keepAliveTimeout || 30000
|
||||
timeout: timeoutConfig.timeout,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout
|
||||
})
|
||||
}
|
||||
return httpAgentCache[key]
|
||||
}
|
||||
|
||||
function createAgent (protocol, serverSetting) {
|
||||
if (protocol === 'https:') {
|
||||
return !serverSetting || (serverSetting.timeout === 20000 && serverSetting.keepAliveTimeout === 30000)
|
||||
? httpsAgent
|
||||
: createHttpsAgent(serverSetting)
|
||||
} else {
|
||||
return !serverSetting || (serverSetting.timeout === 20000 && serverSetting.keepAliveTimeout === 30000)
|
||||
? httpAgent
|
||||
: createHttpAgent(serverSetting)
|
||||
}
|
||||
function createAgent (protocol, timeoutConfig) {
|
||||
return protocol === 'https:'
|
||||
? createHttpsAgent(timeoutConfig)
|
||||
: createHttpAgent(timeoutConfig)
|
||||
}
|
||||
|
||||
util.parseHostnameAndPort = (host, defaultPort) => {
|
||||
|
@ -102,12 +98,19 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null, serverSetting) =>
|
|||
}
|
||||
}
|
||||
|
||||
// 解析host和port
|
||||
const arr = util.parseHostnameAndPort(req.headers.host)
|
||||
const hostname = arr[0]
|
||||
const port = arr[1] || defaultPort
|
||||
|
||||
delete headers['proxy-connection']
|
||||
let agent
|
||||
if (!externalProxyUrl) {
|
||||
// keepAlive
|
||||
if (headers.connection !== 'close') {
|
||||
agent = createAgent(protocol, serverSetting)
|
||||
const timeoutConfig = getTimeoutConfig(hostname, serverSetting)
|
||||
// log.info(`get timeoutConfig: hostname: ${hostname}, timeoutConfig:`, timeoutConfig)
|
||||
agent = createAgent(protocol, timeoutConfig)
|
||||
headers.connection = 'keep-alive'
|
||||
} else {
|
||||
agent = false
|
||||
|
@ -116,19 +119,16 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null, serverSetting) =>
|
|||
agent = util.getTunnelAgent(protocol === 'https:', externalProxyUrl)
|
||||
}
|
||||
|
||||
// 解析host和port
|
||||
const arr = util.parseHostnameAndPort(req.headers.host)
|
||||
|
||||
// 初始化options
|
||||
const options = {
|
||||
protocol: protocol,
|
||||
protocol,
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
hostname: arr[0],
|
||||
port: arr[1] || defaultPort,
|
||||
hostname,
|
||||
port,
|
||||
path: urlObject.path,
|
||||
headers: req.headers,
|
||||
agent: agent
|
||||
agent
|
||||
}
|
||||
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
|
|
|
@ -48,6 +48,16 @@ function loadPacLastModifiedTime (pacTxt) {
|
|||
}
|
||||
}
|
||||
|
||||
function formatDate (date) {
|
||||
const year = date.getFullYear()
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
||||
const day = date.getDate().toString().padStart(2, '0')
|
||||
const hours = date.getHours().toString().padStart(2, '0')
|
||||
const minutes = date.getMinutes().toString().padStart(2, '0')
|
||||
const seconds = date.getSeconds().toString().padStart(2, '0')
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||||
}
|
||||
|
||||
// 保存 pac 内容到 `~/pac.txt` 文件中
|
||||
function savePacFile (pacTxt) {
|
||||
const pacFilePath = getTmpPacFilePath()
|
||||
|
@ -68,7 +78,7 @@ function savePacFile (pacTxt) {
|
|||
if (utimesErr) {
|
||||
log.error('修改 pac.txt 文件时间失败:', utimesErr)
|
||||
} else {
|
||||
log.info(`${pacFilePath} 文件时间已被修改其最近更新时间 '${lastModifiedTime}'`)
|
||||
log.info(`'${pacFilePath}' 文件的修改时间已更新为其最近更新时间 '${formatDate(lastModifiedTime)}'`)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -5,10 +5,10 @@ const log = require('../../../utils/util.log')
|
|||
// copy from node-http-proxy. ^_^
|
||||
|
||||
// create connectHandler function
|
||||
module.exports = function createUpgradeHandler () {
|
||||
module.exports = function createUpgradeHandler (serverSetting) {
|
||||
// return
|
||||
return function upgradeHandler (req, cltSocket, head, ssl) {
|
||||
const clientOptions = util.getOptionsFromRequest(req, ssl)
|
||||
const clientOptions = util.getOptionsFromRequest(req, ssl, null, serverSetting)
|
||||
const proxyReq = (ssl ? https : http).request(clientOptions)
|
||||
proxyReq.on('error', (e) => {
|
||||
log.error('upgradeHandler error:', e)
|
||||
|
|
|
@ -60,7 +60,7 @@ module.exports = {
|
|||
setting
|
||||
)
|
||||
|
||||
const upgradeHandler = createUpgradeHandler()
|
||||
const upgradeHandler = createUpgradeHandler(setting)
|
||||
|
||||
const fakeServersCenter = createFakeServerCenter({
|
||||
caCertPath,
|
||||
|
|
|
@ -19,6 +19,7 @@ function buildIntercepts (intercepts) {
|
|||
module.exports = (serverConfig) => {
|
||||
const intercepts = matchUtil.domainMapRegexply(buildIntercepts(serverConfig.intercepts))
|
||||
const whiteList = matchUtil.domainMapRegexply(serverConfig.whiteList)
|
||||
const timeoutMapping = matchUtil.domainMapRegexply(serverConfig.setting.timeoutMapping)
|
||||
|
||||
const dnsMapping = serverConfig.dns.mapping
|
||||
const setting = serverConfig.setting
|
||||
|
@ -29,6 +30,7 @@ module.exports = (serverConfig) => {
|
|||
if (setting.verifySsl !== false) {
|
||||
setting.verifySsl = true
|
||||
}
|
||||
setting.timeoutMapping = timeoutMapping
|
||||
|
||||
const overWallConfig = serverConfig.plugin.overwall
|
||||
if (overWallConfig.pac && overWallConfig.pac.enabled) {
|
||||
|
|
Loading…
Reference in New Issue