11package common
22
33import (
4- "context"
5- "errors"
6- "fmt"
74 "net/http"
8- gopath "path"
95
10- "github.com/ipfs/boxo/blockservice"
11- blockstore "github.com/ipfs/boxo/blockstore"
12- iface "github.com/ipfs/boxo/coreiface"
13- nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
14- ifacepath "github.com/ipfs/boxo/coreiface/path"
15- bsfetcher "github.com/ipfs/boxo/fetcher/impl/blockservice"
16- "github.com/ipfs/boxo/files"
176 "github.com/ipfs/boxo/gateway"
18- "github.com/ipfs/boxo/ipld/merkledag"
19- "github.com/ipfs/boxo/ipld/unixfs"
20- ufile "github.com/ipfs/boxo/ipld/unixfs/file"
21- uio "github.com/ipfs/boxo/ipld/unixfs/io"
22- "github.com/ipfs/boxo/namesys"
23- "github.com/ipfs/boxo/namesys/resolve"
24- ipfspath "github.com/ipfs/boxo/path"
25- "github.com/ipfs/boxo/path/resolver"
26- "github.com/ipfs/go-block-format"
27- "github.com/ipfs/go-cid"
28- format "github.com/ipfs/go-ipld-format"
29- "github.com/ipfs/go-unixfsnode"
30- dagpb "github.com/ipld/go-codec-dagpb"
31- "github.com/ipld/go-ipld-prime"
32- "github.com/ipld/go-ipld-prime/node/basicnode"
33- "github.com/ipld/go-ipld-prime/schema"
34- "github.com/libp2p/go-libp2p/core/peer"
35- "github.com/libp2p/go-libp2p/core/routing"
36- mc "github.com/multiformats/go-multicodec"
377)
388
39- func NewBlocksHandler (gw * BlocksGateway , port int ) http.Handler {
9+ func NewBlocksHandler (gw gateway. IPFSBackend , port int ) http.Handler {
4010 headers := map [string ][]string {}
4111 gateway .AddAccessControlHeaders (headers )
4212
@@ -50,202 +20,3 @@ func NewBlocksHandler(gw *BlocksGateway, port int) http.Handler {
5020 mux .Handle ("/ipns/" , gwHandler )
5121 return mux
5222}
53-
54- type BlocksGateway struct {
55- blockStore blockstore.Blockstore
56- blockService blockservice.BlockService
57- dagService format.DAGService
58- resolver resolver.Resolver
59-
60- // Optional routing system to handle /ipns addresses.
61- namesys namesys.NameSystem
62- routing routing.ValueStore
63- }
64-
65- func NewBlocksGateway (blockService blockservice.BlockService , routing routing.ValueStore ) (* BlocksGateway , error ) {
66- // Setup the DAG services, which use the CAR block store.
67- dagService := merkledag .NewDAGService (blockService )
68-
69- // Setup the UnixFS resolver.
70- fetcherConfig := bsfetcher .NewFetcherConfig (blockService )
71- fetcherConfig .PrototypeChooser = dagpb .AddSupportToChooser (func (lnk ipld.Link , lnkCtx ipld.LinkContext ) (ipld.NodePrototype , error ) {
72- if tlnkNd , ok := lnkCtx .LinkNode .(schema.TypedLinkNode ); ok {
73- return tlnkNd .LinkTargetNodePrototype (), nil
74- }
75- return basicnode .Prototype .Any , nil
76- })
77- fetcher := fetcherConfig .WithReifier (unixfsnode .Reify )
78- resolver := resolver .NewBasicResolver (fetcher )
79-
80- // Setup a name system so that we are able to resolve /ipns links.
81- var (
82- ns namesys.NameSystem
83- err error
84- )
85- if routing != nil {
86- ns , err = namesys .NewNameSystem (routing )
87- if err != nil {
88- return nil , err
89- }
90- }
91-
92- return & BlocksGateway {
93- blockStore : blockService .Blockstore (),
94- blockService : blockService ,
95- dagService : dagService ,
96- resolver : resolver ,
97- routing : routing ,
98- namesys : ns ,
99- }, nil
100- }
101-
102- func (api * BlocksGateway ) GetUnixFsNode (ctx context.Context , p ifacepath.Resolved ) (files.Node , error ) {
103- nd , err := api .resolveNode (ctx , p )
104- if err != nil {
105- return nil , err
106- }
107-
108- return ufile .NewUnixfsFile (ctx , api .dagService , nd )
109- }
110-
111- func (api * BlocksGateway ) LsUnixFsDir (ctx context.Context , p ifacepath.Resolved ) (<- chan iface.DirEntry , error ) {
112- node , err := api .resolveNode (ctx , p )
113- if err != nil {
114- return nil , err
115- }
116-
117- dir , err := uio .NewDirectoryFromNode (api .dagService , node )
118- if err != nil {
119- return nil , err
120- }
121-
122- out := make (chan iface.DirEntry , uio .DefaultShardWidth )
123-
124- go func () {
125- defer close (out )
126- for l := range dir .EnumLinksAsync (ctx ) {
127- select {
128- case out <- api .processLink (ctx , l ):
129- case <- ctx .Done ():
130- return
131- }
132- }
133- }()
134-
135- return out , nil
136- }
137-
138- func (api * BlocksGateway ) GetBlock (ctx context.Context , c cid.Cid ) (blocks.Block , error ) {
139- return api .blockService .GetBlock (ctx , c )
140- }
141-
142- func (api * BlocksGateway ) GetIPNSRecord (ctx context.Context , c cid.Cid ) ([]byte , error ) {
143- if api .routing == nil {
144- return nil , routing .ErrNotSupported
145- }
146-
147- // Fails fast if the CID is not an encoded Libp2p Key, avoids wasteful
148- // round trips to the remote routing provider.
149- if mc .Code (c .Type ()) != mc .Libp2pKey {
150- return nil , errors .New ("provided cid is not an encoded libp2p key" )
151- }
152-
153- // The value store expects the key itself to be encoded as a multihash.
154- id , err := peer .FromCid (c )
155- if err != nil {
156- return nil , err
157- }
158-
159- return api .routing .GetValue (ctx , "/ipns/" + string (id ))
160- }
161-
162- func (api * BlocksGateway ) GetDNSLinkRecord (ctx context.Context , hostname string ) (ifacepath.Path , error ) {
163- if api .namesys != nil {
164- p , err := api .namesys .Resolve (ctx , "/ipns/" + hostname , nsopts .Depth (1 ))
165- if err == namesys .ErrResolveRecursion {
166- err = nil
167- }
168- return ifacepath .New (p .String ()), err
169- }
170-
171- return nil , errors .New ("not implemented" )
172- }
173-
174- func (api * BlocksGateway ) IsCached (ctx context.Context , p ifacepath.Path ) bool {
175- rp , err := api .ResolvePath (ctx , p )
176- if err != nil {
177- return false
178- }
179-
180- has , _ := api .blockStore .Has (ctx , rp .Cid ())
181- return has
182- }
183-
184- func (api * BlocksGateway ) ResolvePath (ctx context.Context , p ifacepath.Path ) (ifacepath.Resolved , error ) {
185- if _ , ok := p .(ifacepath.Resolved ); ok {
186- return p .(ifacepath.Resolved ), nil
187- }
188-
189- err := p .IsValid ()
190- if err != nil {
191- return nil , err
192- }
193-
194- ipath := ipfspath .Path (p .String ())
195- if ipath .Segments ()[0 ] == "ipns" {
196- ipath , err = resolve .ResolveIPNS (ctx , api .namesys , ipath )
197- if err != nil {
198- return nil , err
199- }
200- }
201-
202- if ipath .Segments ()[0 ] != "ipfs" {
203- return nil , fmt .Errorf ("unsupported path namespace: %s" , p .Namespace ())
204- }
205-
206- node , rest , err := api .resolver .ResolveToLastNode (ctx , ipath )
207- if err != nil {
208- return nil , err
209- }
210-
211- root , err := cid .Parse (ipath .Segments ()[1 ])
212- if err != nil {
213- return nil , err
214- }
215-
216- return ifacepath .NewResolvedPath (ipath , node , root , gopath .Join (rest ... )), nil
217- }
218-
219- func (api * BlocksGateway ) resolveNode (ctx context.Context , p ifacepath.Path ) (format.Node , error ) {
220- rp , err := api .ResolvePath (ctx , p )
221- if err != nil {
222- return nil , err
223- }
224-
225- node , err := api .dagService .Get (ctx , rp .Cid ())
226- if err != nil {
227- return nil , fmt .Errorf ("get node: %w" , err )
228- }
229- return node , nil
230- }
231-
232- func (api * BlocksGateway ) processLink (ctx context.Context , result unixfs.LinkResult ) iface.DirEntry {
233- if result .Err != nil {
234- return iface.DirEntry {Err : result .Err }
235- }
236-
237- link := iface.DirEntry {
238- Name : result .Link .Name ,
239- Cid : result .Link .Cid ,
240- }
241-
242- switch link .Cid .Type () {
243- case cid .Raw :
244- link .Type = iface .TFile
245- link .Size = result .Link .Size
246- case cid .DagProtobuf :
247- link .Size = result .Link .Size
248- }
249-
250- return link
251- }
0 commit comments