bugfix: 修复同一域名不同端口共用fakeServer的Promise的问题
parent
02cbe17935
commit
fb9226cf69
|
@ -1,5 +1,15 @@
|
||||||
const tlsUtils = require('./tlsUtils')
|
const tlsUtils = require('./tlsUtils')
|
||||||
const https = require('https')
|
// const https = require('https')
|
||||||
|
const log = require('../../../utils/util.log')
|
||||||
|
|
||||||
|
function arraysHaveSameElements (arr1, arr2) {
|
||||||
|
if (arr1.length !== arr2.length) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const sortedArr1 = [...arr1].sort()
|
||||||
|
const sortedArr2 = [...arr2].sort()
|
||||||
|
return sortedArr1.every((value, index) => value === sortedArr2[index])
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = class CertAndKeyContainer {
|
module.exports = class CertAndKeyContainer {
|
||||||
constructor ({
|
constructor ({
|
||||||
|
@ -26,6 +36,7 @@ module.exports = class CertAndKeyContainer {
|
||||||
getCertPromise (hostname, port) {
|
getCertPromise (hostname, port) {
|
||||||
for (let i = 0; i < this.queue.length; i++) {
|
for (let i = 0; i < this.queue.length; i++) {
|
||||||
const _certPromiseObj = this.queue[i]
|
const _certPromiseObj = this.queue[i]
|
||||||
|
if (_certPromiseObj.port === port) {
|
||||||
const mappingHostNames = _certPromiseObj.mappingHostNames
|
const mappingHostNames = _certPromiseObj.mappingHostNames
|
||||||
for (let j = 0; j < mappingHostNames.length; j++) {
|
for (let j = 0; j < mappingHostNames.length; j++) {
|
||||||
const DNSName = mappingHostNames[j]
|
const DNSName = mappingHostNames[j]
|
||||||
|
@ -35,8 +46,10 @@ module.exports = class CertAndKeyContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const certPromiseObj = {
|
const certPromiseObj = {
|
||||||
|
port,
|
||||||
mappingHostNames: [hostname] // temporary hostname
|
mappingHostNames: [hostname] // temporary hostname
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,8 +58,13 @@ module.exports = class CertAndKeyContainer {
|
||||||
const _resolve = (_certObj) => {
|
const _resolve = (_certObj) => {
|
||||||
if (once) {
|
if (once) {
|
||||||
once = false
|
once = false
|
||||||
const mappingHostNames = tlsUtils.getMappingHostNamesFromCert(_certObj.cert)
|
let newMappingHostNames = tlsUtils.getMappingHostNamesFromCert(_certObj.cert)
|
||||||
certPromiseObj.mappingHostNames = mappingHostNames // change
|
newMappingHostNames = [...new Set(newMappingHostNames)]
|
||||||
|
|
||||||
|
if (!arraysHaveSameElements(newMappingHostNames, certPromiseObj.mappingHostNames)) {
|
||||||
|
log.info(`【getCertPromise - ${hostname}:${port}】Reset mappingHostNames: `, certPromiseObj.mappingHostNames, '变更为', newMappingHostNames)
|
||||||
|
certPromiseObj.mappingHostNames = newMappingHostNames // change
|
||||||
|
}
|
||||||
resolve(_certObj)
|
resolve(_certObj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,41 +75,41 @@ module.exports = class CertAndKeyContainer {
|
||||||
_resolve(certObj)
|
_resolve(certObj)
|
||||||
} else {
|
} else {
|
||||||
// 这个太慢了
|
// 这个太慢了
|
||||||
const preReq = https.request({
|
// const preReq = https.request({
|
||||||
port: port,
|
// port: port,
|
||||||
hostname: hostname,
|
// hostname: hostname,
|
||||||
path: '/',
|
// path: '/',
|
||||||
method: 'HEAD'
|
// method: 'HEAD'
|
||||||
}, (preRes) => {
|
// }, (preRes) => {
|
||||||
try {
|
// try {
|
||||||
const realCert = preRes.socket.getPeerCertificate()
|
// const realCert = preRes.socket.getPeerCertificate()
|
||||||
if (realCert) {
|
// if (realCert) {
|
||||||
try {
|
// try {
|
||||||
certObj = tlsUtils.createFakeCertificateByCA(this.caKey, this.caCert, realCert)
|
// certObj = tlsUtils.createFakeCertificateByCA(this.caKey, this.caCert, realCert)
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
// certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
// certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
||||||
}
|
// }
|
||||||
_resolve(certObj)
|
// _resolve(certObj)
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
reject(e)
|
// reject(e)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
preReq.setTimeout(~~this.getCertSocketTimeout, () => {
|
// preReq.setTimeout(~~this.getCertSocketTimeout, () => {
|
||||||
if (!certObj) {
|
// if (!certObj) {
|
||||||
certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
// certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
||||||
_resolve(certObj)
|
// _resolve(certObj)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
preReq.on('error', (e) => {
|
// preReq.on('error', (e) => {
|
||||||
if (!certObj) {
|
// if (!certObj) {
|
||||||
certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
// certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
||||||
_resolve(certObj)
|
// _resolve(certObj)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
preReq.end()
|
// preReq.end()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,16 @@ const pki = forge.pki
|
||||||
// const colors = require('colors')
|
// const colors = require('colors')
|
||||||
const tls = require('tls')
|
const tls = require('tls')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
|
|
||||||
|
function arraysHaveSameElements (arr1, arr2) {
|
||||||
|
if (arr1.length !== arr2.length) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const sortedArr1 = [...arr1].sort()
|
||||||
|
const sortedArr2 = [...arr2].sort()
|
||||||
|
return sortedArr1.every((value, index) => value === sortedArr2[index])
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = class FakeServersCenter {
|
module.exports = class FakeServersCenter {
|
||||||
constructor ({ maxLength = 256, requestHandler, upgradeHandler, caCert, caKey, getCertSocketTimeout }) {
|
constructor ({ maxLength = 256, requestHandler, upgradeHandler, caCert, caKey, getCertSocketTimeout }) {
|
||||||
this.queue = []
|
this.queue = []
|
||||||
|
@ -36,6 +46,7 @@ module.exports = class FakeServersCenter {
|
||||||
getServerPromise (hostname, port) {
|
getServerPromise (hostname, port) {
|
||||||
for (let i = 0; i < this.queue.length; i++) {
|
for (let i = 0; i < this.queue.length; i++) {
|
||||||
const serverPromiseObj = this.queue[i]
|
const serverPromiseObj = this.queue[i]
|
||||||
|
if (serverPromiseObj.port === port) {
|
||||||
const mappingHostNames = serverPromiseObj.mappingHostNames
|
const mappingHostNames = serverPromiseObj.mappingHostNames
|
||||||
for (let j = 0; j < mappingHostNames.length; j++) {
|
for (let j = 0; j < mappingHostNames.length; j++) {
|
||||||
const DNSName = mappingHostNames[j]
|
const DNSName = mappingHostNames[j]
|
||||||
|
@ -45,8 +56,10 @@ module.exports = class FakeServersCenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const serverPromiseObj = {
|
const serverPromiseObj = {
|
||||||
|
port,
|
||||||
mappingHostNames: [hostname] // temporary hostname
|
mappingHostNames: [hostname] // temporary hostname
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +88,7 @@ module.exports = class FakeServersCenter {
|
||||||
cert,
|
cert,
|
||||||
key,
|
key,
|
||||||
server: fakeServer,
|
server: fakeServer,
|
||||||
port: 0 // if prot === 0 ,should listen server's `listening` event.
|
port: 0 // if port === 0 ,should listen server's `listening` event.
|
||||||
}
|
}
|
||||||
serverPromiseObj.serverObj = serverObj
|
serverPromiseObj.serverObj = serverObj
|
||||||
|
|
||||||
|
@ -88,14 +101,27 @@ module.exports = class FakeServersCenter {
|
||||||
log.debug(`【fakeServer request - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- res -----\r\n', res)
|
log.debug(`【fakeServer request - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- res -----\r\n', res)
|
||||||
this.requestHandler(req, res, ssl)
|
this.requestHandler(req, res, ssl)
|
||||||
})
|
})
|
||||||
|
let once = true
|
||||||
fakeServer.on('listening', () => {
|
fakeServer.on('listening', () => {
|
||||||
log.debug(`【fakeServer listening - ${hostname}:${port}】no arguments...`)
|
log.debug(`【fakeServer listening - ${hostname}:${port}】no arguments...`)
|
||||||
serverPromiseObj.mappingHostNames = tlsUtils.getMappingHostNamesFromCert(certObj.cert)
|
if (cert && once) {
|
||||||
|
once = false
|
||||||
|
let newMappingHostNames = tlsUtils.getMappingHostNamesFromCert(cert)
|
||||||
|
newMappingHostNames = [...new Set(newMappingHostNames)]
|
||||||
|
if (!arraysHaveSameElements(serverPromiseObj.mappingHostNames, newMappingHostNames)) {
|
||||||
|
log.info(`【fakeServer listening - ${hostname}:${port}】Reset mappingHostNames: `, serverPromiseObj.mappingHostNames, '变更为', newMappingHostNames)
|
||||||
|
serverPromiseObj.mappingHostNames = newMappingHostNames
|
||||||
|
}
|
||||||
|
}
|
||||||
resolve(serverObj)
|
resolve(serverObj)
|
||||||
})
|
})
|
||||||
fakeServer.on('upgrade', (req, socket, head) => {
|
fakeServer.on('upgrade', (req, socket, head) => {
|
||||||
const ssl = true
|
const ssl = true
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
log.debug(`【fakeServer upgrade - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- socket -----\r\n', socket, '\r\n----- head -----\r\n', head)
|
log.debug(`【fakeServer upgrade - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- socket -----\r\n', socket, '\r\n----- head -----\r\n', head)
|
||||||
|
} else {
|
||||||
|
log.info(`【fakeServer upgrade - ${hostname}:${port}】`, req.url)
|
||||||
|
}
|
||||||
this.upgradeHandler(req, socket, head, ssl)
|
this.upgradeHandler(req, socket, head, ssl)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue