Files

69 lines
1.8 KiB
Go

package naive
import (
"fmt"
"net/url"
"strings"
)
// NormalizeProxyURI converts share links and aliases into a naive --proxy URI.
//
// Supported inputs:
// - https://user:pass@host:443
// - quic://user:pass@host
// - naive+https://user:pass@host:443#remark
// - naive+quic://user:pass@host#remark
func NormalizeProxyURI(raw string) (string, error) {
uri, _, err := ParseShareLink(raw)
return uri, err
}
// ParseShareLink returns a normalized proxy URI and optional remark from #fragment.
func ParseShareLink(raw string) (proxyURI, remark string, err error) {
raw = strings.TrimSpace(raw)
if raw == "" {
return "", "", fmt.Errorf("empty proxy URI")
}
if i := strings.IndexByte(raw, '#'); i >= 0 {
remark = strings.TrimSpace(raw[i+1:])
raw = raw[:i]
}
lower := strings.ToLower(raw)
switch {
case strings.HasPrefix(lower, "naive+https://"):
raw = "https://" + raw[len("naive+https://"):]
case strings.HasPrefix(lower, "naive+quic://"):
raw = "quic://" + raw[len("naive+quic://"):]
case strings.HasPrefix(lower, "naive://"):
raw = "https://" + raw[len("naive://"):]
}
u, err := url.Parse(raw)
if err != nil {
return "", "", fmt.Errorf("parse proxy URI: %w", err)
}
switch strings.ToLower(u.Scheme) {
case "https", "quic", "http":
default:
return "", "", fmt.Errorf("unsupported proxy scheme %q (use https://, quic:// or naive+https://)", u.Scheme)
}
if u.Host == "" {
return "", "", fmt.Errorf("proxy URI missing host")
}
if u.User == nil || u.User.Username() == "" {
return "", "", fmt.Errorf("proxy URI missing username")
}
if _, ok := u.User.Password(); !ok {
return "", "", fmt.Errorf("proxy URI missing password")
}
out := &url.URL{
Scheme: strings.ToLower(u.Scheme),
User: u.User,
Host: u.Host,
}
return out.String(), remark, nil
}