@@ -2,6 +2,12 @@ package main
2
2
3
3
import (
4
4
"context"
5
+ "encoding/json"
6
+ "errors"
7
+ "fmt"
8
+ "net/http"
9
+ "net/http/httptest"
10
+ "strings"
5
11
"testing"
6
12
"time"
7
13
@@ -12,19 +18,108 @@ import (
12
18
"github.com/ipfs/go-cid"
13
19
"github.com/ipfs/go-datastore"
14
20
dssync "github.com/ipfs/go-datastore/sync"
21
+ ipld "github.com/ipfs/go-ipld-format"
15
22
"github.com/ipfs/ipfs-check/test"
16
23
"github.com/libp2p/go-libp2p"
17
24
dht "github.com/libp2p/go-libp2p-kad-dht"
18
25
"github.com/libp2p/go-libp2p/core/host"
19
26
"github.com/libp2p/go-libp2p/core/peer"
20
27
"github.com/libp2p/go-libp2p/core/protocol"
21
28
"github.com/libp2p/go-libp2p/p2p/net/connmgr"
29
+ multiaddr "github.com/multiformats/go-multiaddr"
22
30
manet "github.com/multiformats/go-multiaddr/net"
23
31
"github.com/multiformats/go-multihash"
24
32
"github.com/prometheus/client_golang/prometheus"
25
33
"github.com/stretchr/testify/require"
26
34
)
27
35
36
+ type trustlessGateway struct {
37
+ bstore blockstore.Blockstore
38
+ }
39
+
40
+ // A HTTP server for blocks in a blockstore.
41
+ func (h * trustlessGateway ) ServeHTTP (rw http.ResponseWriter , r * http.Request ) {
42
+ path := r .URL .Path
43
+ _ , cidstr , ok := strings .Cut (path , "/ipfs/" )
44
+ if ! ok {
45
+ rw .WriteHeader (http .StatusBadRequest )
46
+ return
47
+ }
48
+
49
+ if cidstr == "bafkqaaa" {
50
+ rw .WriteHeader (http .StatusOK )
51
+ return
52
+ }
53
+
54
+ c , err := cid .Parse (cidstr )
55
+ if err != nil {
56
+ rw .WriteHeader (http .StatusBadRequest )
57
+ return
58
+ }
59
+
60
+ b , err := h .bstore .Get (r .Context (), c )
61
+ if errors .Is (err , ipld.ErrNotFound {}) {
62
+ rw .WriteHeader (http .StatusNotFound )
63
+ return
64
+ }
65
+ if err != nil {
66
+ rw .WriteHeader (http .StatusInternalServerError )
67
+ return
68
+ }
69
+
70
+ rw .WriteHeader (http .StatusOK )
71
+ if r .Method == "HEAD" {
72
+ return
73
+ }
74
+
75
+ rw .Write (b .RawData ())
76
+ }
77
+
78
+ type httpRouting struct {
79
+ bstore blockstore.Blockstore
80
+ addrs []multiaddr.Multiaddr
81
+ id peer.ID
82
+ }
83
+
84
+ // A HTTP server for blocks in a blockstore.
85
+ func (h * httpRouting ) ServeHTTP (rw http.ResponseWriter , r * http.Request ) {
86
+ path := r .URL .Path
87
+ _ , cidstr , ok := strings .Cut (path , "/routing/v1/providers/" )
88
+ if ! ok {
89
+ rw .WriteHeader (http .StatusBadRequest )
90
+ return
91
+ }
92
+
93
+ c , err := cid .Parse (cidstr )
94
+ if err != nil {
95
+ rw .WriteHeader (http .StatusBadRequest )
96
+ return
97
+ }
98
+
99
+ _ , err = h .bstore .Get (r .Context (), c )
100
+ if errors .Is (err , ipld.ErrNotFound {}) {
101
+ rw .WriteHeader (http .StatusNotFound )
102
+ return
103
+ }
104
+ if err != nil {
105
+ rw .WriteHeader (http .StatusInternalServerError )
106
+ return
107
+ }
108
+ rw .Header ().Set ("Content-Type" , "application/x-ndjson" )
109
+ rw .WriteHeader (http .StatusOK )
110
+ jaddrs , _ := json .Marshal (h .addrs )
111
+ resp := `
112
+ {
113
+ "Schema": "peer",
114
+ "ID": "` + h .id .String () + `",
115
+ "Addrs": ` + string (jaddrs ) + `,
116
+ "Protocols": ["transport-ipfs-gateway-http"]
117
+ }
118
+ `
119
+ fmt .Println (resp )
120
+ rw .Write ([]byte (resp ))
121
+ }
122
+
28
123
func TestBasicIntegration (t * testing.T ) {
29
124
ctx , cancel := context .WithCancel (context .Background ())
30
125
defer cancel ()
@@ -95,6 +190,30 @@ func TestBasicIntegration(t *testing.T) {
95
190
require .NoError (t , err )
96
191
hostAddr := mas [0 ]
97
192
193
+ gw := & trustlessGateway {
194
+ bstore : bstore ,
195
+ }
196
+ httpServer := httptest .NewUnstartedServer (gw )
197
+ httpServer .EnableHTTP2 = true
198
+ httpServer .StartTLS ()
199
+ maddr , err := manet .FromNetAddr (httpServer .Listener .Addr ())
200
+ require .NoError (t , err )
201
+ httpAddr , err := multiaddr .NewMultiaddr ("/https" )
202
+ require .NoError (t , err )
203
+ peerAddr , err := multiaddr .NewMultiaddr ("/p2p/" + h .ID ().String ())
204
+ require .NoError (t , err )
205
+ httpPeerAddr := maddr .Encapsulate (httpAddr ).Encapsulate (peerAddr )
206
+
207
+ rt := & httpRouting {
208
+ bstore : bstore ,
209
+ addrs : []multiaddr.Multiaddr {maddr .Encapsulate (httpAddr )},
210
+ id : h .ID (),
211
+ }
212
+
213
+ routingServer := httptest .NewUnstartedServer (rt )
214
+ routingServer .Start ()
215
+ ipniAddr := "http://" + routingServer .Listener .Addr ().String ()
216
+
98
217
t .Run ("Data on reachable peer that's advertised" , func (t * testing.T ) {
99
218
testData := []byte (t .Name ())
100
219
mh , err := multihash .Sum (testData , multihash .SHA2_256 , - 1 )
@@ -184,4 +303,35 @@ func TestBasicIntegration(t *testing.T) {
184
303
res .Value (0 ).Object ().Value ("DataAvailableOverBitswap" ).Object ().Value ("Found" ).Boolean ().IsTrue ()
185
304
res .Value (0 ).Object ().Value ("DataAvailableOverBitswap" ).Object ().Value ("Responded" ).Boolean ().IsTrue ()
186
305
})
306
+
307
+ t .Run ("Data found via HTTP" , func (t * testing.T ) {
308
+ testData := []byte (t .Name ())
309
+ mh , err := multihash .Sum (testData , multihash .SHA2_256 , - 1 )
310
+ require .NoError (t , err )
311
+ testCid := cid .NewCidV1 (cid .Raw , mh )
312
+ testBlock , err := blocks .NewBlockWithCid (testData , testCid )
313
+ require .NoError (t , err )
314
+ err = bstore .Put (ctx , testBlock )
315
+ require .NoError (t , err )
316
+
317
+ obj := test .Query (t , "http://localhost:1234" , testCid .String (), httpPeerAddr .String (), "httpRetrieval=on" )
318
+ obj .Value ("DataAvailableOverHTTP" ).Object ().Value ("Found" ).Boolean ().IsTrue ()
319
+ })
320
+
321
+ t .Run ("Data found via HTTP with just CID" , func (t * testing.T ) {
322
+ testData := []byte (t .Name ())
323
+ mh , err := multihash .Sum (testData , multihash .SHA2_256 , - 1 )
324
+ require .NoError (t , err )
325
+ testCid := cid .NewCidV1 (cid .Raw , mh )
326
+ testBlock , err := blocks .NewBlockWithCid (testData , testCid )
327
+ require .NoError (t , err )
328
+ err = bstore .Put (ctx , testBlock )
329
+ require .NoError (t , err )
330
+
331
+ fmt .Println (ipniAddr )
332
+ fmt .Println (httpAddr .String ())
333
+ obj := test .QueryCid (t , "http://localhost:1234" , testCid .String (), "httpRetrieval=on" , "ipniIndexer=" + ipniAddr )
334
+ obj .Value (0 ).Object ().Value ("DataAvailableOverHTTP" ).Object ().Value ("Found" ).Boolean ().IsTrue ()
335
+ })
336
+
187
337
}
0 commit comments