forked from TrueCloudLab/frostfs-node
[#1884] services/object: Fallback to GET in GET_RANGE
Current spec allows denying GET_RANGE requests from other storage nodes. However, GET should always be allowed and it is enough to perform GET_RANGE locally Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
parent
dde4d4df2a
commit
4baf00aa21
2 changed files with 26 additions and 0 deletions
|
@ -18,6 +18,7 @@ Changelog for NeoFS Node
|
||||||
- `container nodes` command to output list of nodes for container, grouped by replica (#1704)
|
- `container nodes` command to output list of nodes for container, grouped by replica (#1704)
|
||||||
- Configuration flag to ignore shard in `neofs-node` (#1840)
|
- Configuration flag to ignore shard in `neofs-node` (#1840)
|
||||||
- Add new RPC `TreeService.Healthcheck`
|
- Add new RPC `TreeService.Healthcheck`
|
||||||
|
- Fallback to `GET` if `GET_RANGE` from one storage nodes to another is denied by basic ACL (#1884)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Allow to evacuate shard data with `EvacuateShard` control RPC (#1800)
|
- Allow to evacuate shard data with `EvacuateShard` control RPC (#1800)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package getsvc
|
package getsvc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
coreclient "github.com/nspcc-dev/neofs-node/pkg/core/client"
|
coreclient "github.com/nspcc-dev/neofs-node/pkg/core/client"
|
||||||
|
@ -143,12 +145,35 @@ func (c *clientWrapper) getObject(exec *execCtx, info coreclient.NodeInfo) (*obj
|
||||||
|
|
||||||
res, err := internalclient.PayloadRange(prm)
|
res, err := internalclient.PayloadRange(prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
var errAccessDenied *apistatus.ObjectAccessDenied
|
||||||
|
if errors.As(err, &errAccessDenied) {
|
||||||
|
// Current spec allows other storage node to deny access,
|
||||||
|
// fallback to GET_RANGE here.
|
||||||
|
obj, err := c.get(exec, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := obj.Payload()
|
||||||
|
from := rng.GetOffset()
|
||||||
|
to := from + rng.GetLength()
|
||||||
|
|
||||||
|
if pLen := uint64(len(payload)); to < from || pLen < from || pLen < to {
|
||||||
|
return nil, apistatus.ObjectOutOfRange{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return payloadOnlyObject(payload[from:to]), nil
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return payloadOnlyObject(res.PayloadRange()), nil
|
return payloadOnlyObject(res.PayloadRange()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return c.get(exec, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *clientWrapper) get(exec *execCtx, key *ecdsa.PrivateKey) (*object.Object, error) {
|
||||||
var prm internalclient.GetObjectPrm
|
var prm internalclient.GetObjectPrm
|
||||||
|
|
||||||
prm.SetContext(exec.context())
|
prm.SetContext(exec.context())
|
||||||
|
|
Loading…
Reference in a new issue