github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/namesys/namesys.go (about)

     1  package namesys
     2  
     3  import (
     4  	"strings"
     5  
     6  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
     7  	ci "github.com/ipfs/go-ipfs/p2p/crypto"
     8  	path "github.com/ipfs/go-ipfs/path"
     9  	routing "github.com/ipfs/go-ipfs/routing"
    10  )
    11  
    12  // mpns (a multi-protocol NameSystem) implements generic IPFS naming.
    13  //
    14  // Uses several Resolvers:
    15  // (a) ipfs routing naming: SFS-like PKI names.
    16  // (b) dns domains: resolves using links in DNS TXT records
    17  // (c) proquints: interprets string as the raw byte data.
    18  //
    19  // It can only publish to: (a) ipfs routing naming.
    20  //
    21  type mpns struct {
    22  	resolvers  map[string]resolver
    23  	publishers map[string]Publisher
    24  }
    25  
    26  // NewNameSystem will construct the IPFS naming system based on Routing
    27  func NewNameSystem(r routing.IpfsRouting) NameSystem {
    28  	return &mpns{
    29  		resolvers: map[string]resolver{
    30  			"dns":      newDNSResolver(),
    31  			"proquint": new(ProquintResolver),
    32  			"dht":      newRoutingResolver(r),
    33  		},
    34  		publishers: map[string]Publisher{
    35  			"/ipns/": NewRoutingPublisher(r),
    36  		},
    37  	}
    38  }
    39  
    40  // Resolve implements Resolver.
    41  func (ns *mpns) Resolve(ctx context.Context, name string) (path.Path, error) {
    42  	return ns.ResolveN(ctx, name, DefaultDepthLimit)
    43  }
    44  
    45  // ResolveN implements Resolver.
    46  func (ns *mpns) ResolveN(ctx context.Context, name string, depth int) (path.Path, error) {
    47  	if strings.HasPrefix(name, "/ipfs/") {
    48  		return path.ParsePath(name)
    49  	}
    50  
    51  	if !strings.HasPrefix(name, "/") {
    52  		return path.ParsePath("/ipfs/" + name)
    53  	}
    54  
    55  	return resolve(ctx, ns, name, depth, "/ipns/")
    56  }
    57  
    58  // resolveOnce implements resolver.
    59  func (ns *mpns) resolveOnce(ctx context.Context, name string) (path.Path, error) {
    60  	if !strings.HasPrefix(name, "/ipns/") {
    61  		name = "/ipns/" + name
    62  	}
    63  	segments := strings.SplitN(name, "/", 3)
    64  	if len(segments) < 3 || segments[0] != "" {
    65  		log.Warningf("Invalid name syntax for %s", name)
    66  		return "", ErrResolveFailed
    67  	}
    68  
    69  	for protocol, resolver := range ns.resolvers {
    70  		log.Debugf("Attempting to resolve %s with %s", name, protocol)
    71  		p, err := resolver.resolveOnce(ctx, segments[2])
    72  		if err == nil {
    73  			return p, err
    74  		}
    75  	}
    76  	log.Warningf("No resolver found for %s", name)
    77  	return "", ErrResolveFailed
    78  }
    79  
    80  // Publish implements Publisher
    81  func (ns *mpns) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error {
    82  	return ns.publishers["/ipns/"].Publish(ctx, name, value)
    83  }