From 67ad08e2f4de4e826c2b0e36127bece20760ec48 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 7 May 2015 14:31:14 -0700 Subject: [PATCH] namesys: Add recursive resolution This allows direct access to the earlier protocol-specific Resolve implementations. The guts of each protocol-specific resolver are in the internal resolveOnce method, and we've added a new: ResolveN(ctx, name, depth) method to the public interface. There's also: Resolve(ctx, name) which wraps ResolveN using DefaultDepthLimit. The extra API endpoint is intended to reduce the likelyhood of clients accidentally calling the more dangerous ResolveN with a nonsensically high or infinite depth. On IRC on 2015-05-17, Juan said: 15:34 If 90% of uses is the reduced API with no chance to screw it up, that's a huge win. 15:34 Why would those 90% not just set depth=0 or depth=1, depending on which they need? 15:34 Because people will start writing `r.Resolve(ctx, name, d)` where d is a variable. 15:35 And then accidentally set that variable to some huge number? 15:35 Grom experience, i've seen this happen _dozens_ of times. people screw trivial things up. 15:35 Why won't those same people be using ResolveN? 15:36 Because almost every example they see will tell them to use Resolve(), and they will mostly stay away from ResolveN. The per-prodocol versions also resolve recursively within their protocol. For example: DNSResolver.Resolve(ctx, "ipfs.io", 0) will recursively resolve DNS links until the referenced value is no longer a DNS link. I also renamed the multi-protocol ipfs NameSystem (defined in namesys/namesys.go) to 'mpns' (for Multi-Protocol Name System), because I wasn't clear on whether IPNS applied to the whole system or just to to the DHT-based system. The new name is unambiguously multi-protocol, which is good. It would be nice to have a distinct name for the DHT-based link system. Now that resolver output is always prefixed with a namespace and unprefixed mpns resolver input is interpreted as /ipfs/, core/corehttp/ipns_hostname.go can dispense with it's old manual /ipfs/ injection. Now that the Resolver interface handles recursion, we don't need the resolveRecurse helper in core/pathresolver.go. The pathresolver cleanup also called for an adjustment to FromSegments to more easily get slash-prefixed paths. Now that recursive resolution with the namesys/namesys.go composite resolver always gets you to an /ipfs/... path, there's no need for the /ipns/ special case in fuse/ipns/ipns_unix.go. Now that DNS links can be things other than /ipfs/ or DHT-link references (e.g. they could be /ipns/ references) I've also loosened the ParsePath logic to only attempt multihash validation on IPFS paths. It checks to ensure that other paths have a known-protocol prefix, but otherwise leaves them alone. I also changed some key-stringification from .Pretty() to .String() following the potential deprecation mentioned in util/key.go. This commit was moved from ipfs/kubo@3ead2443e5cd55ef551b811ac0a6764ed65c3ec1 --- gateway/core/corehttp/gateway_test.go | 9 ++++----- gateway/core/corehttp/ipns_hostname.go | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/gateway/core/corehttp/gateway_test.go b/gateway/core/corehttp/gateway_test.go index 818338c1c..01d4295b7 100644 --- a/gateway/core/corehttp/gateway_test.go +++ b/gateway/core/corehttp/gateway_test.go @@ -22,6 +22,10 @@ import ( type mockNamesys map[string]path.Path func (m mockNamesys) Resolve(ctx context.Context, name string) (value path.Path, err error) { + return m.ResolveN(ctx, name, namesys.DefaultDepthLimit) +} + +func (m mockNamesys) ResolveN(ctx context.Context, name string, depth int) (value path.Path, err error) { p, ok := m[name] if !ok { return "", namesys.ErrResolveFailed @@ -29,11 +33,6 @@ func (m mockNamesys) Resolve(ctx context.Context, name string) (value path.Path, return p, nil } -func (m mockNamesys) CanResolve(name string) bool { - _, ok := m[name] - return ok -} - func (m mockNamesys) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error { return errors.New("not implemented for mockNamesys") } diff --git a/gateway/core/corehttp/ipns_hostname.go b/gateway/core/corehttp/ipns_hostname.go index 7361001d1..a6e8e91f5 100644 --- a/gateway/core/corehttp/ipns_hostname.go +++ b/gateway/core/corehttp/ipns_hostname.go @@ -20,7 +20,7 @@ func IPNSHostnameOption() ServeOption { host := strings.SplitN(r.Host, ":", 2)[0] if p, err := n.Namesys.Resolve(ctx, host); err == nil { - r.URL.Path = "/ipfs/" + p.String() + r.URL.Path + r.URL.Path = p.String() + r.URL.Path } childMux.ServeHTTP(w, r) })