Skip to content
Draft
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
4 changes: 4 additions & 0 deletions pkg/local_object_storage/metabase/ec.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ func (db *DB) resolveECPartInMetaBucket(crs *bbolt.Cursor, parent oid.ID, pi iec
return oid.ID{}, object.NewSplitInfoError(sizeSplitInfo)
}

if pi.Index == -1 {
return id, nil
}

if (sizeSplitInfo == nil || sizeSplitInfo.GetLastPart().IsZero()) && getObjAttribute(partCrs, id, object.FilterFirstSplitObject) != nil {
if sizeSplitInfo == nil {
sizeSplitInfo = new(object.SplitInfo)
Expand Down
59 changes: 43 additions & 16 deletions pkg/services/object/get/ec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/services/object/internal"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
"github.com/nspcc-dev/neofs-sdk-go/container"
"github.com/nspcc-dev/neofs-sdk-go/container/acl"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/netmap"
"github.com/nspcc-dev/neofs-sdk-go/object"
Expand Down Expand Up @@ -1653,46 +1654,72 @@ func checkECPartInfoRequest(xHdrs []string, cnr container.Container) (iec.PartIn
}
}

if ruleIdxStr == "" && partIdxStr == "" {
if ruleIdxStr == "" {
if partIdxStr != "" {
return res, fmt.Errorf("%s X-header must be set in a correct EC part GET request (%s X-header found: %s)",
iec.AttributeRuleIdx, iec.AttributePartIdx, partIdxStr)
}

res.RuleIndex = -1
return res, nil
}

if (ruleIdxStr == "") != (partIdxStr == "") {
return res, fmt.Errorf("%s and %s X-headers must be set together", iec.AttributeRuleIdx, iec.AttributePartIdx)
}
var (
bACL = cnr.BasicACL()
ecRules = cnr.PlacementPolicy().ECRules()
)

// TODO: state limits in https://github.com/nspcc-dev/neofs-api. Share consts for them.
ruleIdx, err := strconv.ParseUint(ruleIdxStr, 10, 8)
if err != nil {
return res, fmt.Errorf("invalid %s X-header: %w", iec.AttributeRuleIdx, err)
}
res.RuleIndex = int(ruleIdx)
err = checkECRuleIdx(bACL, ecRules, res.RuleIndex)
if err != nil {
return res, err
}

if partIdxStr == "" {
res.Index = -1
return res, nil
}

partIdx, err := strconv.ParseUint(partIdxStr, 10, 8)
if err != nil {
return res, fmt.Errorf("invalid %s X-header: %w", iec.AttributePartIdx, err)
}
res.Index = int(partIdx)

if cnr.BasicACL() != 0 { // Uninitialized in tests, safe to do anyway, invalid requests will fail.
var ecRules = cnr.PlacementPolicy().ECRules()
err = checkECPartIdx(bACL, ecRules, res.RuleIndex, res.Index)
if err != nil {
return res, err
}

return res, nil
}

func checkECRuleIdx(bACL acl.Basic, ecRules []netmap.ECRule, ruleIdx int) error {
if bACL != 0 { // Uninitialized in tests, safe to do anyway, invalid requests will fail.
if len(ecRules) == 0 {
return res, errors.New("EC part requested in container without EC policy")
return errors.New("EC part requested in container without EC policy")
}

if int(ruleIdx) >= len(ecRules) {
return res, fmt.Errorf("EC rule index overflows container policy: idx=%d,rules=%d", ruleIdx, len(ecRules))
if ruleIdx >= len(ecRules) {
return fmt.Errorf("EC rule index overflows container policy: idx=%d,rules=%d", ruleIdx, len(ecRules))
}
}

return nil
}

if total := ecRules[ruleIdx].DataPartNum() + ecRules[ruleIdx].ParityPartNum(); int(partIdx) >= int(total) {
return res, fmt.Errorf("EC part index overflows container policy: idx=%d,parts=%d", partIdx, total)
func checkECPartIdx(bACL acl.Basic, ecRules []netmap.ECRule, ruleIdx, partIdx int) error {
if bACL != 0 { // Uninitialized in tests, safe to do anyway, invalid requests will fail.
if total := ecRules[ruleIdx].DataPartNum() + ecRules[ruleIdx].ParityPartNum(); partIdx >= int(total) {
return fmt.Errorf("EC part index overflows container policy: idx=%d,parts=%d", partIdx, total)
}
}

res.RuleIndex = int(ruleIdx)
res.Index = int(partIdx)

return res, nil
return nil
}

func checkECAttributesInReceivedObject(hdr object.Object, ruleIdx, partIdx string) error {
Expand Down
Loading