Skip to content

Commit

Permalink
feat: soc get api
Browse files Browse the repository at this point in the history
  • Loading branch information
nugaon committed Jun 6, 2024
1 parent ea0dfb3 commit 9d99af1
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 10 deletions.
1 change: 1 addition & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ const (
SwarmEncryptHeader = "Swarm-Encrypt"
SwarmIndexDocumentHeader = "Swarm-Index-Document"
SwarmErrorDocumentHeader = "Swarm-Error-Document"
SwarmSocSignature = "Swarm-Soc-Signature"
SwarmFeedIndexHeader = "Swarm-Feed-Index"
SwarmFeedIndexNextHeader = "Swarm-Feed-Index-Next"
SwarmOnlyRootChunk = "Swarm-Only-Root-Chunk"
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/bzz.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ func (s *Service) downloadHandler(logger log.Logger, w http.ResponseWriter, r *h
l int64
)
if rootCh != nil {
reader, l, err = joiner.NewWithRootCh(ctx, s.storer.Download(cache), s.storer.Cache(), reference, rootCh)
reader, l, err = joiner.NewJoiner(ctx, s.storer.Download(cache), s.storer.Cache(), reference, rootCh)
} else {
reader, l, err = joiner.New(ctx, s.storer.Download(cache), s.storer.Cache(), reference)
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,12 @@ func (s *Service) MountAPI() {
"/bytes",
"/chunks",
"/feeds",
"/soc",
rootPath + "/bzz",
rootPath + "/bytes",
rootPath + "/chunks",
rootPath + "/feeds",
rootPath + "/soc",
}

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -242,6 +244,7 @@ func (s *Service) mountAPI() {
})

handle("/soc/{owner}/{id}", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.socGetHandler),
"POST": web.ChainHandlers(
jsonhttp.NewMaxBodyBytesHandler(swarm.ChunkWithSpanSize),
web.FinalHandlerFunc(s.socUploadHandler),
Expand Down
60 changes: 60 additions & 0 deletions pkg/api/soc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
package api

import (
"bytes"
"encoding/hex"
"errors"
"io"
"net/http"
"strconv"
"strings"

"github.com/ethersphere/bee/v2/pkg/cac"
"github.com/ethersphere/bee/v2/pkg/jsonhttp"
Expand Down Expand Up @@ -173,3 +177,59 @@ func (s *Service) socUploadHandler(w http.ResponseWriter, r *http.Request) {

jsonhttp.Created(w, chunkAddressResponse{Reference: sch.Address()})
}

func (s *Service) socGetHandler(w http.ResponseWriter, r *http.Request) {
logger := s.logger.WithName("get_soc").Build()

paths := struct {
Owner []byte `map:"owner" validate:"required"`
ID []byte `map:"id" validate:"required"`
}{}
if response := s.mapStructure(mux.Vars(r), &paths); response != nil {
response("invalid path params", logger, w)
return
}

headers := struct {
OnlyRootChunk bool `map:"Swarm-Only-Root-Chunk"`
}{}
if response := s.mapStructure(r.Header, &headers); response != nil {
response("invalid header params", logger, w)
return
}

address, err := soc.CreateAddress(paths.ID, paths.Owner)
if err != nil {
jsonhttp.BadRequest(w, "soc address cannot be created")
}

sch, err := s.storer.ChunkStore().Get(r.Context(), address)
if err != nil {
jsonhttp.NotFound(w, "requested chunk cannot be retrievable")
}
socCh, err := soc.FromChunk(sch)
if err != nil {
jsonhttp.InternalServerError(w, "chunk is not a single owner chunk")
}

sig := socCh.Signature()
wc := socCh.WrappedChunk()

additionalHeaders := http.Header{
ContentTypeHeader: {"application/octet-stream"},
SwarmSocSignature: {hex.EncodeToString(sig)},
"Access-Control-Expose-Headers": {SwarmSocSignature},
}

if headers.OnlyRootChunk {
w.Header().Set(ContentLengthHeader, strconv.Itoa(len(wc.Data())))
// include additional headers
for name, values := range additionalHeaders {
w.Header().Set(name, strings.Join(values, ", "))
}
_, _ = io.Copy(w, bytes.NewReader(wc.Data()))
return
}

s.downloadHandler(logger, w, r, wc.Address(), additionalHeaders, true, false, wc)
}
33 changes: 24 additions & 9 deletions pkg/api/soc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,31 @@ func TestSOC(t *testing.T) {
)

// try to fetch the same chunk
rsrc := fmt.Sprintf("/chunks/" + s.Address().String())
resp := request(t, client, http.MethodGet, rsrc, nil, http.StatusOK)
data, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
t.Run("chunks fetch", func(t *testing.T) {
rsrc := fmt.Sprintf("/chunks/" + s.Address().String())
resp := request(t, client, http.MethodGet, rsrc, nil, http.StatusOK)
data, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}

if !bytes.Equal(s.Chunk().Data(), data) {
t.Fatal("data retrieved doesn't match uploaded content")
}
})

if !bytes.Equal(s.Chunk().Data(), data) {
t.Fatal("data retrieved doesn't match uploaded content")
}
t.Run("soc fetch", func(t *testing.T) {
rsrc := fmt.Sprintf("/soc/%s/%s", hex.EncodeToString(s.Owner), hex.EncodeToString(s.ID))
resp := request(t, client, http.MethodGet, rsrc, nil, http.StatusOK)
data, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}

if !bytes.Equal(s.WrappedChunk.Data()[swarm.SpanSize:], data) {
t.Fatal("data retrieved doesn't match uploaded content")
}
})
})

t.Run("postage", func(t *testing.T) {
Expand Down

0 comments on commit 9d99af1

Please sign in to comment.