@@ -2,21 +2,25 @@ const http = require('node:http')
22const https = require ( 'node:https' )
33const tls = require ( 'node:tls' )
44const forge = require ( 'node-forge' )
5+ const LRUCache = require ( 'lru-cache' )
56const CertAndKeyContainer = require ( './CertAndKeyContainer' )
6- const tlsUtils = require ( './tlsUtils' )
77const log = require ( '../../../utils/util.log.server' )
88const compatible = require ( '../compatible/compatible' )
99
1010const pki = forge . pki
1111
12+ // IPv4地址检测正则,提前编译,避免在 getDnsName 中重复创建。
13+ // 不使用 /g 标志:此处只做存在性检测(.test()),无需记录 lastIndex 状态。
14+ const IPv4_RE = / \b (?: 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] \d | 1 \d { 2 } | [ 1 - 9 ] \d | \d ) (?: \. (?: 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] \d | 1 \d { 2 } | [ 1 - 9 ] \d | \d ) \b ) { 3 } /
15+
1216// 获取DNS名称
1317function getDnsName ( hostname ) {
1418 if ( ! hostname . includes ( '.' ) ) {
1519 return hostname // 可能是IPv6地址,直接返回
1620 }
1721
1822 // 判断是否为IP
19- if ( hostname . match ( / \b ( 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] \d | 1 \d { 2 } | [ 1 - 9 ] \d | \d ) ( \. ( 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] \d | 1 \d { 2 } | [ 1 - 9 ] \d | \d ) \b ) { 3 } / g ) ) {
23+ if ( IPv4_RE . test ( hostname ) ) {
2024 return hostname // 为IP,直接返回
2125 }
2226
@@ -29,31 +33,43 @@ function getDnsName (hostname) {
2933 return `*${ hostname . substring ( hostname . indexOf ( '.' ) ) } `
3034}
3135
36+ const DEFAULT_MAX_LENGTH = 256
37+
3238module . exports = class FakeServersCenter {
33- constructor ( { maxLength = 256 , requestHandler, upgradeHandler, caCert, caKey, getCertSocketTimeout } ) {
34- this . queue = [ ]
35- this . maxLength = maxLength
39+ constructor ( {
40+ maxLength = DEFAULT_MAX_LENGTH ,
41+ requestHandler,
42+ upgradeHandler,
43+ caCert,
44+ caKey,
45+ } ) {
46+ // 缓存键格式:`${dnsName}:${port}:${ssl}`
47+ this . cache = new LRUCache ( {
48+ maxSize : maxLength > 0 ? maxLength : DEFAULT_MAX_LENGTH ,
49+ sizeCalculation : ( ) => {
50+ return 1
51+ } ,
52+ dispose : ( evictServerPromiseObj , evictDnsName ) => {
53+ try {
54+ evictServerPromiseObj . serverObj . server . close ( )
55+ log . info ( `旧fake服务缓存被移除,停止服务成功,${ evictDnsName } ` )
56+ } catch ( e ) {
57+ log . error ( `旧fake服务缓存被移除,但停止服务失败,${ evictDnsName } ->` , evictServerPromiseObj , `, error:` , e )
58+ }
59+ } ,
60+ } )
3661 this . requestHandler = requestHandler
3762 this . upgradeHandler = upgradeHandler
3863 this . certAndKeyContainer = new CertAndKeyContainer ( {
39- getCertSocketTimeout ,
64+ maxLength : maxLength > 0 ? maxLength : DEFAULT_MAX_LENGTH ,
4065 caCert,
4166 caKey,
4267 } )
4368 }
4469
4570 addServerPromise ( serverPromiseObj ) {
46- if ( this . queue . length >= this . maxLength ) {
47- const delServerObj = this . queue . shift ( )
48- try {
49- log . info ( `超过最大服务数量${ this . maxLength } ,删除旧服务。delServerObj:` , delServerObj )
50- delServerObj . serverObj . server . close ( )
51- } catch ( e ) {
52- log . error ( '`delServerObj.serverObj.server.close()` error:' , e )
53- }
54- }
55- this . queue . push ( serverPromiseObj )
56- return serverPromiseObj
71+ // 添加缓存
72+ this . cache . set ( serverPromiseObj . cacheKey , serverPromiseObj )
5773 }
5874
5975 getServerPromise ( hostname , port , ssl , manualCompatibleConfig ) {
@@ -69,28 +85,22 @@ module.exports = class FakeServersCenter {
6985
7086 log . info ( `getServerPromise, hostname: ${ hostname } :${ port } , ssl: ${ ssl } , protocol: ${ ssl ? 'https' : 'http' } ` )
7187
72- for ( let i = this . queue . length - 1 ; i >= 0 ; i -- ) {
73- const serverPromiseObj = this . queue [ i ]
74- if ( serverPromiseObj . port === port && serverPromiseObj . ssl === ssl ) {
75- const mappingHostNames = serverPromiseObj . mappingHostNames
76- for ( let j = 0 ; j < mappingHostNames . length ; j ++ ) {
77- const DNSName = mappingHostNames [ j ]
78- if ( tlsUtils . isMappingHostName ( DNSName , hostname ) ) {
79- this . reRankServer ( i )
80- log . info ( `Load fakeServerPromise from cache, hostname: ${ hostname } :${ port } , ssl: ${ ssl } , serverPromiseObj: {"ssl":${ serverPromiseObj . ssl } ,"port":${ serverPromiseObj . port } ,"mappingHostNames":${ JSON . stringify ( serverPromiseObj . mappingHostNames ) } }` )
81- return serverPromiseObj . promise
82- }
83- }
84- }
88+ const dnsName = getDnsName ( hostname )
89+ const cacheKey = `${ dnsName } :${ port } :${ ssl } `
90+
91+ const cachedServerObj = this . cache . get ( cacheKey )
92+ if ( cachedServerObj ) {
93+ log . info ( `Load fakeServerPromise from cache, hostname: ${ hostname } :${ port } , ssl: ${ ssl } , serverPromiseObj: {"ssl":${ cachedServerObj . ssl } ,"port":${ cachedServerObj . port } ,"mappingHostNames":${ JSON . stringify ( cachedServerObj . mappingHostNames ) } }` )
94+ return cachedServerObj . promise
8595 }
8696
87- const dnsName = getDnsName ( hostname )
8897 const mappingHostNames = [ dnsName ]
8998 if ( dnsName . startsWith ( '*.' ) ) {
9099 mappingHostNames . push ( dnsName . replace ( '*.' , '' ) )
91100 }
92101
93102 const serverPromiseObj = {
103+ cacheKey,
94104 port,
95105 ssl,
96106 mappingHostNames,
@@ -228,9 +238,4 @@ module.exports = class FakeServersCenter {
228238
229239 return promise
230240 }
231-
232- reRankServer ( index ) {
233- // index ==> queue foot
234- this . queue . push ( ( this . queue . splice ( index , 1 ) ) [ 0 ] )
235- }
236241}
0 commit comments