{"record":{"id":"5e63030767c4cfe6","repo":"MHSanaei/3x-ui","slug":"parse-proxy-url-w","errorCode":null,"errorMessage":"parse proxy url: %w","messagePattern":"parse proxy url: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/util/netproxy/netproxy.go","lineNumber":35,"sourceCode":"\n// NewHTTPClient returns an *http.Client whose transport honors proxyURL.\n//\n// An empty proxyURL yields a plain client (unchanged behavior). socks5/socks5h\n// URLs are dialed through golang.org/x/net/proxy; http/https URLs use the\n// standard library proxy support. Any other scheme returns an error so callers\n// can log it and fall back to a direct connection.\n//\n// The proxy address is intentionally not subjected to SSRF filtering: it is\n// admin-configured and is commonly a loopback/private address (for example a\n// local Xray SOCKS inbound).\nfunc NewHTTPClient(proxyURL string, timeout time.Duration) (*http.Client, error) {\n\tif proxyURL == \"\" {\n\t\treturn &http.Client{Timeout: timeout}, nil\n\t}\n\n\tparsed, err := url.Parse(proxyURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse proxy url: %w\", err)\n\t}\n\n\ttransport := baseTransport()\n\n\tswitch strings.ToLower(parsed.Scheme) {\n\tcase \"socks5\", \"socks5h\":\n\t\tvar auth *proxy.Auth\n\t\tif parsed.User != nil {\n\t\t\tpassword, _ := parsed.User.Password()\n\t\t\tauth = &proxy.Auth{User: parsed.User.Username(), Password: password}\n\t\t}\n\t\tdialer, err := proxy.SOCKS5(\"tcp\", parsed.Host, auth, proxy.Direct)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"create socks5 dialer: %w\", err)\n\t\t}\n\t\tif contextDialer, ok := dialer.(proxy.ContextDialer); ok {\n\t\t\ttransport.DialContext = contextDialer.DialContext\n\t\t} else {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/util/netproxy/netproxy.go#L17-L53","documentation":"NewHTTPClient in internal/util/netproxy/netproxy.go parses the admin-configured proxy URL with net/url.Parse and wraps any failure as 'parse proxy url: %w'. url.Parse only fails on genuinely malformed URLs (control characters, unmatched brackets, missing scheme with a colon misplaced), not on unknown schemes — those fail later at the scheme switch. Note this address is deliberately exempt from SSRF filtering because it is admin-configured.","triggerScenarios":"Calling NewHTTPClient with a proxyURL containing control chars, spaces, 'socks5://user:pa:ss@1.2.3.4:1080' (colon inside password unescaped), 'http//[::1]:8080' (missing colon), or an empty scheme followed by junk. Set via whatever setting feeds this function (e.g. panel settings for outbound HTTP requests through a proxy).","commonSituations":"Typing a proxy URL in panel settings with an unencoded special character in the password; a trailing newline or space pasted from a terminal; IPv6 proxy address without brackets; env var with stray quotes.","solutions":["Re-enter the proxy URL exactly as scheme://[user:pass@]host:port, URL-encoding any special characters in user/password.","Wrap IPv6 literals in brackets: socks5://[::1]:1080.","Trim whitespace/newlines from the configured value before passing it in.","Test the URL in isolation: url.Parse it in a scratch program to see the underlying error text carried by %w."],"exampleFix":"// before\nproxyURL := \"socks5://user:pa:ss@10.0.0.1:1080\" // colon in password breaks parsing\nclient, err := netproxy.NewHTTPClient(proxyURL, timeout)\n\n// after\nproxyURL := \"socks5://user:pa%3Ass@10.0.0.1:1080\"\nclient, err := netproxy.NewHTTPClient(proxyURL, timeout)","handlingStrategy":"validation","validationCode":"func validProxyURL(raw string) bool {\n\traw = strings.TrimSpace(raw)\n\tif raw == \"\" { return true } // empty means direct\n\tu, err := url.Parse(raw)\n\treturn err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","typeGuard":null,"tryCatchPattern":"client, err := netproxy.NewHTTPClient(proxyURL, timeout)\nif err != nil {\n    return fmt.Errorf(\"bad proxy setting %q: %w\", proxyURL, err)\n}","preventionTips":["Validate the proxy URL at settings-save time, not at request time.","URL-encode credentials containing ':' or '@'.","Trim pasted values and reject embedded newlines on save."],"tags":["proxy","url","http-client","configuration"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}