From 6d8cd5578451cf53066471ea4a138f52779cb251 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Tue, 25 Feb 2025 09:55:19 -0300 Subject: [PATCH] fix and use a supposedly much faster library on NormalizeURL(), it's slightly less tolerant with stupidly-formed URLs. --- go.mod | 1 + go.sum | 4 ++++ normalize.go | 48 +++++++++++++++++++++++++++++++++++------------ normalize_test.go | 13 ++++++++----- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index fd532df..10aadaf 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/nbd-wtf/go-nostr go 1.23.1 require ( + github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 github.com/PowerDNS/lmdb-go v1.9.2 github.com/bluekeyes/go-gitdiff v0.7.1 github.com/btcsuite/btcd/btcec/v2 v2.3.4 diff --git a/go.sum b/go.sum index 8a742ee..035a801 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25Yn github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= +github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 h1:ClzzXMDDuUbWfNNZqGeYq4PnYOlwlOVIvSyNaIy0ykg= +github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3/go.mod h1:we0YA5CsBbH5+/NUzC/AlMmxaDtWlXeNsqrwXjTzmzA= github.com/PowerDNS/lmdb-go v1.9.2 h1:Cmgerh9y3ZKBZGz1irxSShhfmFyRUh+Zdk4cZk7ZJvU= github.com/PowerDNS/lmdb-go v1.9.2/go.mod h1:TE0l+EZK8Z1B4dx070ZxkWTlp8RG1mjN0/+FkFRQMtU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -77,6 +79,7 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/elnosh/gonuts v0.3.1-0.20250123162555-7c0381a585e3 h1:k7evIqJ2BtFn191DgY/b03N2bMYA/iQwzr4f/uHYn20= github.com/elnosh/gonuts v0.3.1-0.20250123162555-7c0381a585e3/go.mod h1:vgZomh4YQk7R3w4ltZc0sHwCmndfHkuX6V4sga/8oNs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -200,6 +203,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= diff --git a/normalize.go b/normalize.go index a0f2ae5..c069767 100644 --- a/normalize.go +++ b/normalize.go @@ -4,6 +4,8 @@ import ( "fmt" "net/url" "strings" + + "github.com/ImVexed/fasturl" ) // NormalizeURL normalizes the url and replaces http://, https:// schemes with ws://, wss:// @@ -14,27 +16,49 @@ func NormalizeURL(u string) string { } u = strings.TrimSpace(u) - if fqn := strings.Split(u, ":")[0]; fqn == "localhost" || fqn == "127.0.0.1" { - u = "ws://" + u - } else if !strings.HasPrefix(u, "http") && !strings.HasPrefix(u, "ws") { - u = "wss://" + u - } - - p, err := url.Parse(u) + p, err := fasturl.ParseURL(u) if err != nil { return "" } - if p.Scheme == "http" { - p.Scheme = "ws" - } else if p.Scheme == "https" { - p.Scheme = "wss" + // the fabulous case of localhost:1234 that considers "localhost" the protocol and "123" the host + if p.Port == "" && len(p.Protocol) > 5 { + p.Protocol, p.Host, p.Port = "", p.Protocol, p.Host + } + + if p.Protocol == "" { + if p.Host == "localhost" || p.Host == "127.0.0.1" { + p.Protocol = "ws" + } else { + p.Protocol = "wss" + } + } else if p.Protocol == "https" { + p.Protocol = "wss" + } else if p.Protocol == "http" { + p.Protocol = "ws" } p.Host = strings.ToLower(p.Host) p.Path = strings.TrimRight(p.Path, "/") - return p.String() + var buf strings.Builder + buf.Grow( + len(p.Protocol) + 3 + len(p.Host) + 1 + len(p.Port) + len(p.Path) + 1 + len(p.Query), + ) + + buf.WriteString(p.Protocol) + buf.WriteString("://") + buf.WriteString(p.Host) + if p.Port != "" { + buf.WriteByte(':') + buf.WriteString(p.Port) + } + buf.WriteString(p.Path) + if p.Query != "" { + buf.WriteByte('?') + buf.WriteString(p.Query) + } + return buf.String() } // NormalizeHTTPURL does normalization of http(s):// URLs according to rfc3986. Don't use for relay URLs. diff --git a/normalize_test.go b/normalize_test.go index 213fc14..813d4b1 100644 --- a/normalize_test.go +++ b/normalize_test.go @@ -1,9 +1,10 @@ package nostr import ( + "strconv" "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type urlTest struct { @@ -21,17 +22,19 @@ var urlTests = []urlTest{ {NormalizeURL(NormalizeURL(NormalizeURL("wss://x.com/"))), "wss://x.com"}, {"wss://x.com", "wss://x.com"}, {"wss://x.com/", "wss://x.com"}, - {"x.com////", "wss://x.com"}, {"x.com/?x=23", "wss://x.com?x=23"}, {"localhost:4036", "ws://localhost:4036"}, {"localhost:4036/relay", "ws://localhost:4036/relay"}, {"localhostmagnanimus.com", "wss://localhostmagnanimus.com"}, {NormalizeURL("localhost:4036/relay"), "ws://localhost:4036/relay"}, + {NormalizeURL("nostr:askjd"), "nostr://askjd"}, } func TestNormalizeURL(t *testing.T) { - for _, test := range urlTests { - output := NormalizeURL(test.url) - assert.Equal(t, test.expected, output) + for i, test := range urlTests { + t.Run(strconv.Itoa(i)+" { "+test.url+" -> "+test.expected+" }", func(t *testing.T) { + output := NormalizeURL(test.url) + require.Equal(t, test.expected, output) + }) } }