mirror of
https://github.com/ipfs/kubo.git
synced 2025-08-06 19:44:01 +08:00
resolve cmd: use coreapi
License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
This commit is contained in:
@ -7,18 +7,16 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-ipfs/core"
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
e "github.com/ipfs/go-ipfs/core/commands/e"
|
||||
ncmd "github.com/ipfs/go-ipfs/core/commands/name"
|
||||
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
|
||||
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
|
||||
ns "github.com/ipfs/go-ipfs/namesys"
|
||||
nsopts "github.com/ipfs/go-ipfs/namesys/opts"
|
||||
path "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
|
||||
|
||||
uio "gx/ipfs/QmPL8bYtbACcSFFiSr4s2du7Na382NxRADR8hC7D9FkEA2/go-unixfs/io"
|
||||
"gx/ipfs/QmPTfgFTo9PFr1PvPKyKoeMgBvYPh6cX3aDP7DHKVbnCbi/go-ipfs-cmds"
|
||||
"gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit"
|
||||
resolver "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path/resolver"
|
||||
)
|
||||
|
||||
var ResolveCmd = &cmds.Command{
|
||||
@ -66,16 +64,30 @@ Resolve the value of an IPFS DAG path:
|
||||
},
|
||||
Options: []cmdkit.Option{
|
||||
cmdkit.BoolOption("recursive", "r", "Resolve until the result is an IPFS name."),
|
||||
cmdkit.UintOption("dht-record-count", "dhtrc", "Number of records to request for DHT resolution."),
|
||||
cmdkit.IntOption("dht-record-count", "dhtrc", "Number of records to request for DHT resolution."),
|
||||
cmdkit.StringOption("dht-timeout", "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
|
||||
api, err := cmdenv.GetApi(env)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
n, err := cmdenv.GetNode(env)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
if !n.OnlineMode() {
|
||||
err := n.SetupOfflineRouting()
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
name := req.Arguments[0]
|
||||
recursive, _ := req.Options["recursive"].(bool)
|
||||
|
||||
@ -83,9 +95,10 @@ Resolve the value of an IPFS DAG path:
|
||||
if strings.HasPrefix(name, "/ipns/") && !recursive {
|
||||
rc, rcok := req.Options["dht-record-count"].(int)
|
||||
dhtt, dhttok := req.Options["dht-timeout"].(string)
|
||||
ropts := []nsopts.ResolveOpt{nsopts.Depth(1)}
|
||||
ropts := []options.NameResolveOption{options.Name.Depth(1)}
|
||||
|
||||
if rcok {
|
||||
ropts = append(ropts, nsopts.DhtRecordCount(uint(rc)))
|
||||
ropts = append(ropts, options.Name.DhtRecordCount(rc))
|
||||
}
|
||||
if dhttok {
|
||||
d, err := time.ParseDuration(dhtt)
|
||||
@ -97,37 +110,32 @@ Resolve the value of an IPFS DAG path:
|
||||
res.SetError(errors.New("DHT timeout value must be >= 0"), cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
ropts = append(ropts, nsopts.DhtTimeout(d))
|
||||
ropts = append(ropts, options.Name.DhtTimeout(d))
|
||||
}
|
||||
p, err := n.Namesys.Resolve(req.Context, name, ropts...)
|
||||
p, err := api.Name().Resolve(req.Context, name, ropts...)
|
||||
// ErrResolveRecursion is fine
|
||||
if err != nil && err != ns.ErrResolveRecursion {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: p})
|
||||
cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: path.Path(p.String())})
|
||||
return
|
||||
}
|
||||
|
||||
// else, ipfs path or ipns with recursive flag
|
||||
p, err := path.ParsePath(name)
|
||||
p, err := coreiface.ParsePath(name)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
r := &resolver.Resolver{
|
||||
DAG: n.DAG,
|
||||
ResolveOnce: uio.ResolveUnixfsOnce,
|
||||
}
|
||||
|
||||
node, err := core.Resolve(req.Context, n.Namesys, r, p)
|
||||
rp, err := api.ResolvePath(req.Context, p)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
c := node.Cid()
|
||||
c := rp.Cid()
|
||||
|
||||
cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: path.FromCid(c)})
|
||||
},
|
||||
|
@ -14,9 +14,12 @@ type NamePublishSettings struct {
|
||||
}
|
||||
|
||||
type NameResolveSettings struct {
|
||||
Recursive bool
|
||||
Local bool
|
||||
Cache bool
|
||||
Depth int
|
||||
Local bool
|
||||
Cache bool
|
||||
|
||||
DhtRecordCount int
|
||||
DhtTimeout time.Duration
|
||||
}
|
||||
|
||||
type NamePublishOption func(*NamePublishSettings) error
|
||||
@ -40,9 +43,12 @@ func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error)
|
||||
|
||||
func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) {
|
||||
options := &NameResolveSettings{
|
||||
Recursive: false,
|
||||
Local: false,
|
||||
Cache: true,
|
||||
Depth: 1,
|
||||
Local: false,
|
||||
Cache: true,
|
||||
|
||||
DhtRecordCount: 16,
|
||||
DhtTimeout: time.Minute,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
@ -80,11 +86,11 @@ func (nameOpts) Key(key string) NamePublishOption {
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive is an option for Name.Resolve which specifies whether to perform a
|
||||
// Depth is an option for Name.Resolve which specifies the maximum depth of a
|
||||
// recursive lookup. Default value is false
|
||||
func (nameOpts) Recursive(recursive bool) NameResolveOption {
|
||||
func (nameOpts) Depth(depth int) NameResolveOption {
|
||||
return func(settings *NameResolveSettings) error {
|
||||
settings.Recursive = recursive
|
||||
settings.Depth = depth
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -106,3 +112,22 @@ func (nameOpts) Cache(cache bool) NameResolveOption {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DhtRecordCount is an option for Name.Resolve which specifies how many records
|
||||
// we want to validate before selecting the best one (newest). Note that setting
|
||||
// this value too low will have security implications
|
||||
func (nameOpts) DhtRecordCount(rc int) NameResolveOption {
|
||||
return func(settings *NameResolveSettings) error {
|
||||
settings.DhtRecordCount = rc
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DhtTimeout is an option for Name.Resolve which specifies timeout for
|
||||
// DHT lookup
|
||||
func (nameOpts) DhtTimeout(timeout time.Duration) NameResolveOption {
|
||||
return func(settings *NameResolveSettings) error {
|
||||
settings.DhtTimeout = timeout
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -119,9 +119,10 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam
|
||||
name = "/ipns/" + name
|
||||
}
|
||||
|
||||
var ropts []nsopts.ResolveOpt
|
||||
if !options.Recursive {
|
||||
ropts = append(ropts, nsopts.Depth(1))
|
||||
ropts := []nsopts.ResolveOpt{
|
||||
nsopts.Depth(uint(options.Depth)),
|
||||
nsopts.DhtRecordCount(uint(options.DhtRecordCount)),
|
||||
nsopts.DhtTimeout(options.DhtTimeout),
|
||||
}
|
||||
|
||||
output, err := resolver.Resolve(ctx, name, ropts...)
|
||||
|
@ -1,53 +1,44 @@
|
||||
package coreapi
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
"context"
|
||||
"fmt"
|
||||
gopath "path"
|
||||
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
"github.com/ipfs/go-ipfs/core"
|
||||
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
|
||||
namesys "github.com/ipfs/go-ipfs/namesys"
|
||||
uio "gx/ipfs/QmPL8bYtbACcSFFiSr4s2du7Na382NxRADR8hC7D9FkEA2/go-unixfs/io"
|
||||
ipfspath "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
|
||||
resolver "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path/resolver"
|
||||
"gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path/resolver"
|
||||
|
||||
cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid"
|
||||
"gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid"
|
||||
ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format"
|
||||
)
|
||||
|
||||
// ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the
|
||||
// resolved Node.
|
||||
func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (ipld.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) (ipld.Node, error) {
|
||||
rp, err := resolvePath(ctx, ng, nsys, p)
|
||||
rp, err := api.ResolvePath(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
node, err := ng.Get(ctx, rp.Cid())
|
||||
node, err := api.node.DAG.Get(ctx, rp.Cid())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSystem, p coreiface.Path) (coreiface.ResolvedPath, error) {
|
||||
// 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) {
|
||||
if _, ok := p.(coreiface.ResolvedPath); ok {
|
||||
return p.(coreiface.ResolvedPath), nil
|
||||
}
|
||||
|
||||
ipath := ipfspath.Path(p.String())
|
||||
ipath, err := core.ResolveIPNS(ctx, nsys, ipath)
|
||||
ipath, err := core.ResolveIPNS(ctx, api.node.Namesys, ipath)
|
||||
if err == core.ErrNoNamesys {
|
||||
return nil, coreiface.ErrOffline
|
||||
} else if err != nil {
|
||||
@ -66,7 +57,7 @@ func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSyste
|
||||
}
|
||||
|
||||
r := &resolver.Resolver{
|
||||
DAG: ng,
|
||||
DAG: api.node.DAG,
|
||||
ResolveOnce: resolveOnce,
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.ResolvedP
|
||||
func (api *UnixfsAPI) Cat(ctx context.Context, p coreiface.Path) (coreiface.Reader, error) {
|
||||
dget := api.node.DAG // TODO: use a session here once routing perf issues are resolved
|
||||
|
||||
dagnode, err := resolveNode(ctx, dget, api.node.Namesys, p)
|
||||
dagnode, err := api.core().ResolveNode(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user