forked from ipfs/kubo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresolve.go
151 lines (128 loc) · 4.56 KB
/
resolve.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package commands
import (
"errors"
"fmt"
"io"
"strings"
"time"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
ncmd "github.com/ipfs/go-ipfs/core/commands/name"
ns "github.com/ipfs/go-ipfs/namesys"
cidenc "github.com/ipfs/go-cidutil/cidenc"
cmds "github.com/ipfs/go-ipfs-cmds"
ipfspath "github.com/ipfs/go-path"
options "github.com/ipfs/interface-go-ipfs-core/options"
nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
path "github.com/ipfs/interface-go-ipfs-core/path"
)
const (
resolveRecursiveOptionName = "recursive"
resolveDhtRecordCountOptionName = "dht-record-count"
resolveDhtTimeoutOptionName = "dht-timeout"
)
var ResolveCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Resolve the value of names to IPFS.",
ShortDescription: `
There are a number of mutable name protocols that can link among
themselves and into IPNS. This command accepts any of these
identifiers and resolves them to the referenced item.
`,
LongDescription: `
There are a number of mutable name protocols that can link among
themselves and into IPNS. For example IPNS references can (currently)
point at an IPFS object, and DNS links can point at other DNS links, IPNS
entries, or IPFS objects. This command accepts any of these
identifiers and resolves them to the referenced item.
EXAMPLES
Resolve the value of your identity:
$ ipfs resolve /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
Resolve the value of another name:
$ ipfs resolve /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
Resolve the value of another name recursively:
$ ipfs resolve -r /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
Resolve the value of an IPFS DAG path:
$ ipfs resolve /ipfs/QmeZy1fGbwgVSrqbfh9fKQrAWgeyRnj7h8fsHS1oy3k99x/beep/boop
/ipfs/QmYRMjyvAiHKN9UTi8Bzt1HUspmSRD8T8DwxfSMzLgBon1
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("name", true, false, "The name to resolve.").EnableStdin(),
},
Options: []cmds.Option{
cmds.BoolOption(resolveRecursiveOptionName, "r", "Resolve until the result is an IPFS name.").WithDefault(true),
cmds.IntOption(resolveDhtRecordCountOptionName, "dhtrc", "Number of records to request for DHT resolution."),
cmds.StringOption(resolveDhtTimeoutOptionName, "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) error {
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
name := req.Arguments[0]
recursive, _ := req.Options[resolveRecursiveOptionName].(bool)
var enc cidenc.Encoder
switch {
case !cmdenv.CidBaseDefined(req):
// Not specified, check the path.
enc, err = cmdenv.CidEncoderFromPath(name)
if err == nil {
break
}
// Nope, fallback on the default.
fallthrough
default:
enc, err = cmdenv.GetCidEncoder(req)
if err != nil {
return err
}
}
// the case when ipns is resolved step by step
if strings.HasPrefix(name, "/ipns/") && !recursive {
rc, rcok := req.Options[resolveDhtRecordCountOptionName].(uint)
dhtt, dhttok := req.Options[resolveDhtTimeoutOptionName].(string)
ropts := []options.NameResolveOption{
options.Name.ResolveOption(nsopts.Depth(1)),
}
if rcok {
ropts = append(ropts, options.Name.ResolveOption(nsopts.DhtRecordCount(rc)))
}
if dhttok {
d, err := time.ParseDuration(dhtt)
if err != nil {
return err
}
if d < 0 {
return errors.New("DHT timeout value must be >= 0")
}
ropts = append(ropts, options.Name.ResolveOption(nsopts.DhtTimeout(d)))
}
p, err := api.Name().Resolve(req.Context, name, ropts...)
// ErrResolveRecursion is fine
if err != nil && err != ns.ErrResolveRecursion {
return err
}
return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(p.String())})
}
// else, ipfs path or ipns with recursive flag
rp, err := api.ResolvePath(req.Context, path.New(name))
if err != nil {
return err
}
encoded := "/" + rp.Namespace() + "/" + enc.Encode(rp.Cid())
if remainder := rp.Remainder(); remainder != "" {
encoded += "/" + remainder
}
return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(encoded)})
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, rp *ncmd.ResolvedPath) error {
fmt.Fprintln(w, rp.Path.String())
return nil
}),
},
Type: ncmd.ResolvedPath{},
}