mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-05 12:29:44 +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')
|
||||
let byPassRules: string[] = []
|
||||
|
||||
const isByPass = (hostname: string) => {
|
||||
const isByPass = (url: string) => {
|
||||
if (byPassRules.length === 0) {
|
||||
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 {
|
||||
private proxyDispatcher: Dispatcher
|
||||
private directDispatcher: Dispatcher
|
||||
@ -31,9 +59,7 @@ class SelectiveDispatcher extends Dispatcher {
|
||||
|
||||
dispatch(opts: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandlers) {
|
||||
if (opts.origin) {
|
||||
const url = new URL(opts.origin)
|
||||
// 检查是否为 localhost 或本地地址
|
||||
if (isByPass(url.hostname)) {
|
||||
if (isByPass(opts.origin.toString())) {
|
||||
return this.directDispatcher.dispatch(opts, handler)
|
||||
}
|
||||
}
|
||||
@ -93,15 +119,20 @@ export class ProxyManager {
|
||||
// Set new interval
|
||||
this.systemProxyInterval = setInterval(async () => {
|
||||
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
|
||||
}
|
||||
|
||||
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({
|
||||
mode: 'system',
|
||||
proxyRules: currentProxy?.proxyUrl.toLowerCase(),
|
||||
proxyBypassRules: undefined
|
||||
proxyBypassRules: currentProxy?.noProxy.join(',')
|
||||
})
|
||||
}, 1000 * 60)
|
||||
}
|
||||
@ -151,6 +182,7 @@ export class ProxyManager {
|
||||
delete process.env.grpc_proxy
|
||||
delete process.env.http_proxy
|
||||
delete process.env.https_proxy
|
||||
delete process.env.no_proxy
|
||||
|
||||
delete process.env.SOCKS_PROXY
|
||||
delete process.env.ALL_PROXY
|
||||
@ -162,6 +194,7 @@ export class ProxyManager {
|
||||
process.env.HTTPS_PROXY = url
|
||||
process.env.http_proxy = url
|
||||
process.env.https_proxy = url
|
||||
process.env.no_proxy = byPassRules.join(',')
|
||||
|
||||
if (url.startsWith('socks')) {
|
||||
process.env.SOCKS_PROXY = url
|
||||
@ -229,8 +262,7 @@ export class ProxyManager {
|
||||
|
||||
// filter localhost
|
||||
if (url) {
|
||||
const hostname = typeof url === 'string' ? new URL(url).hostname : url.hostname
|
||||
if (isByPass(hostname)) {
|
||||
if (isByPass(url.toString())) {
|
||||
return originalMethod(url, options, callback)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user