Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const (
SwarmActTimestampHeader = "Swarm-Act-Timestamp"
SwarmActPublisherHeader = "Swarm-Act-Publisher"
SwarmActHistoryAddressHeader = "Swarm-Act-History-Address"
SwarmChunkTypeHeader = "Swarm-Chunk-Type"

ImmutableHeader = "Immutable"
GasPriceHeader = "Gas-Price"
Expand Down
71 changes: 53 additions & 18 deletions pkg/api/chunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"io"
"net/http"
"strconv"
"strings"

"github.com/ethersphere/bee/v2/pkg/accesscontrol"
"github.com/ethersphere/bee/v2/pkg/cac"
Expand All @@ -37,6 +38,7 @@ func (s *Service) chunkUploadHandler(w http.ResponseWriter, r *http.Request) {
SwarmTag uint64 `map:"Swarm-Tag"`
Act bool `map:"Swarm-Act"`
HistoryAddress swarm.Address `map:"Swarm-Act-History-Address"`
ChunkType string `map:"Swarm-Chunk-Type"`
}{}
if response := s.mapStructure(r.Header, &headers); response != nil {
response("invalid header params", logger, w)
Expand Down Expand Up @@ -138,33 +140,66 @@ func (s *Service) chunkUploadHandler(w http.ResponseWriter, r *http.Request) {
return
}

chunk, err := cac.NewWithDataSpan(data)
if err != nil {
// not a valid cac chunk. Check if it's a replica soc chunk.
logger.Debug("chunk upload: create chunk failed", "error", err)

// FromChunk only uses the chunk data to recreate the soc chunk. So the address is irrelevant.
var chunk swarm.Chunk
switch strings.ToLower(headers.ChunkType) {
case "soc", "1":
sch, err := soc.FromChunk(swarm.NewChunk(swarm.EmptyAddress, data))
if err != nil {
logger.Debug("chunk upload: create soc chunk from data failed", "error", err)
logger.Error(nil, "chunk upload: create chunk error")
jsonhttp.InternalServerError(ow, "create chunk error")
logger.Debug("chunk upload: soc parse failed", "error", err)
logger.Error(nil, "chunk upload: invalid soc chunk")
jsonhttp.BadRequest(ow, "invalid soc chunk")
return
}
chunk, err = sch.Chunk()
if err != nil {
logger.Debug("chunk upload: create chunk from soc failed", "error", err)
logger.Error(nil, "chunk upload: create chunk error")
jsonhttp.InternalServerError(ow, "create chunk error")
if err != nil || !soc.Valid(chunk) {
logger.Debug("chunk upload: soc validation failed", "error", err)
logger.Error(nil, "chunk upload: invalid soc chunk")
jsonhttp.BadRequest(ow, "invalid soc chunk")
return
}

if !soc.Valid(chunk) {
logger.Debug("chunk upload: invalid soc chunk")
logger.Error(nil, "chunk upload: create chunk error")
jsonhttp.InternalServerError(ow, "create chunk error")
case "cac", "0":
chunk, err = cac.NewWithDataSpan(data)
if err != nil {
logger.Debug("chunk upload: cac parse failed", "error", err)
logger.Error(nil, "chunk upload: invalid cac chunk")
jsonhttp.BadRequest(ow, "invalid cac chunk")
return
}
case "":
// No chunk type specified — auto-detect.
// Try SOC first because CAC is too permissive (accepts any 8-4104 byte data).
sch, err := soc.FromChunk(swarm.NewChunk(swarm.EmptyAddress, data))
if err == nil {
chunk, err = sch.Chunk()
if err != nil {
logger.Debug("chunk upload: create chunk from soc failed", "error", err)
logger.Error(nil, "chunk upload: create chunk error")
jsonhttp.InternalServerError(ow, "create chunk error")
return
}
if !soc.Valid(chunk) {
chunk, err = cac.NewWithDataSpan(data)
if err != nil {
logger.Debug("chunk upload: create chunk failed", "error", err)
logger.Error(nil, "chunk upload: create chunk error")
jsonhttp.InternalServerError(ow, "create chunk error")
return
}
}
} else {
chunk, err = cac.NewWithDataSpan(data)
if err != nil {
logger.Debug("chunk upload: create chunk failed", "error", err)
logger.Error(nil, "chunk upload: create chunk error")
jsonhttp.InternalServerError(ow, "create chunk error")
return
}
}
default:
logger.Debug("chunk upload: invalid chunk type", "type", headers.ChunkType)
logger.Error(nil, "chunk upload: invalid chunk type")
jsonhttp.BadRequest(ow, "invalid chunk type; expected 'soc' or 'cac'")
return
}

err = putter.Put(r.Context(), chunk)
Expand Down
Loading
Loading