From 409b61fe3c8046dc26f3442846e9f7032bebb9c5 Mon Sep 17 00:00:00 2001 From: holisticode Date: Thu, 13 Apr 2017 04:06:19 -0500 Subject: [PATCH] swarm/api: better name resolver handling (#3754) Fixes #3608 --- cmd/swarm/main.go | 2 ++ swarm/api/api.go | 28 +++++++++++++++------------- swarm/api/http/server_test.go | 28 ++++++++++++++++++++++++++++ swarm/swarm.go | 11 ++++++++--- 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index 833083b91f..26aa3e50ff 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -358,6 +358,8 @@ func registerBzzService(ctx *cli.Context, stack *node.Node) { if err != nil { utils.Fatalf("Can't connect: %v", err) } + } else { + swapEnabled = false } return swarm.NewSwarm(ctx, client, bzzconfig, swapEnabled, syncEnabled, cors) } diff --git a/swarm/api/api.go b/swarm/api/api.go index f58b7a53d8..26a9445d5f 100644 --- a/swarm/api/api.go +++ b/swarm/api/api.go @@ -17,7 +17,6 @@ package api import ( - "errors" "fmt" "io" "net/http" @@ -84,25 +83,28 @@ type ErrResolve error // DNS Resolver func (self *Api) Resolve(uri *URI) (storage.Key, error) { log.Trace(fmt.Sprintf("Resolving : %v", uri.Addr)) + + var err error + if !uri.Immutable() { + if self.dns != nil { + resolved, err := self.dns.Resolve(uri.Addr) + if err == nil { + return resolved[:], nil + } + } else { + err = fmt.Errorf("no DNS to resolve name") + } + } if hashMatcher.MatchString(uri.Addr) { - log.Trace(fmt.Sprintf("addr is a hash: %q", uri.Addr)) return storage.Key(common.Hex2Bytes(uri.Addr)), nil } - if uri.Immutable() { - return nil, errors.New("refusing to resolve immutable address") - } - if self.dns == nil { - return nil, fmt.Errorf("unable to resolve addr %q, resolver not configured", uri.Addr) - } - hash, err := self.dns.Resolve(uri.Addr) if err != nil { - log.Warn(fmt.Sprintf("DNS error resolving addr %q: %s", uri.Addr, err)) - return nil, ErrResolve(err) + return nil, fmt.Errorf("'%s' does not resolve: %v but is not a content hash", uri.Addr, err) } - log.Trace(fmt.Sprintf("addr lookup: %v -> %v", uri.Addr, hash)) - return hash[:], nil + return nil, fmt.Errorf("'%s' is not a content hash", uri.Addr) } + // Put provides singleton manifest creation on top of dpa store func (self *Api) Put(content, contentType string) (storage.Key, error) { r := strings.NewReader(content) diff --git a/swarm/api/http/server_test.go b/swarm/api/http/server_test.go index 942f3ba0b2..ceb8db75bb 100644 --- a/swarm/api/http/server_test.go +++ b/swarm/api/http/server_test.go @@ -99,4 +99,32 @@ func TestBzzrGetPath(t *testing.T) { } } + nonhashtests := []string{ + srv.URL + "/bzz:/name", + srv.URL + "/bzzi:/nonhash", + srv.URL + "/bzzr:/nonhash", + } + + nonhashresponses := []string{ + "error resolving name: 'name' does not resolve: no DNS to resolve name but is not a content hash\n", + "error resolving nonhash: 'nonhash' is not a content hash\n", + "error resolving nonhash: 'nonhash' does not resolve: no DNS to resolve name but is not a content hash\n", + } + + for i, url := range nonhashtests { + var resp *http.Response + var respbody []byte + + resp, err = http.Get(url) + + if err != nil { + t.Fatalf("Request failed: %v", err) + } + defer resp.Body.Close() + respbody, err = ioutil.ReadAll(resp.Body) + if string(respbody) != nonhashresponses[i] { + t.Fatalf("Non-Hash response body does not match, expected: %v, got: %v", nonhashresponses[i], string(respbody)) + } + } + } diff --git a/swarm/swarm.go b/swarm/swarm.go index eedac93f3a..442e68d517 100644 --- a/swarm/swarm.go +++ b/swarm/swarm.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/contracts/chequebook" "github.com/ethereum/go-ethereum/contracts/ens" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" @@ -134,9 +135,13 @@ func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, config *api. // set up high level api transactOpts := bind.NewKeyedTransactor(self.privateKey) - self.dns, err = ens.NewENS(transactOpts, config.EnsRoot, self.backend) - if err != nil { - return nil, err + if backend == (*ethclient.Client)(nil) { + log.Warn("No ENS, please specify non-empty --ethapi to use domain name resolution") + } else { + self.dns, err = ens.NewENS(transactOpts, config.EnsRoot, self.backend) + if err != nil { + return nil, err + } } log.Debug(fmt.Sprintf("-> Swarm Domain Name Registrar @ address %v", config.EnsRoot.Hex()))