mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-07 05:39:05 +08:00
refactor(ProxyManager): enhance bypass rule matching and logging (#9546)
* refactor(ProxyManager): enhance bypass rule matching and logging - Updated the `isByPass` function to improve hostname and port matching against bypass rules. - Refactored the dispatcher logic to utilize the updated `isByPass` function for better clarity. - Enhanced logging to include bypass rules in system proxy change notifications. - Simplified URL handling in the dispatcher to ensure consistent behavior. * delete file * refactor(ProxyManager): improve bypass rule handling and error logging - Enhanced the `isByPass` function to check for bypass rules more efficiently, including improved error handling and logging for rule parsing failures. - Added error logging for exceptions during URL processing. - Cleaned up the logic to ensure consistent return values and better readability. - Removed unnecessary environment variable deletions in the proxy manager cleanup process. * feat(ProxyManager): add no_proxy environment variable support - Introduced the `no_proxy` environment variable to allow bypassing specific hosts in proxy settings. - The `no_proxy` value is constructed from the existing bypass rules, enhancing flexibility in proxy management.
This commit is contained in:
parent
eac71f1f43
commit
5bbc35695a
@ -11,14 +11,42 @@ import { Dispatcher, EnvHttpProxyAgent, getGlobalDispatcher, setGlobalDispatcher
|
|||||||
const logger = loggerService.withContext('ProxyManager')
|
const logger = loggerService.withContext('ProxyManager')
|
||||||
let byPassRules: string[] = []
|
let byPassRules: string[] = []
|
||||||
|
|
||||||
const isByPass = (hostname: string) => {
|
const isByPass = (url: string) => {
|
||||||
if (byPassRules.length === 0) {
|
if (byPassRules.length === 0) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return byPassRules.includes(hostname)
|
try {
|
||||||
}
|
const subjectUrlTokens = new URL(url)
|
||||||
|
for (const rule of byPassRules) {
|
||||||
|
const ruleMatch = rule.replace(/^(?<leadingDot>\.)/, '*').match(/^(?<hostname>.+?)(?::(?<port>\d+))?$/)
|
||||||
|
|
||||||
|
if (!ruleMatch || !ruleMatch.groups) {
|
||||||
|
logger.warn('Failed to parse bypass rule:', { rule })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ruleMatch.groups.hostname) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const hostnameIsMatch = subjectUrlTokens.hostname === ruleMatch.groups.hostname
|
||||||
|
|
||||||
|
if (
|
||||||
|
hostnameIsMatch &&
|
||||||
|
(!ruleMatch.groups ||
|
||||||
|
!ruleMatch.groups.port ||
|
||||||
|
(subjectUrlTokens.port && subjectUrlTokens.port === ruleMatch.groups.port))
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Failed to check bypass:', error as Error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
class SelectiveDispatcher extends Dispatcher {
|
class SelectiveDispatcher extends Dispatcher {
|
||||||
private proxyDispatcher: Dispatcher
|
private proxyDispatcher: Dispatcher
|
||||||
private directDispatcher: Dispatcher
|
private directDispatcher: Dispatcher
|
||||||
@ -31,9 +59,7 @@ class SelectiveDispatcher extends Dispatcher {
|
|||||||
|
|
||||||
dispatch(opts: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandlers) {
|
dispatch(opts: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandlers) {
|
||||||
if (opts.origin) {
|
if (opts.origin) {
|
||||||
const url = new URL(opts.origin)
|
if (isByPass(opts.origin.toString())) {
|
||||||
// 检查是否为 localhost 或本地地址
|
|
||||||
if (isByPass(url.hostname)) {
|
|
||||||
return this.directDispatcher.dispatch(opts, handler)
|
return this.directDispatcher.dispatch(opts, handler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,15 +119,20 @@ export class ProxyManager {
|
|||||||
// Set new interval
|
// Set new interval
|
||||||
this.systemProxyInterval = setInterval(async () => {
|
this.systemProxyInterval = setInterval(async () => {
|
||||||
const currentProxy = await getSystemProxy()
|
const currentProxy = await getSystemProxy()
|
||||||
if (currentProxy?.proxyUrl.toLowerCase() === this.config?.proxyRules) {
|
if (
|
||||||
|
currentProxy?.proxyUrl.toLowerCase() === this.config?.proxyRules &&
|
||||||
|
currentProxy?.noProxy.join(',').toLowerCase() === this.config?.proxyBypassRules?.toLowerCase()
|
||||||
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`system proxy changed: ${currentProxy?.proxyUrl}, this.config.proxyRules: ${this.config.proxyRules}`)
|
logger.info(
|
||||||
|
`system proxy changed: ${currentProxy?.proxyUrl}, this.config.proxyRules: ${this.config.proxyRules}, this.config.proxyBypassRules: ${this.config.proxyBypassRules}`
|
||||||
|
)
|
||||||
await this.configureProxy({
|
await this.configureProxy({
|
||||||
mode: 'system',
|
mode: 'system',
|
||||||
proxyRules: currentProxy?.proxyUrl.toLowerCase(),
|
proxyRules: currentProxy?.proxyUrl.toLowerCase(),
|
||||||
proxyBypassRules: undefined
|
proxyBypassRules: currentProxy?.noProxy.join(',')
|
||||||
})
|
})
|
||||||
}, 1000 * 60)
|
}, 1000 * 60)
|
||||||
}
|
}
|
||||||
@ -151,6 +182,7 @@ export class ProxyManager {
|
|||||||
delete process.env.grpc_proxy
|
delete process.env.grpc_proxy
|
||||||
delete process.env.http_proxy
|
delete process.env.http_proxy
|
||||||
delete process.env.https_proxy
|
delete process.env.https_proxy
|
||||||
|
delete process.env.no_proxy
|
||||||
|
|
||||||
delete process.env.SOCKS_PROXY
|
delete process.env.SOCKS_PROXY
|
||||||
delete process.env.ALL_PROXY
|
delete process.env.ALL_PROXY
|
||||||
@ -162,6 +194,7 @@ export class ProxyManager {
|
|||||||
process.env.HTTPS_PROXY = url
|
process.env.HTTPS_PROXY = url
|
||||||
process.env.http_proxy = url
|
process.env.http_proxy = url
|
||||||
process.env.https_proxy = url
|
process.env.https_proxy = url
|
||||||
|
process.env.no_proxy = byPassRules.join(',')
|
||||||
|
|
||||||
if (url.startsWith('socks')) {
|
if (url.startsWith('socks')) {
|
||||||
process.env.SOCKS_PROXY = url
|
process.env.SOCKS_PROXY = url
|
||||||
@ -229,8 +262,7 @@ export class ProxyManager {
|
|||||||
|
|
||||||
// filter localhost
|
// filter localhost
|
||||||
if (url) {
|
if (url) {
|
||||||
const hostname = typeof url === 'string' ? new URL(url).hostname : url.hostname
|
if (isByPass(url.toString())) {
|
||||||
if (isByPass(hostname)) {
|
|
||||||
return originalMethod(url, options, callback)
|
return originalMethod(url, options, callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user