package http import ( "errors" "fmt" "net/url" "slices" "strings" ) var ErrOrigin = errors.New("http: the origin is not scheme://host[:port] of a served host") func ParseOrigin(raw, scheme string, hosts ...string) (string, error) { refuse := fmt.Errorf("%w: %q", ErrOrigin, raw) if strings.Contains(raw, "#") { return "", refuse } u, err := url.Parse(raw) if err != nil || u.Scheme != scheme || u.Opaque != "" || u.User != nil || u.Host == "" || u.Path != "" || u.RawPath != "" || u.RawQuery != "" || u.ForceQuery || u.Fragment != "" { return "", refuse } host := CanonicalHost(u.Host) if host != u.Hostname() || !slices.Contains(hosts, host) { return "", refuse } return host, nil }