From 3862333dfaad2b71909d4727109624a6b07f4284 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Wed, 19 Jun 2024 19:54:40 -0300 Subject: [PATCH] nip11: always return a struct from Fetch() with URL filled. --- nip11/fetch.go | 23 +++++++++++++++-------- nip11/nip11_test.go | 25 ++++++++++++++++--------- nip11/types.go | 2 ++ 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/nip11/fetch.go b/nip11/fetch.go index 4627f05..b230a98 100644 --- a/nip11/fetch.go +++ b/nip11/fetch.go @@ -10,8 +10,12 @@ import ( "github.com/nbd-wtf/go-nostr" ) -// Fetch fetches the NIP-11 RelayInformationDocument. -func Fetch(ctx context.Context, u string) (info *RelayInformationDocument, err error) { +// Fetch fetches the NIP-11 metadata for a relay. +// +// It will always return `info` with at least `URL` filled -- even if we can't connect to the +// relay or if it doesn't have a NIP-11 handler -- although in that case it will also return +// an error. +func Fetch(ctx context.Context, u string) (info RelayInformationDocument, err error) { if _, ok := ctx.Deadline(); !ok { // if no timeout is set, force it to 7 seconds var cancel context.CancelFunc @@ -20,10 +24,14 @@ func Fetch(ctx context.Context, u string) (info *RelayInformationDocument, err e } // normalize URL to start with http://, https:// or without protocol - u = "http" + nostr.NormalizeURL(u)[2:] + u = nostr.NormalizeURL(u) + + info = RelayInformationDocument{ + URL: u, + } // make request - req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) + req, err := http.NewRequestWithContext(ctx, "GET", "http"+u[2:], nil) // add the NIP-11 header req.Header.Add("Accept", "application/nostr+json") @@ -31,13 +39,12 @@ func Fetch(ctx context.Context, u string) (info *RelayInformationDocument, err e // send the request resp, err := http.DefaultClient.Do(req) if err != nil { - return nil, fmt.Errorf("request failed: %w", err) + return info, fmt.Errorf("request failed: %w", err) } defer resp.Body.Close() - info = &RelayInformationDocument{} - if err := json.NewDecoder(resp.Body).Decode(info); err != nil { - return nil, fmt.Errorf("invalid json: %w", err) + if err := json.NewDecoder(resp.Body).Decode(&info); err != nil { + return info, fmt.Errorf("invalid json: %w", err) } return info, nil diff --git a/nip11/nip11_test.go b/nip11/nip11_test.go index 9e4e6dd..cda76de 100644 --- a/nip11/nip11_test.go +++ b/nip11/nip11_test.go @@ -3,6 +3,8 @@ package nip11 import ( "context" "testing" + + "github.com/stretchr/testify/assert" ) func TestAddSupportedNIP(t *testing.T) { @@ -34,15 +36,20 @@ func TestAddSupportedNIP(t *testing.T) { func TestFetch(t *testing.T) { res, err := Fetch(context.Background(), "wss://relay.nostr.bg") - if err != nil || res.Name == "" { - t.Errorf("failed to fetch from wss") - } + assert.Equal(t, res.URL, "wss://relay.nostr.bg") + assert.Nil(t, err, "failed to fetch from wss") + assert.NotEmpty(t, res.Name) + res, err = Fetch(context.Background(), "https://relay.nostr.bg") - if err != nil || res.Name == "" { - t.Errorf("failed to fetch from https") - } + assert.Nil(t, err, "failed to fetch from https") + assert.NotEmpty(t, res.Name) + res, err = Fetch(context.Background(), "relay.nostr.bg") - if err != nil || res.Name == "" { - t.Errorf("failed to fetch without protocol") - } + assert.Nil(t, err, "failed to fetch without protocol") + assert.NotEmpty(t, res.Name) + + res, err = Fetch(context.Background(), "wlenwqkeqwe.asjdaskd") + assert.Error(t, err) + assert.NotNil(t, res) + assert.Equal(t, res.URL, "wss://wlenwqkeqwe.asjdaskd") } diff --git a/nip11/types.go b/nip11/types.go index 1894893..7fa3873 100644 --- a/nip11/types.go +++ b/nip11/types.go @@ -3,6 +3,8 @@ package nip11 import "slices" type RelayInformationDocument struct { + URL string `json:"-"` + Name string `json:"name"` Description string `json:"description"` PubKey string `json:"pubkey"`