bugfix: 修复因 `HttpsAgent` 为单例,导致并发请求时因启用了SSL校验导致 proxy 或 sni 请求失败的问题
parent
6064fe4ab1
commit
bf84613f51
|
@ -116,12 +116,16 @@ module.exports = {
|
|||
}
|
||||
|
||||
if (interceptOpt.sni != null) {
|
||||
let unVerifySsl = rOptions.agent.options.rejectUnauthorized === false
|
||||
|
||||
rOptions.servername = interceptOpt.sni
|
||||
if (rOptions.agent && rOptions.agent.options) {
|
||||
rOptions.agent.options.rejectUnauthorized = false
|
||||
if (rOptions.agent.options.rejectUnauthorized && rOptions.agent.unVerifySslAgent) {
|
||||
// rOptions.agent.options.rejectUnauthorized = false // 不能直接在agent上进行修改属性值,因为它采用了单例模式,所有请求共用这个对象的
|
||||
rOptions.agent = rOptions.agent.unVerifySslAgent
|
||||
unVerifySsl = true
|
||||
}
|
||||
res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}, sni: ${interceptOpt.sni}`)
|
||||
log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget, ', sni replace servername:', rOptions.servername)
|
||||
res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}, sni: ${interceptOpt.sni}`, (unVerifySsl ? ', unVerifySsl' : ''))
|
||||
log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget, ', sni replace servername:', rOptions.servername, (unVerifySsl ? ', unVerifySsl' : ''))
|
||||
} else {
|
||||
res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}`)
|
||||
log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget)
|
||||
|
|
|
@ -4,14 +4,17 @@ module.exports = {
|
|||
requestIntercept (context, interceptOpt, req, res, ssl, next) {
|
||||
const { rOptions, log } = context
|
||||
|
||||
let unVerifySsl = rOptions.agent.options.rejectUnauthorized === false
|
||||
|
||||
rOptions.servername = interceptOpt.sni
|
||||
if (rOptions.agent && rOptions.agent.options) {
|
||||
rOptions.agent.options.rejectUnauthorized = false
|
||||
if (rOptions.agent.options.rejectUnauthorized && rOptions.agent.unVerifySslAgent) {
|
||||
// rOptions.agent.options.rejectUnauthorized = false // 不能直接在agent上进行修改属性值,因为它采用了单例模式,所有请求共用这个对象的
|
||||
rOptions.agent = rOptions.agent.unVerifySslAgent
|
||||
unVerifySsl = true
|
||||
}
|
||||
res.setHeader('DS-Interceptor', `sni: ${interceptOpt.sni}`, (unVerifySsl ? ', unVerifySsl' : ''))
|
||||
|
||||
res.setHeader('DS-Interceptor', 'sni: ' + interceptOpt.sni)
|
||||
|
||||
log.info('sni intercept: sni replace servername:', rOptions.hostname, '➜', rOptions.servername)
|
||||
log.info('sni intercept: sni replace servername:', rOptions.hostname, '➜', rOptions.servername, (unVerifySsl ? ', unVerifySsl' : ''))
|
||||
return true
|
||||
},
|
||||
is (interceptOpt) {
|
||||
|
|
|
@ -24,15 +24,27 @@ function getTimeoutConfig (hostname, serverSetting) {
|
|||
}
|
||||
}
|
||||
|
||||
function createHttpsAgent (timeoutConfig) {
|
||||
function createHttpsAgent (timeoutConfig, verifySsl) {
|
||||
const key = timeoutConfig.timeout + '-' + timeoutConfig.keepAliveTimeout
|
||||
if (!httpsAgentCache[key]) {
|
||||
httpsAgentCache[key] = new HttpsAgent({
|
||||
verifySsl = !!verifySsl
|
||||
|
||||
const agent = new HttpsAgent({
|
||||
keepAlive: true,
|
||||
timeout: timeoutConfig.timeout,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout,
|
||||
rejectUnauthorized: verifySsl
|
||||
})
|
||||
|
||||
agent.unVerifySslAgent = new HttpsAgent({
|
||||
keepAlive: true,
|
||||
timeout: timeoutConfig.timeout,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout,
|
||||
rejectUnauthorized: false
|
||||
})
|
||||
|
||||
httpsAgentCache[key] = agent
|
||||
log.info('创建 HttpsAgent 成功, timeoutConfig:', timeoutConfig, ', verifySsl:', verifySsl)
|
||||
}
|
||||
return httpsAgentCache[key]
|
||||
}
|
||||
|
@ -45,13 +57,14 @@ function createHttpAgent (timeoutConfig) {
|
|||
timeout: timeoutConfig.timeout,
|
||||
keepAliveTimeout: timeoutConfig.keepAliveTimeout
|
||||
})
|
||||
log.info('创建 HttpsAgent 成功, timeoutConfig:', timeoutConfig)
|
||||
}
|
||||
return httpAgentCache[key]
|
||||
}
|
||||
|
||||
function createAgent (protocol, timeoutConfig) {
|
||||
function createAgent (protocol, timeoutConfig, verifySsl) {
|
||||
return protocol === 'https:'
|
||||
? createHttpsAgent(timeoutConfig)
|
||||
? createHttpsAgent(timeoutConfig, verifySsl)
|
||||
: createHttpAgent(timeoutConfig)
|
||||
}
|
||||
|
||||
|
@ -110,7 +123,7 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null, serverSetting) =>
|
|||
if (headers.connection !== 'close') {
|
||||
const timeoutConfig = getTimeoutConfig(hostname, serverSetting)
|
||||
// log.info(`get timeoutConfig '${hostname}':`, timeoutConfig)
|
||||
agent = createAgent(protocol, timeoutConfig)
|
||||
agent = createAgent(protocol, timeoutConfig, serverSetting.verifySsl)
|
||||
headers.connection = 'keep-alive'
|
||||
} else {
|
||||
agent = false
|
||||
|
|
|
@ -18,12 +18,6 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
|||
const rOptions = commonUtil.getOptionsFromRequest(req, ssl, externalProxy, setting)
|
||||
let url = `${rOptions.method} ➜ ${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`
|
||||
|
||||
if (rOptions.agent) {
|
||||
rOptions.agent.options.rejectUnauthorized = setting.verifySsl
|
||||
} else if (rOptions.agent !== false) {
|
||||
log.error('rOptions.agent 的值有问题:', rOptions)
|
||||
}
|
||||
|
||||
if (rOptions.headers.connection === 'close') {
|
||||
req.socket.setKeepAlive(false)
|
||||
} else if (rOptions.customSocketId != null) { // for NTLM
|
||||
|
|
Loading…
Reference in New Issue