diff --git a/pkg/services/object/patch/range_provider.go b/pkg/services/object/patch/range_provider.go index 755c5bf60..c66f333aa 100644 --- a/pkg/services/object/patch/range_provider.go +++ b/pkg/services/object/patch/range_provider.go @@ -25,11 +25,19 @@ type rangeProvider struct { commonPrm *objectUtil.CommonPrm localNodeKey *ecdsa.PrivateKey + + originalPayloadLength uint64 } var _ patcherSDK.RangeProvider = (*rangeProvider)(nil) func (r *rangeProvider) GetRange(ctx context.Context, rng *objectSDK.Range) io.Reader { + // Remote GetRange request to a container node uses an SDK-client that fails range validation + // with zero-length. However, from the patcher's point of view, such request is still valid. + if rng.GetOffset() == r.originalPayloadLength && rng.GetLength() == 0 { + return &nopReader{} + } + pipeReader, pipeWriter := io.Pipe() var rngPrm getsvc.RangePrm @@ -61,3 +69,9 @@ func (r *rangeProvider) GetRange(ctx context.Context, rng *objectSDK.Range) io.R return pipeReader } + +type nopReader struct{} + +func (nopReader) Read(_ []byte) (int, error) { + return 0, io.EOF +} diff --git a/pkg/services/object/patch/streamer.go b/pkg/services/object/patch/streamer.go index 84363530e..e04ac74c0 100644 --- a/pkg/services/object/patch/streamer.go +++ b/pkg/services/object/patch/streamer.go @@ -61,6 +61,7 @@ func (s *Streamer) init(ctx context.Context, req *objectV2.PatchRequest) error { if err != nil { return err } + hdr := hdrWithSig.GetHeader() commonPrm, err := util.CommonPrmFromV2(req) if err != nil { @@ -76,6 +77,8 @@ func (s *Streamer) init(ctx context.Context, req *objectV2.PatchRequest) error { commonPrm: commonPrm, localNodeKey: s.localNodeKey, + + originalPayloadLength: hdr.GetPayloadLength(), } putstm, err := s.putSvc.Put() @@ -83,7 +86,6 @@ func (s *Streamer) init(ctx context.Context, req *objectV2.PatchRequest) error { return err } - hdr := hdrWithSig.GetHeader() oV2 := new(objectV2.Object) hV2 := new(objectV2.Header) oV2.SetHeader(hV2)