Files
orca/src/main/network/proxy-settings.ts
T
2026-05-31 05:55:04 -07:00

126 lines
3.7 KiB
TypeScript

import { session } from 'electron'
import {
getProxyBypassRulesFromEnvironment,
getProxyUrlFromEnvironment,
normalizeProxyBypassRules,
normalizeProxyUrl,
type NetworkProxySettings
} from '../../shared/network-proxy'
type ProxySession = {
resolveProxy(url: string): Promise<string>
setProxy(config: {
mode?: 'system' | 'fixed_servers'
proxyRules?: string
proxyBypassRules?: string
}): Promise<void>
closeAllConnections?: () => Promise<void>
}
export type ProxyApplyResult =
| { source: 'settings'; proxyRules: string; proxyBypassRules?: string }
| { source: 'env'; proxyRules: string; proxyBypassRules?: string }
| { source: 'system' | 'none' | 'invalid-settings' | 'invalid-env' }
const PROXY_PROBE_URL = 'https://api.anthropic.com/'
let lastAppliedProxyConfig: Extract<ProxyApplyResult, { source: 'settings' | 'env' }> | null = null
async function setSessionProxy(
proxySession: ProxySession,
config: Parameters<ProxySession['setProxy']>[0]
): Promise<void> {
await proxySession.setProxy(config)
await proxySession.closeAllConnections?.()
}
export function resetProxyApplicationForTests(): void {
lastAppliedProxyConfig = null
}
export async function ensureElectronProxyFromEnvironment(
options: {
proxySession?: ProxySession
env?: Record<string, string | undefined>
force?: boolean
probeUrl?: string
} = {}
): Promise<ProxyApplyResult> {
if (!options.force && lastAppliedProxyConfig !== null) {
return lastAppliedProxyConfig
}
const proxySession = options.proxySession ?? session.defaultSession
const resolved = await proxySession.resolveProxy(options.probeUrl ?? PROXY_PROBE_URL)
if (resolved !== 'DIRECT') {
return { source: 'system' }
}
const proxy = getProxyUrlFromEnvironment(options.env ?? process.env)
if (!proxy.ok) {
return { source: 'invalid-env' }
}
if (!proxy.value) {
return { source: 'none' }
}
const bypassRules = getProxyBypassRulesFromEnvironment(options.env ?? process.env)
await setSessionProxy(proxySession, {
mode: 'fixed_servers',
proxyRules: proxy.value,
...(bypassRules ? { proxyBypassRules: bypassRules } : {})
})
lastAppliedProxyConfig = {
source: 'env',
proxyRules: proxy.value,
...(bypassRules ? { proxyBypassRules: bypassRules } : {})
}
return lastAppliedProxyConfig
}
export async function applyElectronProxySettings(
settings: NetworkProxySettings,
options: {
proxySession?: ProxySession
env?: Record<string, string | undefined>
probeUrl?: string
} = {}
): Promise<ProxyApplyResult> {
const proxySession = options.proxySession ?? session.defaultSession
const proxy = normalizeProxyUrl(settings.httpProxyUrl)
if (!proxy.ok) {
return ensureElectronProxyFromEnvironment({
proxySession,
env: options.env,
force: lastAppliedProxyConfig !== null,
probeUrl: options.probeUrl
}).then((result) => (result.source === 'none' ? { source: 'invalid-settings' } : result))
}
if (proxy.value) {
const bypassRules = normalizeProxyBypassRules(settings.httpProxyBypassRules)
await setSessionProxy(proxySession, {
mode: 'fixed_servers',
proxyRules: proxy.value,
...(bypassRules ? { proxyBypassRules: bypassRules } : {})
})
lastAppliedProxyConfig = {
source: 'settings',
proxyRules: proxy.value,
...(bypassRules ? { proxyBypassRules: bypassRules } : {})
}
return lastAppliedProxyConfig
}
if (lastAppliedProxyConfig !== null) {
await setSessionProxy(proxySession, { mode: 'system' })
lastAppliedProxyConfig = null
}
return ensureElectronProxyFromEnvironment({
proxySession,
env: options.env,
force: true,
probeUrl: options.probeUrl
})
}