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.
This commit is contained in:
Janos Guljas 2017-12-01 10:27:17 +01:00
parent 5aa3eac22d
commit 6928ca2324
3 changed files with 44 additions and 14 deletions

View file

@ -290,9 +290,12 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
fmt.Fprint(w, newKey)
}
// HandleGetRaw handles a GET request to bzzr://<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
// - bzzr://<key> and responds with the raw content stored at the
// given storage key
// - bzzh://<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
@ -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
}

View file

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

View file

@ -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())
}
}
}