mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-09 19:32:24 +08:00
96 lines
2.8 KiB
Go
96 lines
2.8 KiB
Go
package namesys
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore"
|
|
path "github.com/ipfs/go-ipfs/path"
|
|
routing "github.com/ipfs/go-ipfs/routing"
|
|
ci "gx/ipfs/QmUEUu1CM8bxBJxc3ZLojAi8evhTr4byQogWstABet79oY/go-libp2p-crypto"
|
|
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
|
|
)
|
|
|
|
// mpns (a multi-protocol NameSystem) implements generic IPFS naming.
|
|
//
|
|
// Uses several Resolvers:
|
|
// (a) ipfs routing naming: SFS-like PKI names.
|
|
// (b) dns domains: resolves using links in DNS TXT records
|
|
// (c) proquints: interprets string as the raw byte data.
|
|
//
|
|
// It can only publish to: (a) ipfs routing naming.
|
|
//
|
|
type mpns struct {
|
|
resolvers map[string]resolver
|
|
publishers map[string]Publisher
|
|
}
|
|
|
|
// NewNameSystem will construct the IPFS naming system based on Routing
|
|
func NewNameSystem(r routing.IpfsRouting, ds ds.Datastore, cachesize int) NameSystem {
|
|
return &mpns{
|
|
resolvers: map[string]resolver{
|
|
"dns": newDNSResolver(),
|
|
"proquint": new(ProquintResolver),
|
|
"dht": NewRoutingResolver(r, cachesize),
|
|
},
|
|
publishers: map[string]Publisher{
|
|
"/ipns/": NewRoutingPublisher(r, ds),
|
|
},
|
|
}
|
|
}
|
|
|
|
const DefaultResolverCacheTTL = time.Minute
|
|
|
|
// Resolve implements Resolver.
|
|
func (ns *mpns) Resolve(ctx context.Context, name string) (path.Path, error) {
|
|
return ns.ResolveN(ctx, name, DefaultDepthLimit)
|
|
}
|
|
|
|
// ResolveN implements Resolver.
|
|
func (ns *mpns) ResolveN(ctx context.Context, name string, depth int) (path.Path, error) {
|
|
if strings.HasPrefix(name, "/ipfs/") {
|
|
return path.ParsePath(name)
|
|
}
|
|
|
|
if !strings.HasPrefix(name, "/") {
|
|
return path.ParsePath("/ipfs/" + name)
|
|
}
|
|
|
|
return resolve(ctx, ns, name, depth, "/ipns/")
|
|
}
|
|
|
|
// resolveOnce implements resolver.
|
|
func (ns *mpns) resolveOnce(ctx context.Context, name string) (path.Path, error) {
|
|
if !strings.HasPrefix(name, "/ipns/") {
|
|
name = "/ipns/" + name
|
|
}
|
|
segments := strings.SplitN(name, "/", 4)
|
|
if len(segments) < 3 || segments[0] != "" {
|
|
log.Warningf("Invalid name syntax for %s", name)
|
|
return "", ErrResolveFailed
|
|
}
|
|
|
|
for protocol, resolver := range ns.resolvers {
|
|
log.Debugf("Attempting to resolve %s with %s", segments[2], protocol)
|
|
p, err := resolver.resolveOnce(ctx, segments[2])
|
|
if err == nil {
|
|
if len(segments) > 3 {
|
|
return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3])
|
|
} else {
|
|
return p, err
|
|
}
|
|
}
|
|
}
|
|
log.Warningf("No resolver found for %s", name)
|
|
return "", ErrResolveFailed
|
|
}
|
|
|
|
// Publish implements Publisher
|
|
func (ns *mpns) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error {
|
|
return ns.publishers["/ipns/"].Publish(ctx, name, value)
|
|
}
|
|
|
|
func (ns *mpns) PublishWithEOL(ctx context.Context, name ci.PrivKey, val path.Path, eol time.Time) error {
|
|
return ns.publishers["/ipns/"].PublishWithEOL(ctx, name, val, eol)
|
|
}
|