69 lines
1.8 KiB
Go
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
|
|
}
|