diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index e766b79ef7a..93b3b073c0c 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -5,9 +5,10 @@ import ( core "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - path "github.com/ipfs/go-ipfs/path" + ipfspath "github.com/ipfs/go-ipfs/path" ipld "gx/ipfs/QmRSU5EqqWVZSNdbU51yXmVoF1uNw3JgTNB6RaiL7DZM16/go-ipld-node" + cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid" ) type CoreAPI struct { @@ -23,17 +24,47 @@ func (api *CoreAPI) Unixfs() coreiface.UnixfsAPI { return (*UnixfsAPI)(api) } -func resolve(ctx context.Context, n *core.IpfsNode, p string) (ipld.Node, error) { - pp, err := path.ParsePath(p) +func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (ipld.Node, error) { + p, err := api.ResolvePath(ctx, p) if err != nil { return nil, err } - dagnode, err := core.Resolve(ctx, n.Namesys, n.Resolver, pp) + node, err := api.node.DAG.Get(ctx, p.Cid()) if err == core.ErrNoNamesys { return nil, coreiface.ErrOffline } else if err != nil { return nil, err } - return dagnode, nil + return node, nil } + +func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreiface.Path, error) { + if p.Resolved() { + return p, nil + } + + c, err := core.ResolveToCid(ctx, api.node, ipfspath.FromString(p.String())) + if err != nil { + return nil, err + } + return NewResolvedPath(p.String(), c), nil +} + +type path struct { + path string + cid *cid.Cid +} + +func ParsePath(p string) (coreiface.Path, error) { + pp, err := ipfspath.ParsePath(p) + if err != nil { + return nil, err + } + return &path{path: pp.String()}, nil +} +func NewResolvedPath(p string, c *cid.Cid) coreiface.Path { return &path{path: p, cid: c} } +func NewPathFromCid(c *cid.Cid) coreiface.Path { return &path{path: "/ipfs/" + c.String(), cid: c} } +func (p *path) String() string { return p.path } +func (p *path) Cid() *cid.Cid { return p.cid } +func (p *path) Resolved() bool { return p.cid != nil } diff --git a/core/coreapi/interface/interface.go b/core/coreapi/interface/interface.go index cb62b53042b..475df670986 100644 --- a/core/coreapi/interface/interface.go +++ b/core/coreapi/interface/interface.go @@ -9,6 +9,12 @@ import ( cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid" ) +type Path interface { + String() string + Resolved() bool + Cid() *cid.Cid +} + type Link ipld.Link type Reader interface { @@ -18,12 +24,15 @@ type Reader interface { type CoreAPI interface { Unixfs() UnixfsAPI + ResolvePath(context.Context, Path) (Path, error) + ResolveNode(context.Context, Path) (ipld.Node, error) } type UnixfsAPI interface { - Add(context.Context, io.Reader) (*cid.Cid, error) - Cat(context.Context, string) (Reader, error) - Ls(context.Context, string) ([]*Link, error) + Core() CoreAPI + Add(context.Context, io.Reader) (Path, error) + Cat(context.Context, Path) (Reader, error) + Ls(context.Context, Path) ([]*Link, error) } // type ObjectAPI interface { diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 45a0cbe1164..b9a103aea5d 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -13,16 +13,24 @@ import ( type UnixfsAPI CoreAPI -func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (*cid.Cid, error) { +func (api *UnixfsAPI) Core() coreiface.CoreAPI { + return (*CoreAPI)(api) +} + +func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.Path, error) { k, err := coreunix.AddWithContext(ctx, api.node, r) if err != nil { return nil, err } - return cid.Decode(k) + c, err := cid.Decode(k) + if err != nil { + return nil, err + } + return NewPathFromCid(c), nil } -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, p coreiface.Path) (coreiface.Reader, error) { + dagnode, err := api.Core().ResolveNode(ctx, p) if err != nil { return nil, err } @@ -36,8 +44,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, p coreiface.Path) ([]*coreiface.Link, error) { + dagnode, err := api.Core().ResolveNode(ctx, p) if err != nil { return nil, err } diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 7122b0124e1..a0bc7c6c671 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -12,6 +12,7 @@ import ( "time" core "github.com/ipfs/go-ipfs/core" + coreapi "github.com/ipfs/go-ipfs/core/coreapi" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/importer" chunk "github.com/ipfs/go-ipfs/importer/chunk" @@ -158,7 +159,13 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr ipnsHostname = true } - dr, err := i.api.Unixfs().Cat(ctx, urlPath) + parsedPath, err := coreapi.ParsePath(urlPath) + if err != nil { + webError(w, "invalid ipfs path", err, http.StatusBadRequest) + return + } + + dr, err := i.api.Unixfs().Cat(ctx, parsedPath) dir := false switch err { case nil: @@ -231,7 +238,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr return } - links, err := i.api.Unixfs().Ls(ctx, urlPath) + links, err := i.api.Unixfs().Ls(ctx, parsedPath) if err != nil { internalWebError(w, err) return @@ -253,14 +260,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr return } - p, err := path.ParsePath(urlPath + "/index.html") - if err != nil { - internalWebError(w, err) - return - } - - // return index page instead. - dr, err := i.api.Unixfs().Cat(ctx, p.String()) + dr, err := i.api.Unixfs().Cat(ctx, coreapi.NewPathFromCid(link.Cid)) if err != nil { internalWebError(w, err) return