path.go
1 package coreapi 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 8 "github.com/ipfs/boxo/namesys" 9 "github.com/ipfs/kubo/tracing" 10 11 "go.opentelemetry.io/otel/attribute" 12 "go.opentelemetry.io/otel/trace" 13 14 "github.com/ipfs/boxo/path" 15 ipfspathresolver "github.com/ipfs/boxo/path/resolver" 16 ipld "github.com/ipfs/go-ipld-format" 17 coreiface "github.com/ipfs/kubo/core/coreiface" 18 ) 19 20 // ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the 21 // resolved Node. 22 func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, error) { 23 ctx, span := tracing.Span(ctx, "CoreAPI", "ResolveNode", trace.WithAttributes(attribute.String("path", p.String()))) 24 defer span.End() 25 26 rp, _, err := api.ResolvePath(ctx, p) 27 if err != nil { 28 return nil, err 29 } 30 31 node, err := api.dag.Get(ctx, rp.RootCid()) 32 if err != nil { 33 return nil, err 34 } 35 return node, nil 36 } 37 38 // ResolvePath resolves the path `p` using Unixfs resolver, returns the 39 // resolved path. 40 func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.ImmutablePath, []string, error) { 41 ctx, span := tracing.Span(ctx, "CoreAPI", "ResolvePath", trace.WithAttributes(attribute.String("path", p.String()))) 42 defer span.End() 43 44 res, err := namesys.Resolve(ctx, api.namesys, p) 45 if errors.Is(err, namesys.ErrNoNamesys) { 46 return path.ImmutablePath{}, nil, coreiface.ErrOffline 47 } else if err != nil { 48 return path.ImmutablePath{}, nil, err 49 } 50 p = res.Path 51 52 var resolver ipfspathresolver.Resolver 53 switch p.Namespace() { 54 case path.IPLDNamespace: 55 resolver = api.ipldPathResolver 56 case path.IPFSNamespace: 57 resolver = api.unixFSPathResolver 58 default: 59 return path.ImmutablePath{}, nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace()) 60 } 61 62 imPath, err := path.NewImmutablePath(p) 63 if err != nil { 64 return path.ImmutablePath{}, nil, err 65 } 66 67 node, remainder, err := resolver.ResolveToLastNode(ctx, imPath) 68 if err != nil { 69 return path.ImmutablePath{}, nil, err 70 } 71 72 segments := []string{p.Namespace(), node.String()} 73 segments = append(segments, remainder...) 74 75 p, err = path.NewPathFromSegments(segments...) 76 if err != nil { 77 return path.ImmutablePath{}, nil, err 78 } 79 80 imPath, err = path.NewImmutablePath(p) 81 if err != nil { 82 return path.ImmutablePath{}, nil, err 83 } 84 85 return imPath, remainder, nil 86 }