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:
@ -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 {
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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
|
||||
|
33
path/path.go
33
path/path.go
@ -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
|
||||
}
|
||||
|
@ -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
|
@ -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)
|
Reference in New Issue
Block a user