1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-30 09:59:13 +08:00

Merge pull request #4713 from ipfs/feat/split-path-resolver

Feat: Separate "path" from "path/resolver"
This commit is contained in:
Whyrusleeping
2018-02-20 09:55:36 -08:00
committed by GitHub
14 changed files with 71 additions and 56 deletions

View File

@ -13,7 +13,7 @@ import (
offline "github.com/ipfs/go-ipfs/exchange/offline"
filestore "github.com/ipfs/go-ipfs/filestore"
dag "github.com/ipfs/go-ipfs/merkledag"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
pin "github.com/ipfs/go-ipfs/pin"
repo "github.com/ipfs/go-ipfs/repo"
cfg "github.com/ipfs/go-ipfs/repo/config"
@ -230,7 +230,7 @@ func setupNode(ctx context.Context, n *IpfsNode, cfg *BuildCfg) error {
// this is kinda sketchy and could cause data loss
n.Pinning = pin.NewPinner(n.Repo.Datastore(), n.DAG, internalDag)
}
n.Resolver = path.NewBasicResolver(n.DAG)
n.Resolver = resolver.NewBasicResolver(n.DAG)
if cfg.Online {
if err := n.startLateOnlineServices(ctx); err != nil {

View File

@ -19,6 +19,7 @@ import (
dag "github.com/ipfs/go-ipfs/merkledag"
mfs "github.com/ipfs/go-ipfs/mfs"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
ft "github.com/ipfs/go-ipfs/unixfs"
uio "github.com/ipfs/go-ipfs/unixfs/io"
@ -352,7 +353,7 @@ func getNodeFromPath(ctx context.Context, node *core.IpfsNode, p string) (ipld.N
return nil, err
}
resolver := &path.Resolver{
resolver := &resolver.Resolver{
DAG: node.DAG,
ResolveOnce: uio.ResolveUnixfsOnce,
}

View File

@ -13,6 +13,7 @@ import (
offline "github.com/ipfs/go-ipfs/exchange/offline"
merkledag "github.com/ipfs/go-ipfs/merkledag"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
unixfs "github.com/ipfs/go-ipfs/unixfs"
uio "github.com/ipfs/go-ipfs/unixfs/io"
unixfspb "github.com/ipfs/go-ipfs/unixfs/pb"
@ -92,7 +93,7 @@ The JSON output contains type information.
return
}
r := &path.Resolver{
r := &resolver.Resolver{
DAG: nd.DAG,
ResolveOnce: uio.ResolveUnixfsOnce,
}

View File

@ -15,6 +15,7 @@ import (
offline "github.com/ipfs/go-ipfs/exchange/offline"
dag "github.com/ipfs/go-ipfs/merkledag"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
pin "github.com/ipfs/go-ipfs/pin"
uio "github.com/ipfs/go-ipfs/unixfs/io"
@ -387,7 +388,7 @@ new pin and removing the old one.
return
}
r := &path.Resolver{
r := &resolver.Resolver{
DAG: n.DAG,
ResolveOnce: uio.ResolveUnixfsOnce,
}
@ -501,7 +502,7 @@ func pinLsKeys(args []string, typeStr string, ctx context.Context, n *core.IpfsN
keys := make(map[string]RefKeyObject)
r := &path.Resolver{
r := &resolver.Resolver{
DAG: n.DAG,
ResolveOnce: uio.ResolveUnixfsOnce,
}

View File

@ -7,15 +7,17 @@ import (
"sort"
"text/tabwriter"
cmdkit "gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
cmds "github.com/ipfs/go-ipfs/commands"
core "github.com/ipfs/go-ipfs/core"
e "github.com/ipfs/go-ipfs/core/commands/e"
merkledag "github.com/ipfs/go-ipfs/merkledag"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
unixfs "github.com/ipfs/go-ipfs/unixfs"
uio "github.com/ipfs/go-ipfs/unixfs/io"
unixfspb "github.com/ipfs/go-ipfs/unixfs/pb"
cmdkit "gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
)
type LsLink struct {
@ -91,7 +93,7 @@ possible, please use 'ipfs ls' instead.
for _, fpath := range paths {
ctx := req.Context()
resolver := &path.Resolver{
resolver := &resolver.Resolver{
DAG: node.DAG,
ResolveOnce: uio.ResolveUnixfsOnce,
}

View File

@ -33,7 +33,7 @@ import (
namesys "github.com/ipfs/go-ipfs/namesys"
ipnsrp "github.com/ipfs/go-ipfs/namesys/republisher"
p2p "github.com/ipfs/go-ipfs/p2p"
path "github.com/ipfs/go-ipfs/path"
"github.com/ipfs/go-ipfs/path/resolver"
pin "github.com/ipfs/go-ipfs/pin"
repo "github.com/ipfs/go-ipfs/repo"
config "github.com/ipfs/go-ipfs/repo/config"
@ -119,7 +119,7 @@ type IpfsNode struct {
GCLocker bstore.GCLocker // the locker used to protect the blockstore during gc
Blocks bserv.BlockService // the block service, get/add blocks.
DAG ipld.DAGService // the merkle dag service, get/add objects.
Resolver *path.Resolver // the path resolution system
Resolver *resolver.Resolver // the path resolution system
Reporter metrics.Reporter
Discovery discovery.Service
FilesRoot *mfs.Root

View File

@ -7,6 +7,7 @@ import (
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
namesys "github.com/ipfs/go-ipfs/namesys"
ipfspath "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
uio "github.com/ipfs/go-ipfs/unixfs/io"
cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid"
@ -87,7 +88,7 @@ func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSyste
return p, nil
}
r := &ipfspath.Resolver{
r := &resolver.Resolver{
DAG: ng,
ResolveOnce: uio.ResolveUnixfsOnce,
}

View File

@ -19,6 +19,7 @@ import (
dag "github.com/ipfs/go-ipfs/merkledag"
dagutils "github.com/ipfs/go-ipfs/merkledag/utils"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
ft "github.com/ipfs/go-ipfs/unixfs"
uio "github.com/ipfs/go-ipfs/unixfs/io"
@ -445,7 +446,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
var newcid *cid.Cid
rnode, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, rootPath)
switch ev := err.(type) {
case path.ErrNoLink:
case resolver.ErrNoLink:
// ev.Node < node where resolve failed
// ev.Name < new link
// but we need to patch from the root
@ -599,7 +600,7 @@ func (i *gatewayHandler) addUserHeaders(w http.ResponseWriter) {
}
func webError(w http.ResponseWriter, message string, err error, defaultCode int) {
if _, ok := err.(path.ErrNoLink); ok {
if _, ok := err.(resolver.ErrNoLink); ok {
webErrorWithCode(w, message, err, http.StatusNotFound)
} else if err == routing.ErrNotFound {
webErrorWithCode(w, message, err, http.StatusNotFound)

View File

@ -19,6 +19,7 @@ import (
"github.com/ipfs/go-ipfs/core"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
uio "github.com/ipfs/go-ipfs/unixfs/io"
cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid"
@ -27,7 +28,7 @@ import (
func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]*cid.Cid, error) {
out := make([]*cid.Cid, len(paths))
r := &path.Resolver{
r := &resolver.Resolver{
DAG: n.DAG,
ResolveOnce: uio.ResolveUnixfsOnce,
}
@ -60,7 +61,7 @@ func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool)
func Unpin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]*cid.Cid, error) {
unpinned := make([]*cid.Cid, len(paths))
r := &path.Resolver{
r := &resolver.Resolver{
DAG: n.DAG,
ResolveOnce: uio.ResolveUnixfsOnce,
}

View File

@ -5,11 +5,12 @@ import (
core "github.com/ipfs/go-ipfs/core"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
uio "github.com/ipfs/go-ipfs/unixfs/io"
)
func Cat(ctx context.Context, n *core.IpfsNode, pstr string) (uio.DagReader, error) {
r := &path.Resolver{
r := &resolver.Resolver{
DAG: n.DAG,
ResolveOnce: uio.ResolveUnixfsOnce,
}

View File

@ -7,6 +7,7 @@ import (
namesys "github.com/ipfs/go-ipfs/namesys"
path "github.com/ipfs/go-ipfs/path"
resolver "github.com/ipfs/go-ipfs/path/resolver"
logging "gx/ipfs/QmRb5jh8z2E8hMGN2tkvs1yHynUanqnZ3UeKwgN1i9P1F8/go-log"
cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid"
@ -21,7 +22,7 @@ var ErrNoNamesys = errors.New(
// Resolve resolves the given path by parsing out protocol-specific
// entries (e.g. /ipns/<node-key>) and then going through the /ipfs/
// entries and returning the final node.
func Resolve(ctx context.Context, nsys namesys.NameSystem, r *path.Resolver, p path.Path) (ipld.Node, error) {
func Resolve(ctx context.Context, nsys namesys.NameSystem, r *resolver.Resolver, p path.Path) (ipld.Node, error) {
if strings.HasPrefix(p.String(), "/ipns/") {
evt := log.EventBegin(ctx, "resolveIpnsPath")
defer evt.Done()
@ -70,7 +71,7 @@ func Resolve(ctx context.Context, nsys namesys.NameSystem, r *path.Resolver, p p
// It first checks if the path is already in the form of just a cid (<cid> or
// /ipfs/<cid>) and returns immediately if so. Otherwise, it falls back onto
// Resolve to perform resolution of the dagnode being referenced.
func ResolveToCid(ctx context.Context, nsys namesys.NameSystem, r *path.Resolver, p path.Path) (*cid.Cid, error) {
func ResolveToCid(ctx context.Context, nsys namesys.NameSystem, r *resolver.Resolver, p path.Path) (*cid.Cid, error) {
// If the path is simply a cid, parse and return it. Parsed paths are already
// normalized (read: prepended with /ipfs/ if needed), so segment[1] should

View File

@ -9,8 +9,15 @@ import (
cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid"
)
// ErrBadPath is returned when a given path is incorrectly formatted
var ErrBadPath = errors.New("invalid 'ipfs ref' path")
var (
// ErrBadPath is returned when a given path is incorrectly formatted
ErrBadPath = errors.New("invalid 'ipfs ref' path")
// ErrNoComponents is used when Paths after a protocol
// do not contain at least one component
ErrNoComponents = errors.New(
"path must contain at least one component")
)
// A Path represents an ipfs content path:
// * /<cid>/path/to/file
@ -149,3 +156,25 @@ func Join(pths []string) string {
func SplitList(pth string) []string {
return strings.Split(pth, "/")
}
// SplitAbsPath clean up and split fpath. It extracts the first component (which
// must be a Multihash) and return it separately.
func SplitAbsPath(fpath Path) (*cid.Cid, []string, error) {
parts := fpath.Segments()
if parts[0] == "ipfs" {
parts = parts[1:]
}
// if nothing, bail.
if len(parts) == 0 {
return nil, nil, ErrNoComponents
}
c, err := cid.Decode(parts[0])
// first element in the path is a cid
if err != nil {
return nil, nil, err
}
return c, parts[1:], nil
}

View File

@ -1,5 +1,5 @@
// Package path implements utilities for resolving paths within ipfs.
package path
// Package resolver implements utilities for resolving paths within ipfs.
package resolver
import (
"context"
@ -8,13 +8,14 @@ import (
"time"
dag "github.com/ipfs/go-ipfs/merkledag"
path "github.com/ipfs/go-ipfs/path"
logging "gx/ipfs/QmRb5jh8z2E8hMGN2tkvs1yHynUanqnZ3UeKwgN1i9P1F8/go-log"
cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid"
ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format"
)
var log = logging.Logger("path")
var log = logging.Logger("pathresolv")
// ErrNoComponents is used when Paths after a protocol
// do not contain at least one component
@ -51,36 +52,10 @@ func NewBasicResolver(ds ipld.DAGService) *Resolver {
}
}
// SplitAbsPath clean up and split fpath. It extracts the first component (which
// must be a Multihash) and return it separately.
func SplitAbsPath(fpath Path) (*cid.Cid, []string, error) {
log.Debugf("Resolve: '%s'", fpath)
parts := fpath.Segments()
if parts[0] == "ipfs" {
parts = parts[1:]
}
// if nothing, bail.
if len(parts) == 0 {
return nil, nil, ErrNoComponents
}
c, err := cid.Decode(parts[0])
// first element in the path is a cid
if err != nil {
log.Debug("given path element is not a cid.\n")
return nil, nil, err
}
return c, parts[1:], nil
}
// ResolveToLastNode walks the given path and returns the ipld.Node
// referenced by the last element in it.
func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath Path) (ipld.Node, []string, error) {
c, p, err := SplitAbsPath(fpath)
func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath path.Path) (ipld.Node, []string, error) {
c, p, err := path.SplitAbsPath(fpath)
if err != nil {
return nil, nil, err
}
@ -114,7 +89,7 @@ func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath Path) (ipld.Node
// ResolvePath fetches the node for given path. It returns the last item
// returned by ResolvePathComponents.
func (r *Resolver) ResolvePath(ctx context.Context, fpath Path) (ipld.Node, error) {
func (r *Resolver) ResolvePath(ctx context.Context, fpath path.Path) (ipld.Node, error) {
// validate path
if err := fpath.IsValid(); err != nil {
return nil, err
@ -136,11 +111,11 @@ func ResolveSingle(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names
// ResolvePathComponents fetches the nodes for each segment of the given path.
// It uses the first path component as a hash (key) of the first node, then
// resolves all other components walking the links, with ResolveLinks.
func (r *Resolver) ResolvePathComponents(ctx context.Context, fpath Path) ([]ipld.Node, error) {
func (r *Resolver) ResolvePathComponents(ctx context.Context, fpath path.Path) ([]ipld.Node, error) {
evt := log.EventBegin(ctx, "resolvePathComponents", logging.LoggableMap{"fpath": fpath})
defer evt.Done()
h, parts, err := SplitAbsPath(fpath)
h, parts, err := path.SplitAbsPath(fpath)
if err != nil {
evt.Append(logging.LoggableMap{"error": err.Error()})
return nil, err

View File

@ -1,4 +1,4 @@
package path_test
package resolver_test
import (
"context"
@ -8,6 +8,7 @@ import (
merkledag "github.com/ipfs/go-ipfs/merkledag"
dagmock "github.com/ipfs/go-ipfs/merkledag/test"
path "github.com/ipfs/go-ipfs/path"
"github.com/ipfs/go-ipfs/path/resolver"
util "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
ipld "gx/ipfs/Qme5bWv7wtjUNGsK2BNGVUFPKiuxWrsqrtvYwCLRw8YFES/go-ipld-format"
@ -53,7 +54,7 @@ func TestRecurivePathResolution(t *testing.T) {
t.Fatal(err)
}
resolver := path.NewBasicResolver(dagService)
resolver := resolver.NewBasicResolver(dagService)
node, err := resolver.ResolvePath(ctx, p)
if err != nil {
t.Fatal(err)