base.go 1.21 KB
Newer Older
1 2 3 4
package namesys

import (
	"strings"
Steven Allen's avatar
Steven Allen committed
5
	"time"
6

7
	context "context"
8

Dirk McCormick's avatar
Dirk McCormick committed
9
	opts "github.com/ipfs/go-ipfs/namesys/opts"
Steven Allen's avatar
Steven Allen committed
10
	path "gx/ipfs/QmcjwUb36Z16NJkvDX6ccXPqsFswo6AsRXynyXcLLCphV2/go-path"
11 12 13 14
)

type resolver interface {
	// resolveOnce looks up a name once (without recursion).
Steven Allen's avatar
Steven Allen committed
15
	resolveOnce(ctx context.Context, name string, options *opts.ResolveOpts) (value path.Path, ttl time.Duration, err error)
16 17 18
}

// resolve is a helper for implementing Resolver.ResolveN using resolveOnce.
Dirk McCormick's avatar
Dirk McCormick committed
19 20
func resolve(ctx context.Context, r resolver, name string, options *opts.ResolveOpts, prefixes ...string) (path.Path, error) {
	depth := options.Depth
21
	for {
Steven Allen's avatar
Steven Allen committed
22
		p, _, err := r.resolveOnce(ctx, name, options)
23 24 25
		if err != nil {
			return "", err
		}
26
		log.Debugf("resolved %s to %s", name, p.String())
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

		if strings.HasPrefix(p.String(), "/ipfs/") {
			// we've bottomed out with an IPFS path
			return p, nil
		}

		if depth == 1 {
			return p, ErrResolveRecursion
		}

		matched := false
		for _, prefix := range prefixes {
			if strings.HasPrefix(p.String(), prefix) {
				matched = true
				if len(prefixes) == 1 {
					name = strings.TrimPrefix(p.String(), prefix)
				}
				break
			}
		}

		if !matched {
			return p, nil
		}

		if depth > 1 {
			depth--
		}
	}
}