mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
194 lines
6.6 KiB
Go
194 lines
6.6 KiB
Go
package backend
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type ProxyLocationResolveResult struct {
|
|
ProxyId string `json:"proxyId"`
|
|
Ok bool `json:"ok"`
|
|
Auto bool `json:"auto"`
|
|
Source string `json:"source"`
|
|
Error string `json:"error"`
|
|
IP string `json:"ip"`
|
|
Country string `json:"country"`
|
|
Region string `json:"region"`
|
|
City string `json:"city"`
|
|
Timezone string `json:"timezone"`
|
|
Lang string `json:"lang"`
|
|
Health *ProxyIPHealthResult `json:"health,omitempty"`
|
|
Alternates []ProxyLocationOption `json:"alternates,omitempty"`
|
|
ResolvedAt string `json:"resolvedAt"`
|
|
}
|
|
|
|
type ProxyLocationOption struct {
|
|
Label string `json:"label"`
|
|
Timezone string `json:"timezone"`
|
|
Lang string `json:"lang"`
|
|
}
|
|
|
|
var countryLocaleDefaults = map[string]ProxyLocationOption{
|
|
"CN": {Label: "中国", Timezone: "Asia/Shanghai", Lang: "zh-CN"},
|
|
"HK": {Label: "中国香港", Timezone: "Asia/Hong_Kong", Lang: "zh-HK"},
|
|
"TW": {Label: "中国台湾", Timezone: "Asia/Taipei", Lang: "zh-TW"},
|
|
"US": {Label: "美国", Timezone: "America/New_York", Lang: "en-US"},
|
|
"GB": {Label: "英国", Timezone: "Europe/London", Lang: "en-GB"},
|
|
"JP": {Label: "日本", Timezone: "Asia/Tokyo", Lang: "ja-JP"},
|
|
"KR": {Label: "韩国", Timezone: "Asia/Seoul", Lang: "ko-KR"},
|
|
"SG": {Label: "新加坡", Timezone: "Asia/Singapore", Lang: "en-SG"},
|
|
"DE": {Label: "德国", Timezone: "Europe/Berlin", Lang: "de-DE"},
|
|
"FR": {Label: "法国", Timezone: "Europe/Paris", Lang: "fr-FR"},
|
|
"NL": {Label: "荷兰", Timezone: "Europe/Amsterdam", Lang: "nl-NL"},
|
|
"CA": {Label: "加拿大", Timezone: "America/Toronto", Lang: "en-CA"},
|
|
"AU": {Label: "澳大利亚", Timezone: "Australia/Sydney", Lang: "en-AU"},
|
|
"RU": {Label: "俄罗斯", Timezone: "Europe/Moscow", Lang: "ru-RU"},
|
|
"BR": {Label: "巴西", Timezone: "America/Sao_Paulo", Lang: "pt-BR"},
|
|
"IN": {Label: "印度", Timezone: "Asia/Kolkata", Lang: "en-IN"},
|
|
}
|
|
|
|
var cityTimezoneDefaults = map[string]string{
|
|
"US|new york": "America/New_York",
|
|
"US|los angeles": "America/Los_Angeles",
|
|
"US|san francisco": "America/Los_Angeles",
|
|
"US|chicago": "America/Chicago",
|
|
"US|denver": "America/Denver",
|
|
"US|phoenix": "America/Phoenix",
|
|
"CA|toronto": "America/Toronto",
|
|
"CA|vancouver": "America/Vancouver",
|
|
"AU|sydney": "Australia/Sydney",
|
|
"AU|melbourne": "Australia/Melbourne",
|
|
"AU|perth": "Australia/Perth",
|
|
}
|
|
|
|
func (a *App) BrowserProxyResolveLocation(proxyId string) ProxyLocationResolveResult {
|
|
proxyId = strings.TrimSpace(proxyId)
|
|
resolvedAt := time.Now().Format(time.RFC3339)
|
|
if proxyId == "" || strings.EqualFold(proxyId, "__direct__") {
|
|
return ProxyLocationResolveResult{ProxyId: proxyId, Ok: false, Auto: false, Source: "manual", Error: "直连或未选择代理,请手动选择定位", ResolvedAt: resolvedAt}
|
|
}
|
|
|
|
if cached, ok := a.cachedProxyIPHealthResult(proxyId); ok && cached.Ok {
|
|
return buildProxyLocationResolveResult(proxyId, cached, "cache", resolvedAt)
|
|
}
|
|
|
|
health := a.BrowserProxyCheckIPHealth(proxyId)
|
|
if !health.Ok {
|
|
return ProxyLocationResolveResult{ProxyId: proxyId, Ok: false, Auto: false, Source: health.Source, Error: health.Error, Health: &health, ResolvedAt: resolvedAt}
|
|
}
|
|
return buildProxyLocationResolveResult(proxyId, health, "ip_health", resolvedAt)
|
|
}
|
|
|
|
func (a *App) cachedProxyIPHealthResult(proxyId string) (ProxyIPHealthResult, bool) {
|
|
if a == nil || a.browserMgr == nil || a.browserMgr.ProxyDAO == nil {
|
|
return ProxyIPHealthResult{}, false
|
|
}
|
|
proxies, err := a.browserMgr.ProxyDAO.List()
|
|
if err != nil {
|
|
return ProxyIPHealthResult{}, false
|
|
}
|
|
for _, item := range proxies {
|
|
if !strings.EqualFold(strings.TrimSpace(item.ProxyId), proxyId) || strings.TrimSpace(item.LastIPHealthJSON) == "" {
|
|
continue
|
|
}
|
|
var result ProxyIPHealthResult
|
|
if err := json.Unmarshal([]byte(item.LastIPHealthJSON), &result); err == nil && result.ProxyId != "" {
|
|
return result, true
|
|
}
|
|
}
|
|
return ProxyIPHealthResult{}, false
|
|
}
|
|
|
|
func buildProxyLocationResolveResult(proxyId string, health ProxyIPHealthResult, source string, resolvedAt string) ProxyLocationResolveResult {
|
|
option := resolveProxyLocationOption(health.Country, health.City)
|
|
ok := health.Ok && option.Timezone != "" && option.Lang != ""
|
|
result := ProxyLocationResolveResult{
|
|
ProxyId: proxyId,
|
|
Ok: ok,
|
|
Auto: ok,
|
|
Source: source,
|
|
IP: health.IP,
|
|
Country: health.Country,
|
|
Region: health.Region,
|
|
City: health.City,
|
|
Timezone: option.Timezone,
|
|
Lang: option.Lang,
|
|
Health: &health,
|
|
ResolvedAt: resolvedAt,
|
|
}
|
|
if !ok {
|
|
result.Error = fmt.Sprintf("无法根据地区自动匹配定位:%s %s", strings.TrimSpace(health.Country), strings.TrimSpace(health.City))
|
|
result.Alternates = defaultProxyLocationOptions()
|
|
}
|
|
return result
|
|
}
|
|
|
|
func resolveProxyLocationOption(country string, city string) ProxyLocationOption {
|
|
countryCode := normalizeCountryCode(country)
|
|
option := countryLocaleDefaults[countryCode]
|
|
if option.Timezone == "" {
|
|
return ProxyLocationOption{}
|
|
}
|
|
cityKey := countryCode + "|" + strings.ToLower(strings.TrimSpace(city))
|
|
if timezone := cityTimezoneDefaults[cityKey]; timezone != "" {
|
|
option.Timezone = timezone
|
|
}
|
|
return option
|
|
}
|
|
|
|
func normalizeCountryCode(country string) string {
|
|
value := strings.TrimSpace(country)
|
|
upper := strings.ToUpper(value)
|
|
if len(upper) == 2 {
|
|
return upper
|
|
}
|
|
switch strings.ToLower(value) {
|
|
case "china", "中国", "mainland china":
|
|
return "CN"
|
|
case "hong kong", "香港":
|
|
return "HK"
|
|
case "taiwan", "台湾":
|
|
return "TW"
|
|
case "united states", "usa", "us", "美国":
|
|
return "US"
|
|
case "united kingdom", "uk", "great britain", "英国":
|
|
return "GB"
|
|
case "japan", "日本":
|
|
return "JP"
|
|
case "south korea", "korea", "韩国":
|
|
return "KR"
|
|
case "singapore", "新加坡":
|
|
return "SG"
|
|
case "germany", "德国":
|
|
return "DE"
|
|
case "france", "法国":
|
|
return "FR"
|
|
case "netherlands", "荷兰":
|
|
return "NL"
|
|
case "canada", "加拿大":
|
|
return "CA"
|
|
case "australia", "澳大利亚":
|
|
return "AU"
|
|
case "russia", "俄罗斯":
|
|
return "RU"
|
|
case "brazil", "巴西":
|
|
return "BR"
|
|
case "india", "印度":
|
|
return "IN"
|
|
default:
|
|
return upper
|
|
}
|
|
}
|
|
|
|
func defaultProxyLocationOptions() []ProxyLocationOption {
|
|
return []ProxyLocationOption{
|
|
countryLocaleDefaults["US"],
|
|
countryLocaleDefaults["GB"],
|
|
countryLocaleDefaults["JP"],
|
|
countryLocaleDefaults["SG"],
|
|
countryLocaleDefaults["CN"],
|
|
}
|
|
}
|