Use variadic options
License: MIT Signed-off-by: Dirk McCormick <dirkmdev@gmail.com>
Dirk McCormick committed
Feb 28, 2018 at 16:57 UTC
e8f79c88036362d99d2b06e3fa7fae974090cd6f
23 files changed
+172
-131
core/commands/dns.go
+5
-3
@@ -7,6 +7,7 @@ import (
7
cmds "github.com/ipfs/go-ipfs/commands"
8
e "github.com/ipfs/go-ipfs/core/commands/e"
9
namesys "github.com/ipfs/go-ipfs/namesys"
10
+ nsopts "github.com/ipfs/go-ipfs/namesys/opts"
11
12
"gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
13
)
@@ -57,11 +58,12 @@ The resolver can recursively resolve:
58
name := req.Arguments()[0]
59
resolver := namesys.NewDNSResolver()
60
60
- opts := namesys.DefaultResolveOpts()
61
+ ropts := []nsopts.ResolveOpt{}
62
if !recursive {
62
- opts.Depth = 1
63
+ ropts = append(ropts, nsopts.Depth(1))
64
}
64
- output, err := resolver.Resolve(req.Context(), name, opts)
65
+
66
+ output, err := resolver.Resolve(req.Context(), name, ropts...)
67
if err == namesys.ErrResolveFailed {
68
res.SetError(err, cmdkit.ErrNotFound)
69
return
core/commands/ipns.go
+6
-5
@@ -9,6 +9,7 @@ import (
9
cmds "github.com/ipfs/go-ipfs/commands"
10
e "github.com/ipfs/go-ipfs/core/commands/e"
11
namesys "github.com/ipfs/go-ipfs/namesys"
12
+ nsopts "github.com/ipfs/go-ipfs/namesys/opts"
13
14
offline "gx/ipfs/QmZRcGYvxdauCd7hHnMYLYqcZRaDjv24c7eUNyJojAcdBb/go-ipfs-routing/offline"
15
"gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
@@ -111,22 +112,22 @@ Resolve the value of a dnslink:
112
recursive, _, _ := req.Option("recursive").Bool()
113
rc, rcok, _ := req.Option("dht-record-count").Int()
114
dhtt, dhttok, _ := req.Option("dht-timeout").Int()
114
- opts := namesys.DefaultResolveOpts()
115
+ ropts := []nsopts.ResolveOpt{}
116
if !recursive {
116
- opts.Depth = 1
117
+ ropts = append(ropts, nsopts.Depth(1))
118
}
119
if rcok {
119
- opts.DhtRecordCount = uint(rc)
120
+ ropts = append(ropts, nsopts.DhtRecordCount(uint(rc)))
121
}
122
if dhttok {
122
- opts.DhtTimeout = time.Duration(dhtt) * time.Second
123
+ ropts = append(ropts, nsopts.DhtTimeout(time.Duration(dhtt)*time.Second))
124
}
125
126
if !strings.HasPrefix(name, "/ipns/") {
127
name = "/ipns/" + name
128
}
129
129
- output, err := resolver.Resolve(req.Context(), name, opts)
130
+ output, err := resolver.Resolve(req.Context(), name, ropts...)
131
if err != nil {
132
res.SetError(err, cmdkit.ErrNormal)
133
return
core/commands/resolve.go
+5
-5
@@ -9,6 +9,7 @@ import (
9
"github.com/ipfs/go-ipfs/core"
10
e "github.com/ipfs/go-ipfs/core/commands/e"
11
ns "github.com/ipfs/go-ipfs/namesys"
12
+ nsopts "github.com/ipfs/go-ipfs/namesys/opts"
13
path "github.com/ipfs/go-ipfs/path"
14
15
"gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
@@ -89,15 +90,14 @@ Resolve the value of an IPFS DAG path:
90
if strings.HasPrefix(name, "/ipns/") && !recursive {
91
rc, rcok, _ := req.Option("dht-record-count").Int()
92
dhtt, dhttok, _ := req.Option("dht-timeout").Int()
92
- opts := ns.DefaultResolveOpts()
93
- opts.Depth = 1
93
+ ropts := []nsopts.ResolveOpt{nsopts.Depth(1)}
94
if rcok {
95
- opts.DhtRecordCount = uint(rc)
95
+ ropts = append(ropts, nsopts.DhtRecordCount(uint(rc)))
96
}
97
if dhttok {
98
- opts.DhtTimeout = time.Duration(dhtt) * time.Second
98
+ ropts = append(ropts, nsopts.DhtTimeout(time.Duration(dhtt)*time.Second))
99
}
100
- p, err := n.Namesys.Resolve(req.Context(), name, opts)
100
+ p, err := n.Namesys.Resolve(req.Context(), name, ropts...)
101
// ErrResolveRecursion is fine
102
if err != nil && err != ns.ErrResolveRecursion {
103
res.SetError(err, cmdkit.ErrNormal)
core/coreapi/name.go
+7
-6
@@ -12,6 +12,7 @@ import (
12
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
13
keystore "github.com/ipfs/go-ipfs/keystore"
14
namesys "github.com/ipfs/go-ipfs/namesys"
15
+ nsopts "github.com/ipfs/go-ipfs/namesys/opts"
16
ipath "github.com/ipfs/go-ipfs/path"
17
18
offline "gx/ipfs/QmZRcGYvxdauCd7hHnMYLYqcZRaDjv24c7eUNyJojAcdBb/go-ipfs-routing/offline"
@@ -117,16 +118,16 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam
118
resolver = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), 0)
119
}
120
120
- ropts := namesys.DefaultResolveOpts()
121
- if !options.Recursive {
122
- ropts.Depth = 1
123
- }
124
-
121
if !strings.HasPrefix(name, "/ipns/") {
122
name = "/ipns/" + name
123
}
124
129
- output, err := resolver.Resolve(ctx, name, ropts)
125
+ ropts := []nsopts.ResolveOpt{}
126
+ if !options.Recursive {
127
+ ropts = append(ropts, nsopts.Depth(1))
128
+ }
129
+
130
+ output, err := resolver.Resolve(ctx, name, ropts...)
131
if err != nil {
132
return nil, err
133
}
core/corehttp/gateway_test.go
+2
-1
@@ -14,6 +14,7 @@ import (
14
coreunix "github.com/ipfs/go-ipfs/core/coreunix"
15
dag "github.com/ipfs/go-ipfs/merkledag"
16
namesys "github.com/ipfs/go-ipfs/namesys"
17
+ nsopts "github.com/ipfs/go-ipfs/namesys/opts"
18
path "github.com/ipfs/go-ipfs/path"
19
repo "github.com/ipfs/go-ipfs/repo"
20
config "github.com/ipfs/go-ipfs/repo/config"
@@ -28,7 +29,7 @@ var emptyDir = "/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"
29
30
type mockNamesys map[string]path.Path
31
31
-func (m mockNamesys) Resolve(ctx context.Context, name string, opts *namesys.ResolveOpts) (value path.Path, err error) {
32
+func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...nsopts.ResolveOpt) (value path.Path, err error) {
33
p, ok := m[name]
34
if !ok {
35
return "", namesys.ErrResolveFailed
core/corehttp/ipns_hostname.go
+1
-2
@@ -7,7 +7,6 @@ import (
7
"strings"
8
9
"github.com/ipfs/go-ipfs/core"
10
- namesys "github.com/ipfs/go-ipfs/namesys"
10
11
isd "gx/ipfs/QmZmmuAXgX73UQmX1jRKjTGmjzq24Jinqkq8vzkBtno4uX/go-is-domain"
12
)
@@ -25,7 +24,7 @@ func IPNSHostnameOption() ServeOption {
24
host := strings.SplitN(r.Host, ":", 2)[0]
25
if len(host) > 0 && isd.IsDomain(host) {
26
name := "/ipns/" + host
28
- if _, err := n.Namesys.Resolve(ctx, name, namesys.DefaultResolveOpts()); err == nil {
27
+ if _, err := n.Namesys.Resolve(ctx, name); err == nil {
28
r.Header["X-Ipns-Original-Path"] = []string{r.URL.Path}
29
r.URL.Path = name + r.URL.Path
30
}
core/pathresolver.go
+1
-1
@@ -48,7 +48,7 @@ func Resolve(ctx context.Context, nsys namesys.NameSystem, r *resolver.Resolver,
48
return nil, err
49
}
50
51
- respath, err := nsys.Resolve(ctx, resolvable.String(), namesys.DefaultResolveOpts())
51
+ respath, err := nsys.Resolve(ctx, resolvable.String())
52
if err != nil {
53
evt.Append(logging.LoggableMap{"error": err.Error()})
54
return nil, err
fuse/ipns/ipns_unix.go
+1
-1
@@ -203,7 +203,7 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) {
203
}
204
205
// other links go through ipns resolution and are symlinked into the ipfs mountpoint
206
- resolved, err := s.Ipfs.Namesys.Resolve(s.Ipfs.Context(), name, namesys.DefaultResolveOpts())
206
+ resolved, err := s.Ipfs.Namesys.Resolve(s.Ipfs.Context(), name)
207
if err != nil {
208
log.Warningf("ipns: namesys resolve error: %s", err)
209
return nil, fuse.ENOENT
namesys/base.go
+5
-4
@@ -5,19 +5,20 @@ import (
5
6
context "context"
7
8
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
9
path "github.com/ipfs/go-ipfs/path"
10
)
11
12
type resolver interface {
13
// resolveOnce looks up a name once (without recursion).
13
- resolveOnce(ctx context.Context, name string, opts *ResolveOpts) (value path.Path, err error)
14
+ resolveOnce(ctx context.Context, name string, options *opts.ResolveOpts) (value path.Path, err error)
15
}
16
17
// resolve is a helper for implementing Resolver.ResolveN using resolveOnce.
17
-func resolve(ctx context.Context, r resolver, name string, opts *ResolveOpts, prefixes ...string) (path.Path, error) {
18
- depth := opts.Depth
18
+func resolve(ctx context.Context, r resolver, name string, options *opts.ResolveOpts, prefixes ...string) (path.Path, error) {
19
+ depth := options.Depth
20
for {
20
- p, err := r.resolveOnce(ctx, name, opts)
21
+ p, err := r.resolveOnce(ctx, name, options)
22
if err != nil {
23
return "", err
24
}
namesys/dns.go
+4
-3
@@ -6,6 +6,7 @@ import (
6
"net"
7
"strings"
8
9
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
10
path "github.com/ipfs/go-ipfs/path"
11
isd "gx/ipfs/QmZmmuAXgX73UQmX1jRKjTGmjzq24Jinqkq8vzkBtno4uX/go-is-domain"
12
)
@@ -31,8 +32,8 @@ func newDNSResolver() resolver {
32
}
33
34
// Resolve implements Resolver.
34
-func (r *DNSResolver) Resolve(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
35
- return resolve(ctx, r, name, opts, "/ipns/")
35
+func (r *DNSResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
36
+ return resolve(ctx, r, name, opts.ProcessOpts(options), "/ipns/")
37
}
38
39
type lookupRes struct {
@@ -43,7 +44,7 @@ type lookupRes struct {
44
// resolveOnce implements resolver.
45
// TXT records for a given domain name should contain a b58
46
// encoded multihash.
46
-func (r *DNSResolver) resolveOnce(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
47
+func (r *DNSResolver) resolveOnce(ctx context.Context, name string, options *opts.ResolveOpts) (path.Path, error) {
48
segments := strings.SplitN(name, "/", 2)
49
domain := segments[0]
50
namesys/dns_test.go
+20
-18
@@ -3,6 +3,8 @@ package namesys
3
import (
4
"fmt"
5
"testing"
6
+
7
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
8
)
9
10
type mockDNS struct {
@@ -128,33 +130,33 @@ func newMockDNS() *mockDNS {
130
func TestDNSResolution(t *testing.T) {
131
mock := newMockDNS()
132
r := &DNSResolver{lookupTXT: mock.lookupTXT}
131
- testResolution(t, r, "multihash.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
132
- testResolution(t, r, "ipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
133
- testResolution(t, r, "dipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
134
- testResolution(t, r, "dns1.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
133
+ testResolution(t, r, "multihash.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
134
+ testResolution(t, r, "ipfs.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
135
+ testResolution(t, r, "dipfs.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
136
+ testResolution(t, r, "dns1.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
137
testResolution(t, r, "dns1.example.com", 1, "/ipns/ipfs.example.com", ErrResolveRecursion)
136
- testResolution(t, r, "dns2.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
138
+ testResolution(t, r, "dns2.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
139
testResolution(t, r, "dns2.example.com", 1, "/ipns/dns1.example.com", ErrResolveRecursion)
140
testResolution(t, r, "dns2.example.com", 2, "/ipns/ipfs.example.com", ErrResolveRecursion)
139
- testResolution(t, r, "multi.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
141
+ testResolution(t, r, "multi.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
142
testResolution(t, r, "multi.example.com", 1, "/ipns/dns1.example.com", ErrResolveRecursion)
143
testResolution(t, r, "multi.example.com", 2, "/ipns/ipfs.example.com", ErrResolveRecursion)
142
- testResolution(t, r, "equals.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/=equals", nil)
144
+ testResolution(t, r, "equals.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/=equals", nil)
145
testResolution(t, r, "loop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion)
146
testResolution(t, r, "loop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion)
147
testResolution(t, r, "loop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion)
146
- testResolution(t, r, "loop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
148
+ testResolution(t, r, "loop1.example.com", opts.DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
149
testResolution(t, r, "dloop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion)
150
testResolution(t, r, "dloop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion)
151
testResolution(t, r, "dloop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion)
150
- testResolution(t, r, "dloop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
151
- testResolution(t, r, "bad.example.com", DefaultDepthLimit, "", ErrResolveFailed)
152
- testResolution(t, r, "withsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", nil)
153
- testResolution(t, r, "withrecsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub", nil)
154
- testResolution(t, r, "withsegment.example.com/test1", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/test1", nil)
155
- testResolution(t, r, "withrecsegment.example.com/test2", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test2", nil)
156
- testResolution(t, r, "withrecsegment.example.com/test3/", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test3/", nil)
157
- testResolution(t, r, "withtrailingrec.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/", nil)
158
- testResolution(t, r, "double.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
159
- testResolution(t, r, "conflict.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil)
152
+ testResolution(t, r, "dloop1.example.com", opts.DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
153
+ testResolution(t, r, "bad.example.com", opts.DefaultDepthLimit, "", ErrResolveFailed)
154
+ testResolution(t, r, "withsegment.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", nil)
155
+ testResolution(t, r, "withrecsegment.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub", nil)
156
+ testResolution(t, r, "withsegment.example.com/test1", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/test1", nil)
157
+ testResolution(t, r, "withrecsegment.example.com/test2", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test2", nil)
158
+ testResolution(t, r, "withrecsegment.example.com/test3/", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test3/", nil)
159
+ testResolution(t, r, "withtrailingrec.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/", nil)
160
+ testResolution(t, r, "double.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
161
+ testResolution(t, r, "conflict.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil)
162
}
namesys/interface.go
+2
-12
@@ -35,21 +35,11 @@ import (
35
36
context "context"
37
38
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
39
path "github.com/ipfs/go-ipfs/path"
40
ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
41
)
42
42
-const (
43
- // DefaultDepthLimit is the default depth limit used by Resolve.
44
- DefaultDepthLimit = 32
45
-
46
- // UnlimitedDepth allows infinite recursion in ResolveN. You
47
- // probably don't want to use this, but it's here if you absolutely
48
- // trust resolution to eventually complete and can't put an upper
49
- // limit on how many steps it will take.
50
- UnlimitedDepth = 0
51
-)
52
-
43
// ErrResolveFailed signals an error when attempting to resolve.
44
var ErrResolveFailed = errors.New("Could not resolve name.")
45
@@ -90,7 +80,7 @@ type Resolver interface {
80
// There is a default depth-limit to avoid infinite recursion. Most
81
// users will be fine with this default limit, but if you need to
82
// adjust the limit you can specify it as an option.
93
- Resolve(ctx context.Context, name string, opts *ResolveOpts) (value path.Path, err error)
83
+ Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (value path.Path, err error)
84
}
85
86
// Publisher is an object capable of publishing particular names.
namesys/ipns_validate_test.go
+6
-5
@@ -6,6 +6,7 @@ import (
6
"testing"
7
"time"
8
9
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
10
path "github.com/ipfs/go-ipfs/path"
11
12
u "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
@@ -115,7 +116,7 @@ func TestResolverValidation(t *testing.T) {
116
}
117
118
// Resolve entry
118
- resp, err := resolver.resolveOnce(ctx, id.Pretty(), DefaultResolveOpts())
119
+ resp, err := resolver.resolveOnce(ctx, id.Pretty(), opts.DefaultResolveOpts())
120
if err != nil {
121
t.Fatal(err)
122
}
@@ -136,7 +137,7 @@ func TestResolverValidation(t *testing.T) {
137
}
138
139
// Record should fail validation because entry is expired
139
- _, err = resolver.resolveOnce(ctx, id.Pretty(), DefaultResolveOpts())
140
+ _, err = resolver.resolveOnce(ctx, id.Pretty(), opts.DefaultResolveOpts())
141
if err == nil {
142
t.Fatal("ValidateIpnsRecord should have returned error")
143
}
@@ -158,7 +159,7 @@ func TestResolverValidation(t *testing.T) {
159
160
// Record should fail validation because public key defined by
161
// ipns path doesn't match record signature
161
- _, err = resolver.resolveOnce(ctx, id2.Pretty(), DefaultResolveOpts())
162
+ _, err = resolver.resolveOnce(ctx, id2.Pretty(), opts.DefaultResolveOpts())
163
if err == nil {
164
t.Fatal("ValidateIpnsRecord should have failed signature verification")
165
}
@@ -176,7 +177,7 @@ func TestResolverValidation(t *testing.T) {
177
178
// Record should fail validation because public key is not available
179
// in peer store or on network
179
- _, err = resolver.resolveOnce(ctx, id3.Pretty(), DefaultResolveOpts())
180
+ _, err = resolver.resolveOnce(ctx, id3.Pretty(), opts.DefaultResolveOpts())
181
if err == nil {
182
t.Fatal("ValidateIpnsRecord should have failed because public key was not found")
183
}
@@ -191,7 +192,7 @@ func TestResolverValidation(t *testing.T) {
192
// public key is available in the peer store by looking it up in
193
// the DHT, which causes the DHT to fetch it and cache it in the
194
// peer store
194
- _, err = resolver.resolveOnce(ctx, id3.Pretty(), DefaultResolveOpts())
195
+ _, err = resolver.resolveOnce(ctx, id3.Pretty(), opts.DefaultResolveOpts())
196
if err != nil {
197
t.Fatal(err)
198
}
namesys/namesys.go
+8
-7
@@ -7,6 +7,7 @@ import (
7
"sync"
8
"time"
9
10
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
11
path "github.com/ipfs/go-ipfs/path"
12
13
p2phost "gx/ipfs/QmNmJZL7FQySMtE2BQuLMuZg2EB2CLEunJJUSVSc9YnnbV/go-libp2p-host"
@@ -67,7 +68,7 @@ func AddPubsubNameSystem(ctx context.Context, ns NameSystem, host p2phost.Host,
68
const DefaultResolverCacheTTL = time.Minute
69
70
// Resolve implements Resolver.
70
-func (ns *mpns) Resolve(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
71
+func (ns *mpns) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
72
if strings.HasPrefix(name, "/ipfs/") {
73
return path.ParsePath(name)
74
}
@@ -76,11 +77,11 @@ func (ns *mpns) Resolve(ctx context.Context, name string, opts *ResolveOpts) (pa
77
return path.ParsePath("/ipfs/" + name)
78
}
79
79
- return resolve(ctx, ns, name, opts, "/ipns/")
80
+ return resolve(ctx, ns, name, opts.ProcessOpts(options), "/ipns/")
81
}
82
83
// resolveOnce implements resolver.
83
-func (ns *mpns) resolveOnce(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
84
+func (ns *mpns) resolveOnce(ctx context.Context, name string, options *opts.ResolveOpts) (path.Path, error) {
85
if !strings.HasPrefix(name, "/ipns/") {
86
name = "/ipns/" + name
87
}
@@ -109,7 +110,7 @@ func (ns *mpns) resolveOnce(ctx context.Context, name string, opts *ResolveOpts)
110
if err == nil {
111
res, ok := ns.resolvers["pubsub"]
112
if ok {
112
- p, err := res.resolveOnce(ctx, key, opts)
113
+ p, err := res.resolveOnce(ctx, key, options)
114
if err == nil {
115
return makePath(p)
116
}
@@ -117,7 +118,7 @@ func (ns *mpns) resolveOnce(ctx context.Context, name string, opts *ResolveOpts)
118
119
res, ok = ns.resolvers["dht"]
120
if ok {
120
- p, err := res.resolveOnce(ctx, key, opts)
121
+ p, err := res.resolveOnce(ctx, key, options)
122
if err == nil {
123
return makePath(p)
124
}
@@ -129,7 +130,7 @@ func (ns *mpns) resolveOnce(ctx context.Context, name string, opts *ResolveOpts)
130
if isd.IsDomain(key) {
131
res, ok := ns.resolvers["dns"]
132
if ok {
132
- p, err := res.resolveOnce(ctx, key, opts)
133
+ p, err := res.resolveOnce(ctx, key, options)
134
if err == nil {
135
return makePath(p)
136
}
@@ -140,7 +141,7 @@ func (ns *mpns) resolveOnce(ctx context.Context, name string, opts *ResolveOpts)
141
142
res, ok := ns.resolvers["proquint"]
143
if ok {
143
- p, err := res.resolveOnce(ctx, key, opts)
144
+ p, err := res.resolveOnce(ctx, key, options)
145
if err == nil {
146
return makePath(p)
147
}
namesys/namesys_test.go
+8
-9
@@ -6,6 +6,7 @@ import (
6
7
context "context"
8
9
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
10
path "github.com/ipfs/go-ipfs/path"
11
"github.com/ipfs/go-ipfs/unixfs"
12
@@ -20,9 +21,7 @@ type mockResolver struct {
21
}
22
23
func testResolution(t *testing.T, resolver Resolver, name string, depth uint, expected string, expError error) {
23
- opts := DefaultResolveOpts()
24
- opts.Depth = depth
25
- p, err := resolver.Resolve(context.Background(), name, opts)
24
+ p, err := resolver.Resolve(context.Background(), name, opts.Depth(depth))
25
if err != expError {
26
t.Fatal(fmt.Errorf(
27
"Expected %s with a depth of %d to have a '%s' error, but got '%s'",
@@ -35,7 +34,7 @@ func testResolution(t *testing.T, resolver Resolver, name string, depth uint, ex
34
}
35
}
36
38
-func (r *mockResolver) resolveOnce(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
37
+func (r *mockResolver) resolveOnce(ctx context.Context, name string, opts *opts.ResolveOpts) (path.Path, error) {
38
return path.ParsePath(r.entries[name])
39
}
40
@@ -65,14 +64,14 @@ func TestNamesysResolution(t *testing.T) {
64
},
65
}
66
68
- testResolution(t, r, "Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
69
- testResolution(t, r, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
70
- testResolution(t, r, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
67
+ testResolution(t, r, "Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
68
+ testResolution(t, r, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
69
+ testResolution(t, r, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
70
testResolution(t, r, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", 1, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", ErrResolveRecursion)
72
- testResolution(t, r, "/ipns/ipfs.io", DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
71
+ testResolution(t, r, "/ipns/ipfs.io", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
72
testResolution(t, r, "/ipns/ipfs.io", 1, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", ErrResolveRecursion)
73
testResolution(t, r, "/ipns/ipfs.io", 2, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", ErrResolveRecursion)
75
- testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
74
+ testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
75
testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", 1, "/ipns/ipfs.io", ErrResolveRecursion)
76
testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", 2, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", ErrResolveRecursion)
77
testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", 3, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", ErrResolveRecursion)
namesys/opts.go
deleted
-29
@@ -1,29 +0,0 @@
1
-package namesys
2
-
3
-import (
4
- "time"
5
-)
6
-
7
-// ResolveOpts specifies options for resolving an IPNS path
8
-type ResolveOpts struct {
9
- // Recursion depth limit
10
- Depth uint
11
- // The number of IPNS records to retrieve from the DHT
12
- // (the best record is selected from this set)
13
- DhtRecordCount uint
14
- // The amount of time to wait for DHT records to be fetched
15
- // and verified. A zero value indicates that there is no explicit
16
- // timeout (although there is an implicit timeout due to dial
17
- // timeouts within the DHT)
18
- DhtTimeout time.Duration
19
-}
20
-
21
-// DefaultResolveOpts returns the default options for resolving
22
-// an IPNS path
23
-func DefaultResolveOpts() *ResolveOpts {
24
- return &ResolveOpts{
25
- Depth: DefaultDepthLimit,
26
- DhtRecordCount: 16,
27
- DhtTimeout: time.Minute,
28
- }
29
-}
namesys/opts/opts.go
new
+68
@@ -0,0 +1,68 @@
1
+package namesys_opts
2
+
3
+import (
4
+ "time"
5
+)
6
+
7
+const (
8
+ // DefaultDepthLimit is the default depth limit used by Resolve.
9
+ DefaultDepthLimit = 32
10
+
11
+ // UnlimitedDepth allows infinite recursion in Resolve. You
12
+ // probably don't want to use this, but it's here if you absolutely
13
+ // trust resolution to eventually complete and can't put an upper
14
+ // limit on how many steps it will take.
15
+ UnlimitedDepth = 0
16
+)
17
+
18
+// ResolveOpts specifies options for resolving an IPNS path
19
+type ResolveOpts struct {
20
+ // Recursion depth limit
21
+ Depth uint
22
+ // The number of IPNS records to retrieve from the DHT
23
+ // (the best record is selected from this set)
24
+ DhtRecordCount uint
25
+ // The amount of time to wait for DHT records to be fetched
26
+ // and verified. A zero value indicates that there is no explicit
27
+ // timeout (although there is an implicit timeout due to dial
28
+ // timeouts within the DHT)
29
+ DhtTimeout time.Duration
30
+}
31
+
32
+// DefaultResolveOpts returns the default options for resolving
33
+// an IPNS path
34
+func DefaultResolveOpts() *ResolveOpts {
35
+ return &ResolveOpts{
36
+ Depth: DefaultDepthLimit,
37
+ DhtRecordCount: 16,
38
+ DhtTimeout: time.Minute,
39
+ }
40
+}
41
+
42
+type ResolveOpt func(*ResolveOpts)
43
+
44
+func Depth(depth uint) ResolveOpt {
45
+ return func(o *ResolveOpts) {
46
+ o.Depth = depth
47
+ }
48
+}
49
+
50
+func DhtRecordCount(count uint) ResolveOpt {
51
+ return func(o *ResolveOpts) {
52
+ o.DhtRecordCount = count
53
+ }
54
+}
55
+
56
+func DhtTimeout(timeout time.Duration) ResolveOpt {
57
+ return func(o *ResolveOpts) {
58
+ o.DhtTimeout = timeout
59
+ }
60
+}
61
+
62
+func ProcessOpts(opts []ResolveOpt) *ResolveOpts {
63
+ rsopts := DefaultResolveOpts()
64
+ for _, option := range opts {
65
+ option(rsopts)
66
+ }
67
+ return rsopts
68
+}
namesys/proquint.go
+4
-3
@@ -5,6 +5,7 @@ import (
5
6
context "context"
7
8
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
9
path "github.com/ipfs/go-ipfs/path"
10
proquint "gx/ipfs/QmYnf27kzqR2cxt6LFZdrAFJuQd6785fTkBvMuEj9EeRxM/proquint"
11
)
@@ -12,12 +13,12 @@ import (
13
type ProquintResolver struct{}
14
15
// Resolve implements Resolver.
15
-func (r *ProquintResolver) Resolve(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
16
- return resolve(ctx, r, name, opts, "/ipns/")
16
+func (r *ProquintResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
17
+ return resolve(ctx, r, name, opts.ProcessOpts(options), "/ipns/")
18
}
19
20
// resolveOnce implements resolver. Decodes the proquint string.
20
-func (r *ProquintResolver) resolveOnce(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
21
+func (r *ProquintResolver) resolveOnce(ctx context.Context, name string, options *opts.ResolveOpts) (path.Path, error) {
22
ok, err := proquint.IsProquint(name)
23
if err != nil || !ok {
24
return "", errors.New("not a valid proquint string")
namesys/pubsub.go
+4
-3
@@ -8,6 +8,7 @@ import (
8
"sync"
9
"time"
10
11
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
12
pb "github.com/ipfs/go-ipfs/namesys/pb"
13
path "github.com/ipfs/go-ipfs/path"
14
@@ -185,11 +186,11 @@ func (p *PubsubPublisher) publishRecord(ctx context.Context, k ci.PrivKey, value
186
}
187
188
// Resolve resolves a name through pubsub and default depth limit
188
-func (r *PubsubResolver) Resolve(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
189
- return resolve(ctx, r, name, opts, "/ipns/")
189
+func (r *PubsubResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
190
+ return resolve(ctx, r, name, opts.ProcessOpts(options), "/ipns/")
191
}
192
192
-func (r *PubsubResolver) resolveOnce(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
193
+func (r *PubsubResolver) resolveOnce(ctx context.Context, name string, options *opts.ResolveOpts) (path.Path, error) {
194
log.Debugf("PubsubResolve: resolve '%s'", name)
195
196
// retrieve the public key once (for verifying messages)
namesys/pubsub_test.go
+2
-2
@@ -180,14 +180,14 @@ func TestPubsubPublishSubscribe(t *testing.T) {
180
}
181
182
func checkResolveNotFound(ctx context.Context, t *testing.T, i int, resolver Resolver, name string) {
183
- _, err := resolver.Resolve(ctx, name, DefaultResolveOpts())
183
+ _, err := resolver.Resolve(ctx, name)
184
if err != ErrResolveFailed {
185
t.Fatalf("[resolver %d] unexpected error: %s", i, err.Error())
186
}
187
}
188
189
func checkResolve(ctx context.Context, t *testing.T, i int, resolver Resolver, name string, val path.Path) {
190
- xval, err := resolver.Resolve(ctx, name, DefaultResolveOpts())
190
+ xval, err := resolver.Resolve(ctx, name)
191
if err != nil {
192
t.Fatalf("[resolver %d] resolve failed: %s", i, err.Error())
193
}
namesys/republisher/repub_test.go
+2
-2
@@ -98,7 +98,7 @@ func verifyResolution(nodes []*core.IpfsNode, key string, exp path.Path) error {
98
ctx, cancel := context.WithCancel(context.Background())
99
defer cancel()
100
for _, n := range nodes {
101
- val, err := n.Namesys.Resolve(ctx, key, namesys.DefaultResolveOpts())
101
+ val, err := n.Namesys.Resolve(ctx, key)
102
if err != nil {
103
return err
104
}
@@ -114,7 +114,7 @@ func verifyResolutionFails(nodes []*core.IpfsNode, key string) error {
114
ctx, cancel := context.WithCancel(context.Background())
115
defer cancel()
116
for _, n := range nodes {
117
- _, err := n.Namesys.Resolve(ctx, key, namesys.DefaultResolveOpts())
117
+ _, err := n.Namesys.Resolve(ctx, key)
118
if err == nil {
119
return errors.New("expected resolution to fail")
120
}
namesys/resolve_test.go
+2
-2
@@ -40,7 +40,7 @@ func TestRoutingResolve(t *testing.T) {
40
t.Fatal(err)
41
}
42
43
- res, err := resolver.Resolve(context.Background(), pid.Pretty(), DefaultResolveOpts())
43
+ res, err := resolver.Resolve(context.Background(), pid.Pretty())
44
if err != nil {
45
t.Fatal(err)
46
}
@@ -125,7 +125,7 @@ func TestPrexistingRecord(t *testing.T) {
125
}
126
127
func verifyCanResolve(r Resolver, name string, exp path.Path) error {
128
- res, err := r.Resolve(context.Background(), name, DefaultResolveOpts())
128
+ res, err := r.Resolve(context.Background(), name)
129
if err != nil {
130
return err
131
}
namesys/routing.go
+9
-8
@@ -5,6 +5,7 @@ import (
5
"strings"
6
"time"
7
8
+ opts "github.com/ipfs/go-ipfs/namesys/opts"
9
pb "github.com/ipfs/go-ipfs/namesys/pb"
10
path "github.com/ipfs/go-ipfs/path"
11
@@ -104,23 +105,23 @@ func NewRoutingResolver(route routing.ValueStore, cachesize int) *routingResolve
105
}
106
107
// Resolve implements Resolver.
107
-func (r *routingResolver) Resolve(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
108
- return resolve(ctx, r, name, opts, "/ipns/")
108
+func (r *routingResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
109
+ return resolve(ctx, r, name, opts.ProcessOpts(options), "/ipns/")
110
}
111
112
// resolveOnce implements resolver. Uses the IPFS routing system to
113
// resolve SFS-like names.
113
-func (r *routingResolver) resolveOnce(ctx context.Context, name string, opts *ResolveOpts) (path.Path, error) {
114
+func (r *routingResolver) resolveOnce(ctx context.Context, name string, options *opts.ResolveOpts) (path.Path, error) {
115
log.Debugf("RoutingResolver resolving %s", name)
116
cached, ok := r.cacheGet(name)
117
if ok {
118
return cached, nil
119
}
120
120
- if opts.DhtTimeout != 0 {
121
+ if options.DhtTimeout != 0 {
122
// Resolution must complete within the timeout
123
var cancel context.CancelFunc
123
- ctx, cancel = context.WithTimeout(ctx, opts.DhtTimeout)
124
+ ctx, cancel = context.WithTimeout(ctx, options.DhtTimeout)
125
defer cancel()
126
}
127
@@ -153,7 +154,7 @@ func (r *routingResolver) resolveOnce(ctx context.Context, name string, opts *Re
154
// Note that the DHT will call the ipns validator when retrieving
155
// the value, which in turn verifies the ipns record signature
156
_, ipnsKey := IpnsKeysForID(pid)
156
- val, err := r.getValue(ctx, ipnsKey, opts)
157
+ val, err := r.getValue(ctx, ipnsKey, options)
158
if err != nil {
159
log.Debugf("RoutingResolver: dht get for name %s failed: %s", name, err)
160
return "", err
@@ -186,9 +187,9 @@ func (r *routingResolver) resolveOnce(ctx context.Context, name string, opts *Re
187
}
188
}
189
189
-func (r *routingResolver) getValue(ctx context.Context, ipnsKey string, opts *ResolveOpts) ([]byte, error) {
190
+func (r *routingResolver) getValue(ctx context.Context, ipnsKey string, options *opts.ResolveOpts) ([]byte, error) {
191
// Get specified number of values from the DHT
191
- vals, err := r.routing.GetValues(ctx, ipnsKey, int(opts.DhtRecordCount))
192
+ vals, err := r.routing.GetValues(ctx, ipnsKey, int(options.DhtRecordCount))
193
if err != nil {
194
return nil, err
195
}