fix and use a supposedly much faster library on NormalizeURL(), it's slightly less tolerant with stupidly-formed URLs.

This commit is contained in:
fiatjaf 2025-02-25 09:55:19 -03:00
parent 7e06354b6f
commit 6d8cd55784
4 changed files with 49 additions and 17 deletions

1
go.mod
View File

@ -3,6 +3,7 @@ module github.com/nbd-wtf/go-nostr
go 1.23.1 go 1.23.1
require ( require (
github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3
github.com/PowerDNS/lmdb-go v1.9.2 github.com/PowerDNS/lmdb-go v1.9.2
github.com/bluekeyes/go-gitdiff v0.7.1 github.com/bluekeyes/go-gitdiff v0.7.1
github.com/btcsuite/btcd/btcec/v2 v2.3.4 github.com/btcsuite/btcd/btcec/v2 v2.3.4

4
go.sum
View File

@ -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/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 h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= 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 h1:Cmgerh9y3ZKBZGz1irxSShhfmFyRUh+Zdk4cZk7ZJvU=
github.com/PowerDNS/lmdb-go v1.9.2/go.mod h1:TE0l+EZK8Z1B4dx070ZxkWTlp8RG1mjN0/+FkFRQMtU= 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= 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/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 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= 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 h1:k7evIqJ2BtFn191DgY/b03N2bMYA/iQwzr4f/uHYn20=
github.com/elnosh/gonuts v0.3.1-0.20250123162555-7c0381a585e3/go.mod h1:vgZomh4YQk7R3w4ltZc0sHwCmndfHkuX6V4sga/8oNs= 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= 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/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.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.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.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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=

View File

@ -4,6 +4,8 @@ import (
"fmt" "fmt"
"net/url" "net/url"
"strings" "strings"
"github.com/ImVexed/fasturl"
) )
// NormalizeURL normalizes the url and replaces http://, https:// schemes with ws://, wss:// // 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) u = strings.TrimSpace(u)
if fqn := strings.Split(u, ":")[0]; fqn == "localhost" || fqn == "127.0.0.1" { p, err := fasturl.ParseURL(u)
u = "ws://" + u
} else if !strings.HasPrefix(u, "http") && !strings.HasPrefix(u, "ws") {
u = "wss://" + u
}
p, err := url.Parse(u)
if err != nil { if err != nil {
return "" return ""
} }
if p.Scheme == "http" { // the fabulous case of localhost:1234 that considers "localhost" the protocol and "123" the host
p.Scheme = "ws" if p.Port == "" && len(p.Protocol) > 5 {
} else if p.Scheme == "https" { p.Protocol, p.Host, p.Port = "", p.Protocol, p.Host
p.Scheme = "wss" }
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.Host = strings.ToLower(p.Host)
p.Path = strings.TrimRight(p.Path, "/") 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. // NormalizeHTTPURL does normalization of http(s):// URLs according to rfc3986. Don't use for relay URLs.

View File

@ -1,9 +1,10 @@
package nostr package nostr
import ( import (
"strconv"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"
) )
type urlTest struct { type urlTest struct {
@ -21,17 +22,19 @@ var urlTests = []urlTest{
{NormalizeURL(NormalizeURL(NormalizeURL("wss://x.com/"))), "wss://x.com"}, {NormalizeURL(NormalizeURL(NormalizeURL("wss://x.com/"))), "wss://x.com"},
{"wss://x.com", "wss://x.com"}, {"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"}, {"x.com/?x=23", "wss://x.com?x=23"},
{"localhost:4036", "ws://localhost:4036"}, {"localhost:4036", "ws://localhost:4036"},
{"localhost:4036/relay", "ws://localhost:4036/relay"}, {"localhost:4036/relay", "ws://localhost:4036/relay"},
{"localhostmagnanimus.com", "wss://localhostmagnanimus.com"}, {"localhostmagnanimus.com", "wss://localhostmagnanimus.com"},
{NormalizeURL("localhost:4036/relay"), "ws://localhost:4036/relay"}, {NormalizeURL("localhost:4036/relay"), "ws://localhost:4036/relay"},
{NormalizeURL("nostr:askjd"), "nostr://askjd"},
} }
func TestNormalizeURL(t *testing.T) { func TestNormalizeURL(t *testing.T) {
for _, test := range urlTests { for i, test := range urlTests {
output := NormalizeURL(test.url) t.Run(strconv.Itoa(i)+" { "+test.url+" -> "+test.expected+" }", func(t *testing.T) {
assert.Equal(t, test.expected, output) output := NormalizeURL(test.url)
require.Equal(t, test.expected, output)
})
} }
} }