swarm: add CLI --ens-endpoint flag (#14386)

Implement a CLI flag that can be repeated to allow multiple ENS
resolvers for different TLDs.
This commit is contained in:
Janos Guljas
2017-12-01 10:32:14 +01:00
parent 5aa3eac22d
commit 057af8c5c8
5 changed files with 459 additions and 63 deletions

View File

@ -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