summaryrefslogtreecommitdiff
path: root/internal/util/punycode.go
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2024-07-26 13:11:07 +0200
committerLibravatar GitHub <noreply@github.com>2024-07-26 13:11:07 +0200
commitecfea10e359b9c9e7c0e6b5fd092e3caa5587df6 (patch)
treecc5cb01cf7d97baf7e47bb7a246fbc392c41fe9e /internal/util/punycode.go
parent[feature] Federate interaction policies + Accepts; enforce policies (#3138) (diff)
downloadgotosocial-ecfea10e359b9c9e7c0e6b5fd092e3caa5587df6.tar.xz
[bugfix] Use punycode for `host` part of `resource` query param when doing webfinger requests (#3133)
* [bugfix] use punycode when webfingering * account for punycode when checking if final URI matches expected * hmm * fix test
Diffstat (limited to 'internal/util/punycode.go')
-rw-r--r--internal/util/punycode.go68
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
+}