package netproxy import ( "fmt" "net/url" "strings" ) const ( ModeNone = "none" ModeGlobal = "global" ModeCustom = "custom" ) type Config struct { Mode string HTTPProxy string } func FromPlatformConfig(values map[string]any) Config { config := Config{ Mode: stringFromMap(values, "proxyMode"), HTTPProxy: stringFromMap(values, "httpProxy"), } if nested := recordFromAny(values["networkProxy"]); nested != nil { if mode := stringFromMap(nested, "mode"); mode != "" { config.Mode = mode } if proxy := stringFromMap(nested, "httpProxy"); proxy != "" { config.HTTPProxy = proxy } } return config } func Normalize(input Config) (Config, error) { mode, err := normalizeMode(input.Mode) if err != nil { return Config{}, err } config := Config{Mode: mode} if mode != ModeCustom { return config, nil } normalized, _, err := ParseHTTPProxy(input.HTTPProxy) if err != nil { return Config{}, err } config.HTTPProxy = normalized return config, nil } func NormalizePlatformConfig(values map[string]any) (map[string]any, error) { next := map[string]any{} for key, value := range values { next[key] = value } config, err := Normalize(FromPlatformConfig(values)) if err != nil { return nil, err } networkProxy := map[string]any{"mode": config.Mode} if config.Mode == ModeCustom { networkProxy["httpProxy"] = config.HTTPProxy } next["networkProxy"] = networkProxy delete(next, "proxyMode") delete(next, "httpProxy") return next, nil } func ParseHTTPProxy(raw string) (string, *url.URL, error) { trimmed := strings.TrimSpace(raw) if trimmed == "" { return "", nil, fmt.Errorf("http proxy is required") } if !strings.Contains(trimmed, "://") { trimmed = "http://" + trimmed } parsed, err := url.Parse(trimmed) if err != nil { return "", nil, fmt.Errorf("invalid http proxy: %w", err) } if parsed.Scheme != "http" && parsed.Scheme != "https" { return "", nil, fmt.Errorf("http proxy scheme must be http or https") } if parsed.Host == "" { return "", nil, fmt.Errorf("http proxy host is required") } return parsed.String(), parsed, nil } func normalizeMode(value string) (string, error) { switch strings.ToLower(strings.TrimSpace(value)) { case "", "none", "off", "disabled", "disable": return ModeNone, nil case "global", "system", "env", "environment": return ModeGlobal, nil case "custom": return ModeCustom, nil default: return "", fmt.Errorf("unsupported proxy mode %q", value) } } func recordFromAny(value any) map[string]any { record, _ := value.(map[string]any) return record } func stringFromMap(values map[string]any, key string) string { value, _ := values[key].(string) return strings.TrimSpace(value) }