From 6928ca2324391fd96cfbe8766f40067cba8821f6 Mon Sep 17 00:00:00 2001 From: Janos Guljas Date: Fri, 1 Dec 2017 10:27:17 +0100 Subject: [PATCH] swarm/api: url scheme bzzh for getting hashes of swarm content (#15238) Update URI to support bzzh scheme and handle such HTTP requests by responding with hash of the content as a text/plain response. --- swarm/api/http/server.go | 36 +++++++++++++++++++++++------------- swarm/api/uri.go | 8 +++++++- swarm/api/uri_test.go | 14 ++++++++++++++ 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go index 65f6afab72..0b685b0534 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 bzzr:// 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 +// - bzzr:// and responds with the raw content stored at the +// given storage key +// - bzzh:// 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:/ with an Accept @@ -616,8 +626,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.HandleDelete(w, req) case "GET": - if uri.Raw() { - s.HandleGetRaw(w, req) + if uri.Raw() || uri.Hash() { + s.HandleGet(w, req) return } diff --git a/swarm/api/uri.go b/swarm/api/uri.go index caed4212d5..117ecf5d25 100644 --- a/swarm/api/uri.go +++ b/swarm/api/uri.go @@ -30,6 +30,8 @@ type URI struct { // * bzzr - raw swarm content // * bzzi - immutable URI of an entry in a swarm manifest // (address is not resolved) + // * bzzh - hash of swarm content + // Scheme string // Addr is either a hexadecimal storage key or it an address which @@ -60,7 +62,7 @@ func Parse(rawuri string) (*URI, error) { // check the scheme is valid switch uri.Scheme { - case "bzz", "bzzi", "bzzr": + case "bzz", "bzzi", "bzzr", "bzzh": default: return nil, fmt.Errorf("unknown scheme %q", u.Scheme) } @@ -91,6 +93,10 @@ func (u *URI) Immutable() bool { return u.Scheme == "bzzi" } +func (u *URI) Hash() bool { + return u.Scheme == "bzzh" +} + 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 7d4160601d..b858bd7d58 100644 --- a/swarm/api/uri_test.go +++ b/swarm/api/uri_test.go @@ -28,6 +28,7 @@ func TestParseURI(t *testing.T) { expectErr bool expectRaw bool expectImmutable bool + expectHash bool } tests := []test{ { @@ -95,6 +96,16 @@ func TestParseURI(t *testing.T) { uri: "bzz://abc123/path/to/entry", expectURI: &URI{Scheme: "bzz", Addr: "abc123", Path: "path/to/entry"}, }, + { + uri: "bzzh:", + expectURI: &URI{Scheme: "bzzh"}, + expectHash: true, + }, + { + uri: "bzzh:/", + expectURI: &URI{Scheme: "bzzh"}, + expectHash: true, + }, } for _, x := range tests { actual, err := Parse(x.uri) @@ -116,5 +127,8 @@ func TestParseURI(t *testing.T) { if actual.Immutable() != x.expectImmutable { t.Fatalf("expected %s immutable to be %t, got %t", x.uri, x.expectImmutable, actual.Immutable()) } + if actual.Hash() != x.expectHash { + t.Fatalf("expected %s hash to be %t, got %t", x.uri, x.expectHash, actual.Hash()) + } } }