Skip to content

Commit 1c140f7

Browse files
authored
Merge pull request #3615 from nolash/bzzpathfix_real5
cmd/swarm, swarm/api: bzzr improve + networkid prio
2 parents f3c368c + e5a93bf commit 1c140f7

File tree

6 files changed

+187
-15
lines changed

6 files changed

+187
-15
lines changed

cmd/swarm/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import (
3939
"github.com/ethereum/go-ethereum/p2p/discover"
4040
"github.com/ethereum/go-ethereum/swarm"
4141
bzzapi "github.com/ethereum/go-ethereum/swarm/api"
42-
"github.com/ethereum/go-ethereum/swarm/network"
4342
"gopkg.in/urfave/cli.v1"
4443
)
4544

@@ -76,7 +75,6 @@ var (
7675
SwarmNetworkIdFlag = cli.IntFlag{
7776
Name: "bzznetworkid",
7877
Usage: "Network identifier (integer, default 3=swarm testnet)",
79-
Value: network.NetworkId,
8078
}
8179
SwarmConfigPathFlag = cli.StringFlag{
8280
Name: "bzzconfig",
@@ -242,13 +240,15 @@ func bzzd(ctx *cli.Context) error {
242240
}
243241

244242
func registerBzzService(ctx *cli.Context, stack *node.Node) {
243+
245244
prvkey := getAccount(ctx, stack)
246245

247246
chbookaddr := common.HexToAddress(ctx.GlobalString(ChequebookAddrFlag.Name))
248247
bzzdir := ctx.GlobalString(SwarmConfigPathFlag.Name)
249248
if bzzdir == "" {
250249
bzzdir = stack.InstanceDir()
251250
}
251+
252252
bzzconfig, err := bzzapi.NewConfig(bzzdir, chbookaddr, prvkey, ctx.GlobalUint64(SwarmNetworkIdFlag.Name))
253253
if err != nil {
254254
utils.Fatalf("unable to configure swarm: %v", err)
@@ -280,6 +280,7 @@ func registerBzzService(ctx *cli.Context, stack *node.Node) {
280280

281281
func getAccount(ctx *cli.Context, stack *node.Node) *ecdsa.PrivateKey {
282282
keyid := ctx.GlobalString(SwarmAccountFlag.Name)
283+
283284
if keyid == "" {
284285
utils.Fatalf("Option %q is required", SwarmAccountFlag.Name)
285286
}

swarm/api/api.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package api
1919
import (
2020
"fmt"
2121
"io"
22+
"net/http"
2223
"regexp"
2324
"strings"
2425
"sync"
@@ -71,6 +72,7 @@ type ErrResolve error
7172

7273
// DNS Resolver
7374
func (self *Api) Resolve(hostPort string, nameresolver bool) (storage.Key, error) {
75+
glog.V(logger.Detail).Infof("Resolving : %v", hostPort)
7476
if hashMatcher.MatchString(hostPort) || self.dns == nil {
7577
glog.V(logger.Detail).Infof("host is a contentHash: '%v'", hostPort)
7678
return storage.Key(common.Hex2Bytes(hostPort)), nil
@@ -86,8 +88,10 @@ func (self *Api) Resolve(hostPort string, nameresolver bool) (storage.Key, error
8688
glog.V(logger.Detail).Infof("host lookup: %v -> %v", err)
8789
return contentHash[:], err
8890
}
89-
90-
func parse(uri string) (hostPort, path string) {
91+
func Parse(uri string) (hostPort, path string) {
92+
if uri == "" {
93+
return
94+
}
9195
parts := slashes.Split(uri, 3)
9296
var i int
9397
if len(parts) == 0 {
@@ -111,7 +115,7 @@ func parse(uri string) (hostPort, path string) {
111115
}
112116

113117
func (self *Api) parseAndResolve(uri string, nameresolver bool) (key storage.Key, hostPort, path string, err error) {
114-
hostPort, path = parse(uri)
118+
hostPort, path = Parse(uri)
115119
//resolving host and port
116120
contentHash, err := self.Resolve(hostPort, nameresolver)
117121
glog.V(logger.Debug).Infof("Resolved '%s' to contentHash: '%s', path: '%s'", uri, contentHash, path)
@@ -153,14 +157,17 @@ func (self *Api) Get(uri string, nameresolver bool) (reader storage.LazySectionR
153157
}
154158

155159
glog.V(logger.Detail).Infof("getEntry(%s)", path)
160+
156161
entry, _ := trie.getEntry(path)
162+
157163
if entry != nil {
158164
key = common.Hex2Bytes(entry.Hash)
159165
status = entry.Status
160166
mimeType = entry.ContentType
161167
glog.V(logger.Detail).Infof("content lookup key: '%v' (%v)", key, mimeType)
162168
reader = self.dpa.Retrieve(key)
163169
} else {
170+
status = http.StatusNotFound
164171
err = fmt.Errorf("manifest entry for '%s' not found", path)
165172
glog.V(logger.Warn).Infof("%v", err)
166173
}

swarm/api/config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,17 @@ func NewConfig(path string, contract common.Address, prvKey *ecdsa.PrivateKey, n
8585
NetworkId: networkId,
8686
}
8787
data, err = ioutil.ReadFile(confpath)
88+
89+
// if not set in function param, then set default for swarm network, will be overwritten by config file if present
90+
if networkId == 0 {
91+
self.NetworkId = network.NetworkId
92+
}
93+
8894
if err != nil {
8995
if !os.IsNotExist(err) {
9096
return
9197
}
98+
9299
// file does not exist
93100
// write out config file
94101
err = self.Save()
@@ -97,6 +104,7 @@ func NewConfig(path string, contract common.Address, prvKey *ecdsa.PrivateKey, n
97104
}
98105
return
99106
}
107+
100108
// file exists, deserialise
101109
err = json.Unmarshal(data, self)
102110
if err != nil {
@@ -109,6 +117,12 @@ func NewConfig(path string, contract common.Address, prvKey *ecdsa.PrivateKey, n
109117
if keyhex != self.BzzKey {
110118
return nil, fmt.Errorf("bzz key does not match the one in the config file %v != %v", keyhex, self.BzzKey)
111119
}
120+
121+
// if set in function param, replace id set from config file
122+
if networkId != 0 {
123+
self.NetworkId = networkId
124+
}
125+
112126
self.Swap.SetKey(prvKey)
113127

114128
if (self.EnsRoot == common.Address{}) {

swarm/api/http/server.go

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/ethereum/go-ethereum/logger"
3333
"github.com/ethereum/go-ethereum/logger/glog"
3434
"github.com/ethereum/go-ethereum/swarm/api"
35+
"github.com/ethereum/go-ethereum/swarm/storage"
3536
"github.com/rs/cors"
3637
)
3738

@@ -194,17 +195,34 @@ func handler(w http.ResponseWriter, r *http.Request, a *api.Api) {
194195
}
195196
case r.Method == "GET" || r.Method == "HEAD":
196197
path = trailingSlashes.ReplaceAllString(path, "")
198+
if path == "" {
199+
http.Error(w, "Empty path not allowed", http.StatusBadRequest)
200+
return
201+
}
197202
if raw {
198-
// resolving host
199-
key, err := a.Resolve(path, nameresolver)
200-
if err != nil {
201-
glog.V(logger.Error).Infof("%v", err)
202-
http.Error(w, err.Error(), http.StatusBadRequest)
203-
return
203+
var reader storage.LazySectionReader
204+
parsedurl, _ := api.Parse(path)
205+
206+
if parsedurl == path {
207+
key, err := a.Resolve(parsedurl, nameresolver)
208+
if err != nil {
209+
glog.V(logger.Error).Infof("%v", err)
210+
http.Error(w, err.Error(), http.StatusBadRequest)
211+
return
212+
}
213+
reader = a.Retrieve(key)
214+
} else {
215+
var status int
216+
readertmp, _, status, err := a.Get(path, nameresolver)
217+
if err != nil {
218+
http.Error(w, err.Error(), status)
219+
return
220+
}
221+
reader = readertmp
204222
}
205223

206224
// retrieving content
207-
reader := a.Retrieve(key)
225+
208226
quitC := make(chan bool)
209227
size, err := reader.Size(quitC)
210228
if err != nil {

swarm/api/http/server_test.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Copyright 2017 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package http
18+
19+
import (
20+
"bytes"
21+
"io/ioutil"
22+
"net/http"
23+
"sync"
24+
"testing"
25+
"time"
26+
27+
"github.com/ethereum/go-ethereum/common"
28+
"github.com/ethereum/go-ethereum/swarm/api"
29+
"github.com/ethereum/go-ethereum/swarm/storage"
30+
)
31+
32+
func TestBzzrGetPath(t *testing.T) {
33+
34+
var err error
35+
36+
maxproxyattempts := 3
37+
38+
testmanifest := []string{
39+
`{"entries":[{"path":"a/","hash":"674af7073604ebfc0282a4ab21e5ef1a3c22913866879ebc0816f8a89896b2ed","contentType":"application/bzz-manifest+json","status":0}]}`,
40+
`{"entries":[{"path":"a","hash":"011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce","contentType":"","status":0},{"path":"b/","hash":"0a87b1c3e4bf013686cdf107ec58590f2004610ee58cc2240f26939f691215f5","contentType":"application/bzz-manifest+json","status":0}]}`,
41+
`{"entries":[{"path":"b","hash":"011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce","contentType":"","status":0},{"path":"c","hash":"011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce","contentType":"","status":0}]}`,
42+
}
43+
44+
testrequests := make(map[string]int)
45+
testrequests["/"] = 0
46+
testrequests["/a"] = 1
47+
testrequests["/a/b"] = 2
48+
testrequests["/x"] = 0
49+
testrequests[""] = 0
50+
51+
expectedfailrequests := []string{"", "/x"}
52+
53+
reader := [3]*bytes.Reader{}
54+
55+
key := [3]storage.Key{}
56+
57+
dir, _ := ioutil.TempDir("", "bzz-storage-test")
58+
59+
storeparams := &storage.StoreParams{
60+
ChunkDbPath: dir,
61+
DbCapacity: 5000000,
62+
CacheCapacity: 5000,
63+
Radius: 0,
64+
}
65+
66+
localStore, err := storage.NewLocalStore(storage.MakeHashFunc("SHA3"), storeparams)
67+
if err != nil {
68+
t.Fatal(err)
69+
}
70+
chunker := storage.NewTreeChunker(storage.NewChunkerParams())
71+
dpa := &storage.DPA{
72+
Chunker: chunker,
73+
ChunkStore: localStore,
74+
}
75+
dpa.Start()
76+
defer dpa.Stop()
77+
78+
wg := &sync.WaitGroup{}
79+
80+
for i, mf := range testmanifest {
81+
reader[i] = bytes.NewReader([]byte(mf))
82+
key[i], err = dpa.Store(reader[i], int64(len(mf)), wg, nil)
83+
if err != nil {
84+
t.Fatal(err)
85+
}
86+
wg.Wait()
87+
}
88+
89+
a := api.NewApi(dpa, nil)
90+
91+
/// \todo iterate port numbers up if fail
92+
StartHttpServer(a, &Server{Addr: "127.0.0.1:8504", CorsString: ""})
93+
// how to wait for ListenAndServe to have initialized? This is pretty cruuuude
94+
// if we fix it we don't need maxproxyattempts anymore either
95+
time.Sleep(1000 * time.Millisecond)
96+
for i := 0; i <= maxproxyattempts; i++ {
97+
_, err := http.Get("http://127.0.0.1:8504/bzzr:/" + common.ToHex(key[0])[2:] + "/a")
98+
if i == maxproxyattempts {
99+
t.Fatalf("Failed to connect to proxy after %v attempts: %v", i, err)
100+
} else if err != nil {
101+
time.Sleep(100 * time.Millisecond)
102+
continue
103+
}
104+
break
105+
}
106+
107+
for k, v := range testrequests {
108+
var resp *http.Response
109+
var respbody []byte
110+
111+
url := "http://127.0.0.1:8504/bzzr:/"
112+
if k[:] != "" {
113+
url += common.ToHex(key[0])[2:] + "/" + k[1:] + "?content_type=text/plain"
114+
}
115+
resp, err = http.Get(url)
116+
defer resp.Body.Close()
117+
respbody, err = ioutil.ReadAll(resp.Body)
118+
119+
if string(respbody) != testmanifest[v] {
120+
isexpectedfailrequest := false
121+
122+
for _, r := range expectedfailrequests {
123+
if k[:] == r {
124+
isexpectedfailrequest = true
125+
}
126+
}
127+
if isexpectedfailrequest == false {
128+
t.Fatalf("Response body does not match, expected: %v, got %v", testmanifest[v], string(respbody))
129+
}
130+
}
131+
}
132+
133+
}

swarm/api/manifest.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ func (self *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *man
302302
if (len(path) >= epl) && (path[:epl] == entry.Path) {
303303
glog.V(logger.Detail).Infof("entry.ContentType = %v", entry.ContentType)
304304
if entry.ContentType == manifestType {
305-
if self.loadSubTrie(entry, quitC) != nil {
305+
err := self.loadSubTrie(entry, quitC)
306+
if err != nil {
306307
return nil, 0
307308
}
308309
entry, pos = entry.subtrie.findPrefixOf(path[epl:], quitC)
@@ -312,8 +313,6 @@ func (self *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *man
312313
} else {
313314
pos = epl
314315
}
315-
} else {
316-
entry = nil
317316
}
318317
return
319318
}

0 commit comments

Comments
 (0)