aboutsummaryrefslogtreecommitdiffstats
path: root/swarm/api/api.go
diff options
context:
space:
mode:
Diffstat (limited to 'swarm/api/api.go')
-rw-r--r--swarm/api/api.go64
1 files changed, 64 insertions, 0 deletions
diff --git a/swarm/api/api.go b/swarm/api/api.go
index 79de29a1c..d0c3754e0 100644
--- a/swarm/api/api.go
+++ b/swarm/api/api.go
@@ -17,6 +17,7 @@
package api
import (
+ "errors"
"fmt"
"io"
"net/http"
@@ -40,6 +41,69 @@ type Resolver interface {
Resolve(string) (common.Hash, error)
}
+// errNoResolver is returned by MultiResolver.Resolve if no resolver
+// can be found for the address.
+var errNoResolver = errors.New("no resolver")
+
+// MultiResolver is used to resolve URL addresses based on their TLDs.
+// Each TLD can have multiple resolvers, and the resoluton from the
+// first one in the sequence will be returned.
+type MultiResolver struct {
+ resolvers map[string][]Resolver
+}
+
+// MultiResolverOption sets options for MultiResolver and is used as
+// arguments for its constructor.
+type MultiResolverOption func(*MultiResolver)
+
+// MultiResolverOptionWithResolver adds a Resolver to a list of resolvers
+// for a specific TLD. If TLD is an empty string, the resolver will be added
+// to the list of default resolver, the ones that will be used for resolution
+// of addresses which do not have their TLD resolver specified.
+func MultiResolverOptionWithResolver(r Resolver, tld string) MultiResolverOption {
+ return func(m *MultiResolver) {
+ if _, ok := m.resolvers[tld]; !ok {
+ m.resolvers[tld] = []Resolver{}
+ }
+ m.resolvers[tld] = append(m.resolvers[tld], r)
+ }
+}
+
+// NewMultiResolver creates a new instance of MultiResolver.
+func NewMultiResolver(opts ...MultiResolverOption) (m *MultiResolver) {
+ m = &MultiResolver{
+ resolvers: map[string][]Resolver{},
+ }
+ for _, o := range opts {
+ o(m)
+ }
+ return m
+}
+
+// Resolve resolves address by choosing a Resolver by TLD.
+// If there are more default Resolvers, or for a specific TLD,
+// the Hash from the the first one which does not return error
+// will be returned.
+func (m MultiResolver) Resolve(addr string) (h common.Hash, err error) {
+ rs, _ := m.resolvers[""]
+ if i := strings.LastIndex(addr, "."); i >= 0 {
+ rstld, ok := m.resolvers[addr[i+1:]]
+ if ok {
+ rs = rstld
+ }
+ }
+ if rs == nil {
+ return h, errNoResolver
+ }
+ for _, r := range rs {
+ h, err = r.Resolve(addr)
+ if err == nil {
+ return
+ }
+ }
+ return
+}
+
/*
Api implements webserver/file system related content storage and retrieval
on top of the dpa