From 87cb6a201b3ed811f414fa3017463bc1bd081389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 8 Feb 2018 17:39:05 +0100 Subject: [PATCH] coreapi: separate path into two types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Ɓukasz Magiera --- core/coreapi/block.go | 23 +++++-- core/coreapi/coreapi.go | 4 +- core/coreapi/dag.go | 4 +- core/coreapi/dag_test.go | 2 +- core/coreapi/interface/interface.go | 49 ++++++++------- core/coreapi/interface/options/path.go | 30 ---------- core/coreapi/object.go | 12 ++-- core/coreapi/path.go | 83 ++++++++++++-------------- core/coreapi/pin.go | 44 ++++++++------ core/coreapi/unixfs.go | 2 +- core/coreapi/unixfs_test.go | 58 ++++++++++++------ core/corehttp/gateway_handler.go | 2 +- path/path.go | 2 +- 13 files changed, 167 insertions(+), 148 deletions(-) delete mode 100644 core/coreapi/interface/options/path.go diff --git a/core/coreapi/block.go b/core/coreapi/block.go index f5bcc1a88ee..213829428ce 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -27,7 +27,7 @@ type BlockStat struct { size int } -func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.BlockPutOption) (coreiface.Path, error) { +func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.BlockPutOption) (coreiface.ResolvedPath, error) { settings, err := caopts.BlockPutOptions(opts...) if err != nil { return nil, err @@ -72,7 +72,12 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc } func (api *BlockAPI) Get(ctx context.Context, p coreiface.Path) (io.Reader, error) { - b, err := api.node.Blocks.GetBlock(ctx, p.Cid()) + rp, err := api.ResolvePath(ctx, p) + if err != nil { + return nil, err + } + + b, err := api.node.Blocks.GetBlock(ctx, rp.Cid()) if err != nil { return nil, err } @@ -81,11 +86,16 @@ func (api *BlockAPI) Get(ctx context.Context, p coreiface.Path) (io.Reader, erro } func (api *BlockAPI) Rm(ctx context.Context, p coreiface.Path, opts ...caopts.BlockRmOption) error { + rp, err := api.ResolvePath(ctx, p) + if err != nil { + return err + } + settings, err := caopts.BlockRmOptions(opts...) if err != nil { return err } - cids := []*cid.Cid{p.Cid()} + cids := []*cid.Cid{rp.Cid()} o := util.RmBlocksOpts{Force: settings.Force} out, err := util.RmBlocks(api.node.Blockstore, api.node.Pinning, cids, o) @@ -116,7 +126,12 @@ func (api *BlockAPI) Rm(ctx context.Context, p coreiface.Path, opts ...caopts.Bl } func (api *BlockAPI) Stat(ctx context.Context, p coreiface.Path) (coreiface.BlockStat, error) { - b, err := api.node.Blocks.GetBlock(ctx, p.Cid()) + rp, err := api.ResolvePath(ctx, p) + if err != nil { + return nil, err + } + + b, err := api.node.Blocks.GetBlock(ctx, rp.Cid()) if err != nil { return nil, err } diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index ed3c5596021..8658b00bc72 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -3,17 +3,15 @@ package coreapi import ( core "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) type CoreAPI struct { node *core.IpfsNode - *caopts.ApiOptions } // NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node. func NewCoreAPI(n *core.IpfsNode) coreiface.CoreAPI { - api := &CoreAPI{n, nil} + api := &CoreAPI{n} return api } diff --git a/core/coreapi/dag.go b/core/coreapi/dag.go index 41baaad65ab..8ae69c285fa 100644 --- a/core/coreapi/dag.go +++ b/core/coreapi/dag.go @@ -22,7 +22,7 @@ type DagAPI struct { // Put inserts data using specified format and input encoding. Unless used with // `WithCodes` or `WithHash`, the defaults "dag-cbor" and "sha256" are used. // Returns the path of the inserted data. -func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPutOption) (coreiface.Path, error) { +func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPutOption) (coreiface.ResolvedPath, error) { settings, err := caopts.DagPutOptions(opts...) if err != nil { return nil, err @@ -68,7 +68,7 @@ func (api *DagAPI) Tree(ctx context.Context, p coreiface.Path, opts ...caopts.Da paths := n.Tree("", settings.Depth) out := make([]coreiface.Path, len(paths)) for n, p2 := range paths { - out[n], err = api.ParsePath(ctx, gopath.Join(p.String(), p2)) + out[n], err = api.ParsePath(gopath.Join(p.String(), p2)) if err != nil { return nil, err } diff --git a/core/coreapi/dag_test.go b/core/coreapi/dag_test.go index 3a1a5db2dbd..5b5fa17f3e6 100644 --- a/core/coreapi/dag_test.go +++ b/core/coreapi/dag_test.go @@ -70,7 +70,7 @@ func TestPath(t *testing.T) { t.Error(err) } - p, err := api.ParsePath(ctx, path.Join(res.Cid().String(), "lnk")) + p, err := api.ParsePath(path.Join(res.Cid().String(), "lnk")) if err != nil { t.Error(err) } diff --git a/core/coreapi/interface/interface.go b/core/coreapi/interface/interface.go index 275f7ce696e..bee12c2d0f1 100644 --- a/core/coreapi/interface/interface.go +++ b/core/coreapi/interface/interface.go @@ -16,15 +16,26 @@ import ( // Path is a generic wrapper for paths used in the API. A path can be resolved // to a CID using one of Resolve functions in the API. +// TODO: figure out/explain namespaces type Path interface { // String returns the path as a string. String() string + + // Namespace returns the first component of the path + Namespace() string +} + +// ResolvedPath is a resolved Path +type ResolvedPath interface { // Cid returns cid referred to by path Cid() *cid.Cid + // Root returns cid of root path Root() *cid.Cid - // Resolved returns whether path has been fully resolved - Resolved() bool + + //TODO: Path remainder + + Path } // TODO: should we really copy these? @@ -61,7 +72,7 @@ type BlockStat interface { // Pin holds information about pinned resource type Pin interface { // Path to the pinned object - Path() Path + Path() ResolvedPath // Type of the pin Type() string @@ -79,7 +90,7 @@ type PinStatus interface { // BadPinNode is a node that has been marked as bad by Pin.Verify type BadPinNode interface { // Path is the path of the node - Path() Path + Path() ResolvedPath // Err is the reason why the node has been marked as bad Err() error @@ -101,33 +112,31 @@ type CoreAPI interface { // Key returns an implementation of Key API. Key() KeyAPI + + // Pin returns an implementation of Pin API Pin() PinAPI // ObjectAPI returns an implementation of Object API Object() ObjectAPI // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, Path) (Path, error) + ResolvePath(context.Context, Path) (ResolvedPath, error) // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node ResolveNode(context.Context, Path) (Node, error) // ParsePath parses string path to a Path - ParsePath(context.Context, string, ...options.ParsePathOption) (Path, error) - - // WithResolve is an option for ParsePath which when set to true tells - // ParsePath to also resolve the path - WithResolve(bool) options.ParsePathOption + ParsePath(string) (Path, error) // ParseCid creates new path from the provided CID - ParseCid(*cid.Cid) Path + ParseCid(*cid.Cid) ResolvedPath } // UnixfsAPI is the basic interface to immutable files in IPFS type UnixfsAPI interface { // Add imports the data from the reader into merkledag file - Add(context.Context, io.Reader) (Path, error) + Add(context.Context, io.Reader) (ResolvedPath, error) // Cat returns a reader for the file Cat(context.Context, Path) (Reader, error) @@ -139,7 +148,7 @@ type UnixfsAPI interface { // BlockAPI specifies the interface to the block layer type BlockAPI interface { // Put imports raw block data, hashing it using specified settings. - Put(context.Context, io.Reader, ...options.BlockPutOption) (Path, error) + Put(context.Context, io.Reader, ...options.BlockPutOption) (ResolvedPath, error) // WithFormat is an option for Put which specifies the multicodec to use to // serialize the object. Default is "v0" @@ -173,7 +182,7 @@ type DagAPI interface { // Put inserts data using specified format and input encoding. // Unless used with WithCodec or WithHash, the defaults "dag-cbor" and // "sha256" are used. - Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (Path, error) + Put(ctx context.Context, src io.Reader, opts ...options.DagPutOption) (ResolvedPath, error) // WithInputEnc is an option for Put which specifies the input encoding of the // data. Default is "json", most formats/codecs support "raw" @@ -290,13 +299,13 @@ type ObjectAPI interface { WithType(string) options.ObjectNewOption // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (Path, error) + Put(context.Context, io.Reader, ...options.ObjectPutOption) (ResolvedPath, error) // WithInputEnc is an option for Put which specifies the input encoding of the // data. Default is "json". // // Supported encodings: - // * "protobuf" + // * "protobuf"reselved version of Path // * "json" WithInputEnc(e string) options.ObjectPutOption @@ -323,20 +332,20 @@ type ObjectAPI interface { // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). - AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Path, error) + AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (ResolvedPath, error) // WithCreate is an option for AddLink which specifies whether create required // directories for the child WithCreate(create bool) options.ObjectAddLinkOption // RmLink removes a link from the node - RmLink(ctx context.Context, base Path, link string) (Path, error) + RmLink(ctx context.Context, base Path, link string) (ResolvedPath, error) // AppendData appends data to the node - AppendData(context.Context, Path, io.Reader) (Path, error) + AppendData(context.Context, Path, io.Reader) (ResolvedPath, error) // SetData sets the data contained in the node - SetData(context.Context, Path, io.Reader) (Path, error) + SetData(context.Context, Path, io.Reader) (ResolvedPath, error) } // ObjectStat provides information about dag nodes diff --git a/core/coreapi/interface/options/path.go b/core/coreapi/interface/options/path.go deleted file mode 100644 index bf6eed65b8c..00000000000 --- a/core/coreapi/interface/options/path.go +++ /dev/null @@ -1,30 +0,0 @@ -package options - -type ParsePathSettings struct { - Resolve bool -} - -type ParsePathOption func(*ParsePathSettings) error - -func ParsePathOptions(opts ...ParsePathOption) (*ParsePathSettings, error) { - options := &ParsePathSettings{ - Resolve: false, - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - -type ApiOptions struct{} - -func (api *ApiOptions) WithResolve(r bool) ParsePathOption { - return func(settings *ParsePathSettings) error { - settings.Resolve = r - return nil - } -} diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 599ca3a3cd0..74c20518a94 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -59,7 +59,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( return n, nil } -func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (coreiface.Path, error) { +func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (coreiface.ResolvedPath, error) { options, err := caopts.ObjectPutOptions(opts...) if err != nil { return nil, err @@ -183,7 +183,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, path coreiface.Path) (*coreiface return out, nil } -func (api *ObjectAPI) AddLink(ctx context.Context, base coreiface.Path, name string, child coreiface.Path, opts ...caopts.ObjectAddLinkOption) (coreiface.Path, error) { +func (api *ObjectAPI) AddLink(ctx context.Context, base coreiface.Path, name string, child coreiface.Path, opts ...caopts.ObjectAddLinkOption) (coreiface.ResolvedPath, error) { options, err := caopts.ObjectAddLinkOptions(opts...) if err != nil { return nil, err @@ -224,7 +224,7 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base coreiface.Path, name str return api.ParseCid(nnode.Cid()), nil } -func (api *ObjectAPI) RmLink(ctx context.Context, base coreiface.Path, link string) (coreiface.Path, error) { +func (api *ObjectAPI) RmLink(ctx context.Context, base coreiface.Path, link string) (coreiface.ResolvedPath, error) { baseNd, err := api.core().ResolveNode(ctx, base) if err != nil { return nil, err @@ -250,15 +250,15 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base coreiface.Path, link stri return api.ParseCid(nnode.Cid()), nil } -func (api *ObjectAPI) AppendData(ctx context.Context, path coreiface.Path, r io.Reader) (coreiface.Path, error) { +func (api *ObjectAPI) AppendData(ctx context.Context, path coreiface.Path, r io.Reader) (coreiface.ResolvedPath, error) { return api.patchData(ctx, path, r, true) } -func (api *ObjectAPI) SetData(ctx context.Context, path coreiface.Path, r io.Reader) (coreiface.Path, error) { +func (api *ObjectAPI) SetData(ctx context.Context, path coreiface.Path, r io.Reader) (coreiface.ResolvedPath, error) { return api.patchData(ctx, path, r, false) } -func (api *ObjectAPI) patchData(ctx context.Context, path coreiface.Path, r io.Reader, appendData bool) (coreiface.Path, error) { +func (api *ObjectAPI) patchData(ctx context.Context, path coreiface.Path, r io.Reader, appendData bool) (coreiface.ResolvedPath, error) { nd, err := api.core().ResolveNode(ctx, path) if err != nil { return nil, err diff --git a/core/coreapi/path.go b/core/coreapi/path.go index 11175b37431..dbfb28f614d 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -5,7 +5,6 @@ import ( core "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" namesys "github.com/ipfs/go-ipfs/namesys" ipfspath "github.com/ipfs/go-ipfs/path" uio "github.com/ipfs/go-ipfs/unixfs/io" @@ -14,35 +13,51 @@ import ( ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" ) +// path implements coreiface.Path +type path struct { + path ipfspath.Path +} + +// resolvedPath implements coreiface.resolvedPath +type resolvedPath struct { + path + cid *cid.Cid + root *cid.Cid +} + +// ParseCid parses the path from `c`, retruns the parsed path. +func (api *CoreAPI) ParseCid(c *cid.Cid) coreiface.ResolvedPath { + return &resolvedPath{path: path{ipfspath.FromCid(c)}, cid: c, root: c} +} + // ResolveNode resolves the path `p` using Unixfx resolver, gets and returns the // resolved Node. func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreiface.Node, error) { return resolveNode(ctx, api.node.DAG, api.node.Namesys, p) } +// ResolvePath resolves the path `p` using Unixfs resolver, returns the +// resolved path. +func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreiface.ResolvedPath, error) { + return resolvePath(ctx, api.node.DAG, api.node.Namesys, p) +} + func resolveNode(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSystem, p coreiface.Path) (coreiface.Node, error) { - p, err := resolvePath(ctx, ng, nsys, p) + rp, err := resolvePath(ctx, ng, nsys, p) if err != nil { return nil, err } - node, err := ng.Get(ctx, p.Cid()) + node, err := ng.Get(ctx, rp.Cid()) if err != nil { return nil, err } return node, nil } -// ResolvePath resolves the path `p` using Unixfs resolver, returns the -// resolved path. -// TODO: store all of ipfspath.Resolver.ResolvePathComponents() in Path -func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreiface.Path, error) { - return resolvePath(ctx, api.node.DAG, api.node.Namesys, p) -} - -func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSystem, p coreiface.Path) (coreiface.Path, error) { - if p.Resolved() { - return p, nil +func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSystem, p coreiface.Path) (coreiface.ResolvedPath, error) { + if _, ok := p.(coreiface.ResolvedPath); ok { + return p.(coreiface.ResolvedPath), nil } r := &ipfspath.Resolver{ @@ -63,46 +78,26 @@ func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSyste root = node.Cid() } - return ResolvedPath(p.String(), node.Cid(), root), nil -} - -// Implements coreiface.Path -type path struct { - path ipfspath.Path - cid *cid.Cid - root *cid.Cid + return &resolvedPath{path: path{p2}, cid: node.Cid(), root: root}, nil } // ParsePath parses path `p` using ipfspath parser, returns the parsed path. -func (api *CoreAPI) ParsePath(ctx context.Context, p string, opts ...caopts.ParsePathOption) (coreiface.Path, error) { - options, err := caopts.ParsePathOptions(opts...) - if err != nil { - return nil, err - } - +func (api *CoreAPI) ParsePath(p string) (coreiface.Path, error) { pp, err := ipfspath.ParsePath(p) if err != nil { return nil, err } - res := &path{path: pp} - if options.Resolve { - return api.ResolvePath(ctx, res) - } - return res, nil + return &path{path: pp}, nil } -// ParseCid parses the path from `c`, retruns the parsed path. -func (api *CoreAPI) ParseCid(c *cid.Cid) coreiface.Path { - return &path{path: ipfspath.FromCid(c), cid: c, root: c} -} - -// ResolvePath parses path from string `p`, returns parsed path. -func ResolvedPath(p string, c *cid.Cid, r *cid.Cid) coreiface.Path { - return &path{path: ipfspath.FromString(p), cid: c, root: r} +func (p *path) String() string { return p.path.String() } +func (p *path) Namespace() string { + if len(p.path.Segments()) < 1 { + return "" + } + return p.path.Segments()[0] } -func (p *path) String() string { return p.path.String() } -func (p *path) Cid() *cid.Cid { return p.cid } -func (p *path) Root() *cid.Cid { return p.root } -func (p *path) Resolved() bool { return p.cid != nil } +func (p *resolvedPath) Cid() *cid.Cid { return p.cid } +func (p *resolvedPath) Root() *cid.Cid { return p.root } diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index 61768999e07..cf2d4749d7f 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -10,10 +10,8 @@ import ( corerepo "github.com/ipfs/go-ipfs/core/corerepo" offline "github.com/ipfs/go-ipfs/exchange/offline" merkledag "github.com/ipfs/go-ipfs/merkledag" - pin "github.com/ipfs/go-ipfs/pin" cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid" - ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format" ) type PinAPI struct { @@ -49,7 +47,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]coreif return nil, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.Type) } - return pinLsAll(settings.Type, ctx, api.node.Pinning, api.node.DAG) + return api.pinLsAll(settings.Type, ctx) } func (api *PinAPI) Rm(ctx context.Context, p coreiface.Path) error { @@ -67,7 +65,17 @@ func (api *PinAPI) Update(ctx context.Context, from coreiface.Path, to coreiface return err } - return api.node.Pinning.Update(ctx, from.Cid(), to.Cid(), settings.Unpin) + fp, err := api.ResolvePath(ctx, from) + if err != nil { + return err + } + + tp, err := api.ResolvePath(ctx, to) + if err != nil { + return err + } + + return api.node.Pinning.Update(ctx, fp.Cid(), tp.Cid(), settings.Unpin) } type pinStatus struct { @@ -78,8 +86,8 @@ type pinStatus struct { // BadNode is used in PinVerifyRes type badNode struct { - cid *cid.Cid - err error + path coreiface.ResolvedPath + err error } func (s *pinStatus) Ok() bool { @@ -90,8 +98,8 @@ func (s *pinStatus) BadNodes() []coreiface.BadPinNode { return s.badNodes } -func (n *badNode) Path() coreiface.Path { - return ParseCid(n.cid) +func (n *badNode) Path() coreiface.ResolvedPath { + return n.path } func (n *badNode) Err() error { @@ -115,7 +123,7 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro links, err := getLinks(ctx, root) if err != nil { status := &pinStatus{ok: false, cid: root} - status.badNodes = []coreiface.BadPinNode{&badNode{cid: root, err: err}} + status.badNodes = []coreiface.BadPinNode{&badNode{path: api.ParseCid(root), err: err}} visited[key] = status return status } @@ -146,18 +154,18 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro type pinInfo struct { pinType string - object *cid.Cid + path coreiface.ResolvedPath } -func (p *pinInfo) Path() coreiface.Path { - return ParseCid(p.object) +func (p *pinInfo) Path() coreiface.ResolvedPath { + return p.path } func (p *pinInfo) Type() string { return p.pinType } -func pinLsAll(typeStr string, ctx context.Context, pinning pin.Pinner, dag ipld.DAGService) ([]coreiface.Pin, error) { +func (api *PinAPI) pinLsAll(typeStr string, ctx context.Context) ([]coreiface.Pin, error) { keys := make(map[string]*pinInfo) @@ -165,18 +173,18 @@ func pinLsAll(typeStr string, ctx context.Context, pinning pin.Pinner, dag ipld. for _, c := range keyList { keys[c.String()] = &pinInfo{ pinType: typeStr, - object: c, + path: api.ParseCid(c), } } } if typeStr == "direct" || typeStr == "all" { - AddToResultKeys(pinning.DirectKeys(), "direct") + AddToResultKeys(api.node.Pinning.DirectKeys(), "direct") } if typeStr == "indirect" || typeStr == "all" { set := cid.NewSet() - for _, k := range pinning.RecursiveKeys() { - err := merkledag.EnumerateChildren(ctx, merkledag.GetLinksWithDAG(dag), k, set.Visit) + for _, k := range api.node.Pinning.RecursiveKeys() { + err := merkledag.EnumerateChildren(ctx, merkledag.GetLinksWithDAG(api.node.DAG), k, set.Visit) if err != nil { return nil, err } @@ -184,7 +192,7 @@ func pinLsAll(typeStr string, ctx context.Context, pinning pin.Pinner, dag ipld. AddToResultKeys(set.Keys(), "indirect") } if typeStr == "recursive" || typeStr == "all" { - AddToResultKeys(pinning.RecursiveKeys(), "recursive") + AddToResultKeys(api.node.Pinning.RecursiveKeys(), "recursive") } out := make([]coreiface.Pin, 0, len(keys)) diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index eb3d12b6ddd..659e8dfdc61 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -17,7 +17,7 @@ type UnixfsAPI CoreAPI // Add builds a merkledag node from a reader, adds it to the blockstore, // and returns the key representing that node. -func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.Path, error) { +func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.ResolvedPath, error) { k, err := coreunix.AddWithContext(ctx, api.node, r) if err != nil { return nil, err diff --git a/core/coreapi/unixfs_test.go b/core/coreapi/unixfs_test.go index 806082c0dbc..3e08ce74c6f 100644 --- a/core/coreapi/unixfs_test.go +++ b/core/coreapi/unixfs_test.go @@ -28,14 +28,11 @@ import ( const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" // `echo -n 'hello, world!' | ipfs add` -var hello = coreapi.ResolvedPath("/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk", nil, nil) +var hello = "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" var helloStr = "hello, world!" -// `ipfs object new unixfs-dir` -var emptyDir = coreapi.ResolvedPath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn", nil, nil) - // `echo -n | ipfs add` -var emptyFile = coreapi.ResolvedPath("/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH", nil, nil) +var emptyFile = "/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" func makeAPIIdent(ctx context.Context, fullIdentity bool) (*core.IpfsNode, coreiface.CoreAPI, error) { var ident config.Identity @@ -97,11 +94,11 @@ func TestAdd(t *testing.T) { t.Error(err) } - if p.String() != hello.String() { + if p.String() != hello { t.Fatalf("expected path %s, got: %s", hello, p) } - r, err := api.Unixfs().Cat(ctx, hello) + r, err := api.Unixfs().Cat(ctx, p) if err != nil { t.Fatal(err) } @@ -129,7 +126,7 @@ func TestAddEmptyFile(t *testing.T) { t.Error(err) } - if p.String() != emptyFile.String() { + if p.String() != emptyFile { t.Fatalf("expected path %s, got: %s", hello, p) } } @@ -148,11 +145,16 @@ func TestCatBasic(t *testing.T) { } p = "/ipfs/" + p - if p != hello.String() { + if p != hello { t.Fatalf("expected CID %s, got: %s", hello, p) } - r, err := api.Unixfs().Cat(ctx, hello) + helloPath, err := api.ParsePath(hello) + if err != nil { + t.Fatal(err) + } + + r, err := api.Unixfs().Cat(ctx, helloPath) if err != nil { t.Fatal(err) } @@ -179,7 +181,12 @@ func TestCatEmptyFile(t *testing.T) { t.Fatal(err) } - r, err := api.Unixfs().Cat(ctx, emptyFile) + emptyFilePath, err := api.ParsePath(emptyFile) + if err != nil { + t.Fatal(err) + } + + r, err := api.Unixfs().Cat(ctx, emptyFilePath) if err != nil { t.Fatal(err) } @@ -207,11 +214,16 @@ func TestCatDir(t *testing.T) { } p := api.ParseCid(edir.Cid()) - if p.String() != emptyDir.String() { - t.Fatalf("expected path %s, got: %s", emptyDir, p) + emptyDir, err := api.Object().New(ctx, api.Object().WithType("unixfs-dir")) + if err != nil { + t.Error(err) } - _, err = api.Unixfs().Cat(ctx, emptyDir) + if p.String() != api.ParseCid(emptyDir.Cid()).String() { + t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) + } + + _, err = api.Unixfs().Cat(ctx, api.ParseCid(emptyDir.Cid())) if err != coreiface.ErrIsDir { t.Fatalf("expected ErrIsDir, got: %s", err) } @@ -243,7 +255,11 @@ func TestCatOffline(t *testing.T) { t.Error(err) } - _, err = api.Unixfs().Cat(ctx, coreapi.ResolvedPath("/ipns/Qmfoobar", nil, nil)) + p, err := api.ParsePath("/ipns/Qmfoobar") + if err != nil { + t.Error(err) + } + _, err = api.Unixfs().Cat(ctx, p) if err != coreiface.ErrOffline { t.Fatalf("expected ErrOffline, got: %s", err) } @@ -265,7 +281,10 @@ func TestLs(t *testing.T) { if len(parts) != 2 { t.Errorf("unexpected path: %s", k) } - p := coreapi.ResolvedPath("/ipfs/"+parts[0], nil, nil) + p, err := api.ParsePath("/ipfs/" + parts[0]) + if err != nil { + t.Error(err) + } links, err := api.Unixfs().Ls(ctx, p) if err != nil { @@ -298,7 +317,12 @@ func TestLsEmptyDir(t *testing.T) { t.Error(err) } - links, err := api.Unixfs().Ls(ctx, emptyDir) + emptyDir, err := api.Object().New(ctx, api.Object().WithType("unixfs-dir")) + if err != nil { + t.Error(err) + } + + links, err := api.Unixfs().Ls(ctx, api.ParseCid(emptyDir.Cid())) if err != nil { t.Error(err) } diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 66c883d8fe7..dfe5450768b 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -160,7 +160,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr ipnsHostname = true } - parsedPath, err := i.api.ParsePath(ctx, urlPath) + parsedPath, err := i.api.ParsePath(urlPath) if err != nil { webError(w, "invalid ipfs path", err, http.StatusBadRequest) return diff --git a/path/path.go b/path/path.go index decf2890487..341b01201b6 100644 --- a/path/path.go +++ b/path/path.go @@ -96,7 +96,7 @@ func ParsePath(txt string) (Path, error) { if _, err := ParseCidToPath(parts[2]); err != nil { return "", err } - } else if parts[1] != "ipns" { + } else if parts[1] != "ipns" && parts[1] != "ipld" { //TODO: make this smarter return "", ErrBadPath }