Skip to content

Commit

Permalink
coreapi: be more flexible about inputs
Browse files Browse the repository at this point in the history
While coreapi functions previously only accepted path strings,
they now accept anything from Path structs and strings,
Multihash structs and strings, and most notably: Cid structs,
strings and byte arrays. See go-cid.Parse() for more information.

If the argument is a string containing at least one forward-slash,
it's treated as a path and resolved accordingly, i.e. including
IPNS resolution and link traversal.

Anything else will be parsed as a Cid and fetched directly using DAG.Get().

This change makes various use cases of the Core API more efficient,
since there's no more need for expensive string/Path/Cid conversions.

License: MIT
Signed-off-by: Lars Gierth <[email protected]>
  • Loading branch information
Lars Gierth committed Dec 9, 2016
1 parent e1c190a commit 2e15ba9
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
42 changes: 36 additions & 6 deletions core/coreapi/coreapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package coreapi

import (
"context"
"strings"

core "github.com/ipfs/go-ipfs/core"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
path "github.com/ipfs/go-ipfs/path"

ipld "gx/ipfs/QmRSU5EqqWVZSNdbU51yXmVoF1uNw3JgTNB6RaiL7DZM16/go-ipld-node"
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
)

type CoreAPI struct {
Expand All @@ -23,17 +25,45 @@ func (api *CoreAPI) Unixfs() coreiface.UnixfsAPI {
return (*UnixfsAPI)(api)
}

func resolve(ctx context.Context, n *core.IpfsNode, p string) (ipld.Node, error) {
func resolve(ctx context.Context, n *core.IpfsNode, ref coreiface.Ref) (ipld.Node, error) {
switch v := ref.(type) {
case string:
if strings.Contains(v, "/") {
return resolvePath(ctx, n, v)
}
}
return resolveCid(ctx, n, ref)
}

func resolvePath(ctx context.Context, n *core.IpfsNode, p string) (ipld.Node, error) {
pp, err := path.ParsePath(p)
if err != nil {
return nil, err
}

dagnode, err := core.Resolve(ctx, n.Namesys, n.Resolver, pp)
if err == core.ErrNoNamesys {
return nil, coreiface.ErrOffline
} else if err != nil {
node, err := core.Resolve(ctx, n.Namesys, n.Resolver, pp)
if err != nil {
return nil, resolveError(err)
}
return node, nil
}

func resolveCid(ctx context.Context, n *core.IpfsNode, ref coreiface.Ref) (ipld.Node, error) {
c, err := cid.Parse(ref)
if err != nil {
return nil, err
}
return dagnode, nil

node, err := n.DAG.Get(ctx, c)
if err != nil {
return nil, resolveError(err)
}
return node, nil
}

func resolveError(err error) error {
if err == core.ErrNoNamesys {
return coreiface.ErrOffline
}
return err
}
6 changes: 4 additions & 2 deletions core/coreapi/interface/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
)

type Ref interface{}

type Link ipld.Link

type Reader interface {
Expand All @@ -22,8 +24,8 @@ type CoreAPI interface {

type UnixfsAPI interface {
Add(context.Context, io.Reader) (*cid.Cid, error)
Cat(context.Context, string) (Reader, error)
Ls(context.Context, string) ([]*Link, error)
Cat(context.Context, Ref) (Reader, error)
Ls(context.Context, Ref) ([]*Link, error)
}

// type ObjectAPI interface {
Expand Down
8 changes: 4 additions & 4 deletions core/coreapi/unixfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (*cid.Cid, error) {
return cid.Decode(k)
}

func (api *UnixfsAPI) Cat(ctx context.Context, p string) (coreiface.Reader, error) {
dagnode, err := resolve(ctx, api.node, p)
func (api *UnixfsAPI) Cat(ctx context.Context, ref coreiface.Ref) (coreiface.Reader, error) {
dagnode, err := resolve(ctx, api.node, ref)
if err != nil {
return nil, err
}
Expand All @@ -36,8 +36,8 @@ func (api *UnixfsAPI) Cat(ctx context.Context, p string) (coreiface.Reader, erro
return r, nil
}

func (api *UnixfsAPI) Ls(ctx context.Context, p string) ([]*coreiface.Link, error) {
dagnode, err := resolve(ctx, api.node, p)
func (api *UnixfsAPI) Ls(ctx context.Context, ref coreiface.Ref) ([]*coreiface.Link, error) {
dagnode, err := resolve(ctx, api.node, ref)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 2e15ba9

Please sign in to comment.