Skip to content

Commit

Permalink
fix: add newline in NDJSON responses
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed May 16, 2023
1 parent 5e94b9d commit 6829ed6
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
7 changes: 7 additions & 0 deletions routing/http/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ func (s *server) findProvidersNDJSON(w http.ResponseWriter, provIter iter.Result
logger.Warn("FindProviders ndjson write error", "Error", err)
return
}

_, err = w.Write([]byte{'\n'})
if err != nil {
logger.Warn("FindProviders ndjson write error", "Error", err)
return
}

if f, ok := w.(http.Flusher); ok {
f.Flush()
}
Expand Down
56 changes: 56 additions & 0 deletions routing/http/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package server

import (
"context"
"io"
"net/http"
"net/http/httptest"
"testing"
Expand All @@ -10,6 +11,7 @@ import (
"github.com/ipfs/boxo/routing/http/types"
"github.com/ipfs/boxo/routing/http/types/iter"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -48,6 +50,60 @@ func TestHeaders(t *testing.T) {
require.Equal(t, "text/plain; charset=utf-8", header)
}

func TestResponse(t *testing.T) {
pidStr := "12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn"
cidStr := "bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4"

pid, err := peer.Decode(pidStr)
require.NoError(t, err)

cid, err := cid.Decode(cidStr)
require.NoError(t, err)

runTest := func(t *testing.T, contentType string, expected string) {
t.Parallel()

results := iter.FromSlice([]iter.Result[types.ProviderResponse]{
{Val: &types.ReadBitswapProviderRecord{
Protocol: "transport-bitswap",
Schema: types.SchemaBitswap,
ID: &pid,
Addrs: []types.Multiaddr{},
}}},
)

router := &mockContentRouter{}
server := httptest.NewServer(Handler(router))
t.Cleanup(server.Close)
serverAddr := "http://" + server.Listener.Addr().String()
router.On("FindProviders", mock.Anything, cid).Return(results, nil)
urlStr := serverAddr + ProvidePath + cidStr

req, err := http.NewRequest(http.MethodGet, urlStr, nil)
require.NoError(t, err)
req.Header.Set("Accept", contentType)

resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
header := resp.Header.Get("Content-Type")
require.Equal(t, contentType, header)

body, err := io.ReadAll(resp.Body)
require.NoError(t, err)

require.Equal(t, string(body), expected)
}

t.Run("JSON Response", func(t *testing.T) {
runTest(t, mediaTypeJSON, `{"Providers":[{"Protocol":"transport-bitswap","Schema":"bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Addrs":[]}]}`)
})

t.Run("NDJSON Response", func(t *testing.T) {
runTest(t, mediaTypeNDJSON, `{"Protocol":"transport-bitswap","Schema":"bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Addrs":[]}`+"\n")
})
}

type mockContentRouter struct{ mock.Mock }

func (m *mockContentRouter) FindProviders(ctx context.Context, key cid.Cid) (iter.ResultIter[types.ProviderResponse], error) {
Expand Down

0 comments on commit 6829ed6

Please sign in to comment.