refactor: 拆分 proxy.go 为平台特定文件,兼容 macOS 和 Linux\n\n- proxy.go: 保留通用类型和辅助函数\n- proxy_windows.go: 通过注册表读取 Windows 系统代理\n- proxy_darwin.go: 通过 scutil --proxy 读取 macOS 系统代理\n- proxy_linux.go: 通过 gsettings/kreadconfig 读取 Linux 系统代理"

This commit is contained in:
zyj
2026-03-10 11:55:34 +08:00
parent 6e0becb748
commit cb6b21ef98
4 changed files with 259 additions and 53 deletions

View File

@@ -4,8 +4,6 @@ import (
"fmt"
"os"
"strings"
"golang.org/x/sys/windows/registry"
)
// ProxyInfo 保存当前系统代理信息
@@ -25,8 +23,8 @@ type ProxyInfo struct {
}
// GetCurrentProxy 获取本机当前的代理设置
// 优先读取 Windows 系统代理(注册表),同时也读取环境变量中的代理配置
// 支持检测 Clash、V2Ray 等常见代理工具的配置
// 优先读取系统代理(Windows 注册表 / macOS scutil / Linux 环境变量),
// 同时也读取环境变量中的代理配置
func GetCurrentProxy() (*ProxyInfo, error) {
info := &ProxyInfo{}
@@ -34,9 +32,8 @@ func GetCurrentProxy() (*ProxyInfo, error) {
info.HTTPProxy = getEnvProxy("HTTP_PROXY", "http_proxy")
info.HTTPSProxy = getEnvProxy("HTTPS_PROXY", "https_proxy")
// 2. 从 Windows 注册表读取系统代理设置
if err := readWindowsSystemProxy(info); err != nil {
// 注册表读取失败不算致命错误,环境变量中可能仍有代理信息
// 2. 从系统设置读取代理(平台相关)
if err := readSystemProxy(info); err != nil {
fmt.Printf("读取系统代理设置时出错: %v\n", err)
}
@@ -54,42 +51,6 @@ func GetCurrentProxy() (*ProxyInfo, error) {
return info, nil
}
// readWindowsSystemProxy 从 Windows 注册表读取系统代理设置
func readWindowsSystemProxy(info *ProxyInfo) error {
key, err := registry.OpenKey(
registry.CURRENT_USER,
`Software\Microsoft\Windows\CurrentVersion\Internet Settings`,
registry.QUERY_VALUE,
)
if err != nil {
return fmt.Errorf("无法打开注册表键: %w", err)
}
defer key.Close()
// 读取代理是否启用 (ProxyEnable: 0=关闭, 1=开启)
proxyEnable, _, err := key.GetIntegerValue("ProxyEnable")
if err != nil {
return fmt.Errorf("无法读取 ProxyEnable: %w", err)
}
info.Enabled = proxyEnable == 1
// 读取代理服务器地址
proxyServer, _, err := key.GetStringValue("ProxyServer")
if err == nil && proxyServer != "" {
info.Server = proxyServer
// 根据端口推断代理协议
info.Protocol = guessProtocol(proxyServer)
}
// 读取代理绕过列表
bypass, _, err := key.GetStringValue("ProxyOverride")
if err == nil {
info.Bypass = bypass
}
return nil
}
// getEnvProxy 依次检查多个环境变量名,返回第一个非空值
func getEnvProxy(names ...string) string {
for _, name := range names {
@@ -104,11 +65,9 @@ func getEnvProxy(names ...string) string {
// 例如 "http://127.0.0.1:7890" -> "127.0.0.1:7890"
func extractServerFromURL(proxyURL string) string {
s := proxyURL
// 去掉协议前缀
if idx := strings.Index(s, "://"); idx != -1 {
s = s[idx+3:]
}
// 去掉尾部斜杠
s = strings.TrimRight(s, "/")
return s
}
@@ -127,14 +86,14 @@ func extractProtocolFromURL(proxyURL string) string {
// V2Ray 默认: 10808(socks5), 10809(http)
func guessProtocol(server string) string {
knownPorts := map[string]string{
"7890": "http", // Clash HTTP
"7891": "socks5", // Clash SOCKS5
"7892": "http", // Clash mixed
"10808": "socks5", // V2Ray SOCKS5
"10809": "http", // V2Ray HTTP
"1080": "socks5", // 通用 SOCKS5
"1081": "http", // 通用 HTTP
"8080": "http", // 通用 HTTP
"7890": "http",
"7891": "socks5",
"7892": "http",
"10808": "socks5",
"10809": "http",
"1080": "socks5",
"1081": "http",
"8080": "http",
}
parts := strings.Split(server, ":")