mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-23 03:17:43 +08:00
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 <jbenet> If 90% of uses is the reduced API with no chance to screw it up, that's a huge win. 15:34 <wking> Why would those 90% not just set depth=0 or depth=1, depending on which they need? 15:34 <jbenet> Because people will start writing `r.Resolve(ctx, name, d)` where d is a variable. 15:35 <wking> And then accidentally set that variable to some huge number? 15:35 <jbenet> Grom experience, i've seen this happen _dozens_ of times. people screw trivial things up. 15:35 <wking> Why won't those same people be using ResolveN? 15:36 <jbenet> 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/<domain-name> 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.
52 lines
1.4 KiB
Go
52 lines
1.4 KiB
Go
package core
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
|
|
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
|
|
|
merkledag "github.com/ipfs/go-ipfs/merkledag"
|
|
path "github.com/ipfs/go-ipfs/path"
|
|
)
|
|
|
|
// ErrNoNamesys is an explicit error for when an IPFS node doesn't
|
|
// (yet) have a name system
|
|
var ErrNoNamesys = errors.New(
|
|
"core/resolve: no Namesys on IpfsNode - can't resolve ipns entry")
|
|
|
|
// 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 merkledage node. Effectively
|
|
// enables /ipns/, /dns/, etc. in commands.
|
|
func Resolve(ctx context.Context, n *IpfsNode, p path.Path) (*merkledag.Node, error) {
|
|
if strings.HasPrefix(p.String(), "/") {
|
|
// namespaced path (/ipfs/..., /ipns/..., etc.)
|
|
// TODO(cryptix): we sould be able to query the local cache for the path
|
|
if n.Namesys == nil {
|
|
return nil, ErrNoNamesys
|
|
}
|
|
|
|
seg := p.Segments()
|
|
extensions := seg[2:]
|
|
resolvable, err := path.FromSegments("/", seg[0], seg[1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
respath, err := n.Namesys.Resolve(ctx, resolvable.String())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
segments := append(respath.Segments(), extensions...)
|
|
p, err = path.FromSegments("/", segments...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// ok, we have an ipfs path now (or what we'll treat as one)
|
|
return n.Resolver.ResolvePath(ctx, p)
|
|
}
|