diff options
-rw-r--r-- | cmd/utils/fdlimit_freebsd.go | 10 | ||||
-rw-r--r-- | cmd/utils/fdlimit_test.go | 12 | ||||
-rw-r--r-- | cmd/utils/fdlimit_unix.go | 10 | ||||
-rw-r--r-- | cmd/utils/fdlimit_windows.go | 6 | ||||
-rw-r--r-- | swarm/api/http/server.go | 36 | ||||
-rw-r--r-- | swarm/api/http/server_test.go | 36 | ||||
-rw-r--r-- | swarm/api/uri.go | 10 | ||||
-rw-r--r-- | swarm/api/uri_test.go | 14 |
8 files changed, 117 insertions, 17 deletions
diff --git a/cmd/utils/fdlimit_freebsd.go b/cmd/utils/fdlimit_freebsd.go index 4cb5013c8..f9ed8937e 100644 --- a/cmd/utils/fdlimit_freebsd.go +++ b/cmd/utils/fdlimit_freebsd.go @@ -52,3 +52,13 @@ func getFdLimit() (int, error) { } return int(limit.Cur), nil } + +// getFdMaxLimit retrieves the maximum number of file descriptors this process is +// allowed to request for itself. +func getFdMaxLimit() (int, error) { + var limit syscall.Rlimit + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err + } + return int(limit.Max), nil +} diff --git a/cmd/utils/fdlimit_test.go b/cmd/utils/fdlimit_test.go index 0a950a6c9..48489cf4c 100644 --- a/cmd/utils/fdlimit_test.go +++ b/cmd/utils/fdlimit_test.go @@ -16,12 +16,22 @@ package utils -import "testing" +import ( + "fmt" + "testing" +) // TestFileDescriptorLimits simply tests whether the file descriptor allowance // per this process can be retrieved. func TestFileDescriptorLimits(t *testing.T) { target := 4096 + hardlimit, err := getFdMaxLimit() + if err != nil { + t.Fatal(err) + } + if hardlimit < target { + t.Skip(fmt.Sprintf("system limit is less than desired test target: %d < %d", hardlimit, target)) + } if limit, err := getFdLimit(); err != nil || limit <= 0 { t.Fatalf("failed to retrieve file descriptor limit (%d): %v", limit, err) diff --git a/cmd/utils/fdlimit_unix.go b/cmd/utils/fdlimit_unix.go index 08e153bbd..c08d1fab0 100644 --- a/cmd/utils/fdlimit_unix.go +++ b/cmd/utils/fdlimit_unix.go @@ -48,3 +48,13 @@ func getFdLimit() (int, error) { } return int(limit.Cur), nil } + +// getFdMaxLimit retrieves the maximum number of file descriptors this process is +// allowed to request for itself. +func getFdMaxLimit() (int, error) { + var limit syscall.Rlimit + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err + } + return int(limit.Max), nil +} diff --git a/cmd/utils/fdlimit_windows.go b/cmd/utils/fdlimit_windows.go index 53aad3d7a..f239683d2 100644 --- a/cmd/utils/fdlimit_windows.go +++ b/cmd/utils/fdlimit_windows.go @@ -39,3 +39,9 @@ func getFdLimit() (int, error) { // Please see raiseFdLimit for the reason why we use hard coded 16K as the limit return 16384, nil } + +// getFdMaxLimit retrieves the maximum number of file descriptors this process is +// allowed to request for itself. +func getFdMaxLimit() (int, error) { + return getFdLimit() +} diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go index 3872cbc4f..74341899d 100644 --- a/swarm/api/http/server.go +++ b/swarm/api/http/server.go @@ -290,9 +290,12 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) { fmt.Fprint(w, newKey) } -// HandleGetRaw handles a GET request to bzz-raw://<key> and responds with -// the raw content stored at the given storage key -func (s *Server) HandleGetRaw(w http.ResponseWriter, r *Request) { +// HandleGet handles a GET request to +// - bzz-raw://<key> and responds with the raw content stored at the +// given storage key +// - bzz-hash://<key> and responds with the hash of the content stored +// at the given storage key as a text/plain response +func (s *Server) HandleGet(w http.ResponseWriter, r *Request) { key, err := s.api.Resolve(r.uri) if err != nil { s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err)) @@ -345,15 +348,22 @@ func (s *Server) HandleGetRaw(w http.ResponseWriter, r *Request) { return } - // allow the request to overwrite the content type using a query - // parameter - contentType := "application/octet-stream" - if typ := r.URL.Query().Get("content_type"); typ != "" { - contentType = typ - } - w.Header().Set("Content-Type", contentType) + switch { + case r.uri.Raw(): + // allow the request to overwrite the content type using a query + // parameter + contentType := "application/octet-stream" + if typ := r.URL.Query().Get("content_type"); typ != "" { + contentType = typ + } + w.Header().Set("Content-Type", contentType) - http.ServeContent(w, &r.Request, "", time.Now(), reader) + http.ServeContent(w, &r.Request, "", time.Now(), reader) + case r.uri.Hash(): + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, key) + } } // HandleGetFiles handles a GET request to bzz:/<manifest> with an Accept @@ -619,8 +629,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.HandleDelete(w, req) case "GET": - if uri.Raw() || uri.DeprecatedRaw() { - s.HandleGetRaw(w, req) + if uri.Raw() || uri.Hash() || uri.DeprecatedRaw() { + s.HandleGet(w, req) return } diff --git a/swarm/api/http/server_test.go b/swarm/api/http/server_test.go index dbbfa3b07..305d5cf7d 100644 --- a/swarm/api/http/server_test.go +++ b/swarm/api/http/server_test.go @@ -33,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/swarm/testutil" ) -func TestBzzrGetPath(t *testing.T) { +func TestBzzGetPath(t *testing.T) { var err error @@ -104,6 +104,38 @@ func TestBzzrGetPath(t *testing.T) { } } + for k, v := range testrequests { + var resp *http.Response + var respbody []byte + + url := srv.URL + "/bzz-hash:/" + if k[:] != "" { + url += common.ToHex(key[0])[2:] + "/" + k[1:] + } + 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 err != nil { + t.Fatalf("Read request body: %v", err) + } + + if string(respbody) != key[v].String() { + isexpectedfailrequest := false + + for _, r := range expectedfailrequests { + if k[:] == r { + isexpectedfailrequest = true + } + } + if !isexpectedfailrequest { + t.Fatalf("Response body does not match, expected: %v, got %v", key[v], string(respbody)) + } + } + } + for _, c := range []struct { path string json string @@ -197,6 +229,7 @@ func TestBzzrGetPath(t *testing.T) { srv.URL + "/bzz-immutable:/nonhash", srv.URL + "/bzz-raw:/nonhash", srv.URL + "/bzz-list:/nonhash", + srv.URL + "/bzz-hash:/nonhash", } nonhashresponses := []string{ @@ -204,6 +237,7 @@ func TestBzzrGetPath(t *testing.T) { "error resolving nonhash: immutable address not a content hash: "nonhash"", "error resolving nonhash: no DNS to resolve name: "nonhash"", "error resolving nonhash: no DNS to resolve name: "nonhash"", + "error resolving nonhash: no DNS to resolve name: "nonhash"", } for i, url := range nonhashtests { diff --git a/swarm/api/uri.go b/swarm/api/uri.go index af1dc7445..d8aafedf4 100644 --- a/swarm/api/uri.go +++ b/swarm/api/uri.go @@ -36,6 +36,8 @@ type URI struct { // * bzzr - raw swarm content // * bzzi - immutable URI of an entry in a swarm manifest // (address is not resolved) + // * bzz-hash - hash of swarm content + // Scheme string // Addr is either a hexadecimal storage key or it an address which @@ -56,7 +58,7 @@ type URI struct { // * <scheme>://<addr> // * <scheme>://<addr>/<path> // -// with scheme one of bzz, bzz-raw, bzz-immutable or bzz-list +// with scheme one of bzz, bzz-raw, bzz-immutable, bzz-list or bzz-hash // or deprecated ones bzzr and bzzi func Parse(rawuri string) (*URI, error) { u, err := url.Parse(rawuri) @@ -67,7 +69,7 @@ func Parse(rawuri string) (*URI, error) { // check the scheme is valid switch uri.Scheme { - case "bzz", "bzz-raw", "bzz-immutable", "bzz-list", "bzzr", "bzzi": + case "bzz", "bzz-raw", "bzz-immutable", "bzz-list", "bzz-hash", "bzzr", "bzzi": default: return nil, fmt.Errorf("unknown scheme %q", u.Scheme) } @@ -110,6 +112,10 @@ func (u *URI) DeprecatedImmutable() bool { return u.Scheme == "bzzi" } +func (u *URI) Hash() bool { + return u.Scheme == "bzz-hash" +} + func (u *URI) String() string { return u.Scheme + ":/" + u.Addr + "/" + u.Path } diff --git a/swarm/api/uri_test.go b/swarm/api/uri_test.go index babb2834e..137b4505d 100644 --- a/swarm/api/uri_test.go +++ b/swarm/api/uri_test.go @@ -29,6 +29,7 @@ func TestParseURI(t *testing.T) { expectRaw bool expectImmutable bool expectList bool + expectHash bool expectDeprecatedRaw bool expectDeprecatedImmutable bool } @@ -99,6 +100,16 @@ func TestParseURI(t *testing.T) { expectURI: &URI{Scheme: "bzz", Addr: "abc123", Path: "path/to/entry"}, }, { + uri: "bzz-hash:", + expectURI: &URI{Scheme: "bzz-hash"}, + expectHash: true, + }, + { + uri: "bzz-hash:/", + expectURI: &URI{Scheme: "bzz-hash"}, + expectHash: true, + }, + { uri: "bzz-list:", expectURI: &URI{Scheme: "bzz-list"}, expectList: true, @@ -152,6 +163,9 @@ func TestParseURI(t *testing.T) { if actual.List() != x.expectList { t.Fatalf("expected %s list to be %t, got %t", x.uri, x.expectList, actual.List()) } + if actual.Hash() != x.expectHash { + t.Fatalf("expected %s hash to be %t, got %t", x.uri, x.expectHash, actual.Hash()) + } if actual.DeprecatedRaw() != x.expectDeprecatedRaw { t.Fatalf("expected %s deprecated raw to be %t, got %t", x.uri, x.expectDeprecatedRaw, actual.DeprecatedRaw()) } |