diff options
Diffstat (limited to 'internal/util/punycode.go')
-rw-r--r-- | internal/util/punycode.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/internal/util/punycode.go b/internal/util/punycode.go index 4a595a281..cc1b57a27 100644 --- a/internal/util/punycode.go +++ b/internal/util/punycode.go @@ -18,6 +18,7 @@ package util import ( + "net/url" "strings" "golang.org/x/net/idna" @@ -42,3 +43,70 @@ func DePunify(domain string) (string, error) { out, err := idna.ToUnicode(domain) return strings.ToLower(out), err } + +// URIMatches returns true if the expected URI matches +// any of the given URIs, taking account of punycode. +func URIMatches(expect *url.URL, uris ...*url.URL) (bool, error) { + // Normalize expect to punycode. + expectPuny, err := PunifyURI(expect) + if err != nil { + return false, err + } + expectStr := expectPuny.String() + + for _, uri := range uris { + uriPuny, err := PunifyURI(uri) + if err != nil { + return false, err + } + + if uriPuny.String() == expectStr { + // Looks good. + return true, nil + } + } + + // Didn't match. + return false, nil +} + +// PunifyURI returns a copy of the given URI +// with the 'host' part converted to punycode. +func PunifyURI(in *url.URL) (*url.URL, error) { + // Take a copy of in. + out := new(url.URL) + *out = *in + + // Normalize host to punycode. + var err error + out.Host, err = Punify(in.Host) + return out, err +} + +// PunifyURIStr returns a copy of the given URI +// string with the 'host' part converted to punycode. +func PunifyURIStr(in string) (string, error) { + inURI, err := url.Parse(in) + if err != nil { + return "", err + } + + outURIPuny, err := Punify(inURI.Host) + if err != nil { + return "", err + } + + if outURIPuny == in { + // Punify did nothing, so in was + // already punified, return as-is. + return in, nil + } + + // Take a copy of in. + outURI := new(url.URL) + *outURI = *inURI + + // Normalize host to punycode. + outURI.Host = outURIPuny + return outURI.String(), err +} |