mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
164 lines
6.8 KiB
Go
164 lines
6.8 KiB
Go
package backend
|
|
|
|
import (
|
|
"ant-chrome/backend/internal/config"
|
|
"ant-chrome/backend/internal/logger"
|
|
"ant-chrome/backend/internal/proxy"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
const temporaryDirectProxyID = "__direct__"
|
|
|
|
func (a *App) resolveBrowserStartProxy(input browserStartInput, profile *BrowserProfile) (string, profileProxyBridgeRef, bool, error) {
|
|
log := logger.New("Browser")
|
|
proxies := a.getLatestProxies()
|
|
profileID := input.ProfileID
|
|
|
|
if input.ForceDirectProxy {
|
|
log.Warn("按请求直连启动实例",
|
|
logger.F("profile_id", profileID),
|
|
logger.F("proxy_id", profile.ProxyId),
|
|
)
|
|
return "direct://", profileProxyBridgeRef{}, false, nil
|
|
}
|
|
|
|
resolvedProxyID := strings.TrimSpace(profile.ProxyId)
|
|
resolvedProxyConfig := strings.TrimSpace(profile.ProxyConfig)
|
|
usingTemporaryProxy := input.hasTemporaryProxy()
|
|
if usingTemporaryProxy {
|
|
var err error
|
|
resolvedProxyID, resolvedProxyConfig, err = resolveTemporaryBrowserStartProxy(input.TemporaryProxyID, input.TemporaryProxyConfig, proxies)
|
|
if err != nil {
|
|
startErr := fmt.Errorf("实例启动失败:%s", err.Error())
|
|
profile.LastError = startErr.Error()
|
|
log.Error("一次性代理配置无效",
|
|
logger.F("profile_id", profileID),
|
|
logger.F("temporary_proxy_id", input.TemporaryProxyID),
|
|
logger.F("error", err.Error()),
|
|
logger.F("reason", startErr.Error()),
|
|
)
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
} else if resolvedProxyID != "" {
|
|
for _, item := range proxies {
|
|
if strings.EqualFold(item.ProxyId, resolvedProxyID) {
|
|
resolvedProxyID = strings.TrimSpace(item.ProxyId)
|
|
resolvedProxyConfig = strings.TrimSpace(item.ProxyConfig)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
log.Info("代理配置检查",
|
|
logger.F("profile_id", profileID),
|
|
logger.F("proxy_id", profile.ProxyId),
|
|
logger.F("profile_proxy_config", profile.ProxyConfig),
|
|
logger.F("temporary_proxy", usingTemporaryProxy),
|
|
logger.F("temporary_proxy_id", input.TemporaryProxyID),
|
|
logger.F("temporary_proxy_config", input.TemporaryProxyConfig),
|
|
logger.F("resolved_proxy_config", resolvedProxyConfig),
|
|
)
|
|
if supported, errorMsg := proxy.ValidateProxyConfig(resolvedProxyConfig, proxies, resolvedProxyID); !supported {
|
|
startErr := fmt.Errorf("实例启动失败:%s", errorMsg)
|
|
profile.LastError = startErr.Error()
|
|
log.Error("代理配置无效",
|
|
logger.F("profile_id", profileID),
|
|
logger.F("proxy_id", resolvedProxyID),
|
|
logger.F("error", errorMsg),
|
|
logger.F("reason", startErr.Error()),
|
|
)
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
|
|
connectorType := config.BrowserConnectorXray
|
|
if a.config != nil {
|
|
connectorType = config.NormalizeBrowserConnectorType(a.config.Browser.DefaultConnectorType)
|
|
}
|
|
resolution, err := proxy.ResolveProxyKernelForConnector(resolvedProxyConfig, proxies, resolvedProxyID, connectorType)
|
|
if err != nil {
|
|
startErr := fmt.Errorf("实例启动失败:%s", err.Error())
|
|
profile.LastError = startErr.Error()
|
|
log.Error("代理内核选择失败",
|
|
logger.F("profile_id", profileID),
|
|
logger.F("proxy_id", resolvedProxyID),
|
|
logger.F("error", err.Error()),
|
|
logger.F("reason", startErr.Error()),
|
|
)
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
log.Info("实际代理内核", logger.F("profile_id", profileID), logger.F("engine", resolution.Kernel), logger.F("protocol", resolution.Protocol), logger.F("proxy_id", resolvedProxyID), logger.F("reason", resolution.Reason))
|
|
|
|
switch resolution.Kernel {
|
|
case proxy.ProxyKernelMihomo:
|
|
if a.clashMgr == nil {
|
|
startErr := fmt.Errorf("实例启动失败:mihomo 管理器未初始化,无法启动该协议代理。请先下载 Mihomo 内核。")
|
|
profile.LastError = startErr.Error()
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
proxyURL, bridgeKey, bridgeErr := a.clashMgr.AcquireNodeBridge(resolvedProxyConfig, proxies, resolvedProxyID)
|
|
if bridgeErr != nil {
|
|
startErr := fmt.Errorf("实例启动失败:mihomo 代理桥接失败:%v", bridgeErr)
|
|
log.Error("代理桥接失败(mihomo)", logger.F("error", bridgeErr.Error()), logger.F("reason", startErr.Error()))
|
|
profile.LastError = startErr.Error()
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
return proxyURL, newProfileProxyBridgeRef(profileProxyBridgeEngineMihomo, bridgeKey), bridgeKey != "", nil
|
|
case proxy.ProxyKernelSingBox:
|
|
if a.singboxMgr == nil {
|
|
startErr := fmt.Errorf("实例启动失败:sing-box 管理器未初始化,无法启动该协议代理。请检查 sing-box 内核配置。")
|
|
profile.LastError = startErr.Error()
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
socksURL, bridgeKey, bridgeErr := a.singboxMgr.AcquireBridge(resolvedProxyConfig, proxies, resolvedProxyID)
|
|
if bridgeErr != nil {
|
|
startErr := fmt.Errorf("实例启动失败:sing-box 代理桥接失败:%v", bridgeErr)
|
|
log.Error("代理桥接失败(sing-box)", logger.F("error", bridgeErr.Error()), logger.F("reason", startErr.Error()))
|
|
profile.LastError = startErr.Error()
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
return socksURL, newProfileProxyBridgeRef(profileProxyBridgeEngineSingBox, bridgeKey), bridgeKey != "", nil
|
|
case proxy.ProxyKernelXray:
|
|
if a.xrayMgr == nil {
|
|
startErr := fmt.Errorf("实例启动失败:xray 管理器未初始化,无法启动该协议代理。")
|
|
profile.LastError = startErr.Error()
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
socksURL, bridgeKey, bridgeErr := a.xrayMgr.AcquireBridge(resolvedProxyConfig, proxies, resolvedProxyID)
|
|
if bridgeErr != nil {
|
|
startErr := fmt.Errorf("实例启动失败:Xray 代理桥接失败:%v", bridgeErr)
|
|
log.Error("代理桥接失败(xray)", logger.F("error", bridgeErr.Error()), logger.F("reason", startErr.Error()))
|
|
profile.LastError = startErr.Error()
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
return socksURL, newProfileProxyBridgeRef(profileProxyBridgeEngineXray, bridgeKey), bridgeKey != "", nil
|
|
case proxy.ProxyKernelNative:
|
|
return resolvedProxyConfig, profileProxyBridgeRef{}, false, nil
|
|
default:
|
|
startErr := fmt.Errorf("实例启动失败:无法为协议 %s 选择代理内核", resolution.Protocol)
|
|
profile.LastError = startErr.Error()
|
|
return "", profileProxyBridgeRef{}, false, startErr
|
|
}
|
|
}
|
|
|
|
func resolveTemporaryBrowserStartProxy(proxyID string, proxyConfig string, proxies []BrowserProxy) (string, string, error) {
|
|
proxyID = strings.TrimSpace(proxyID)
|
|
proxyConfig = strings.TrimSpace(proxyConfig)
|
|
if proxyID == "" {
|
|
return "", proxyConfig, nil
|
|
}
|
|
|
|
for _, item := range proxies {
|
|
if strings.EqualFold(item.ProxyId, proxyID) {
|
|
return strings.TrimSpace(item.ProxyId), strings.TrimSpace(item.ProxyConfig), nil
|
|
}
|
|
}
|
|
if strings.EqualFold(proxyID, temporaryDirectProxyID) {
|
|
return temporaryDirectProxyID, "direct://", nil
|
|
}
|
|
if proxyConfig != "" {
|
|
return "", proxyConfig, nil
|
|
}
|
|
return "", "", fmt.Errorf("代理ID不存在(proxy id not found: %s),且未提供 proxyConfig", proxyID)
|
|
}
|