[#246] pkg/client: Use io.Reader wrapper at object put

Object payload transferred in chunks. Size of the
chunks may be limited by transport protocols. To
split it we use `io.CopyBuffer` with pre-allocated
buffer size of one chunk. However this function may
ignore buffer if reader or writer implements
`WriteTo` or `ReadFrom` methods. Unfortunately
`bytes.Reader` implements `WriteTo` function.

To fix this we wrap reader so wrapper implements
only `io.Reader` interface.

Related to github.com/nspcc-dev/neofs-node/issues/338

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-01-25 10:59:08 +03:00 committed by Alex Vanin
parent c7dcea9e49
commit 9401724b9c

View file

@ -83,6 +83,10 @@ type SearchObjectParams struct {
filters object.SearchFilters filters object.SearchFilters
} }
type putObjectV2Reader struct {
r io.Reader
}
type putObjectV2Writer struct { type putObjectV2Writer struct {
key *ecdsa.PrivateKey key *ecdsa.PrivateKey
@ -134,6 +138,10 @@ func (t checksumType) toV2() v2refs.ChecksumType {
} }
} }
func (w *putObjectV2Reader) Read(p []byte) (int, error) {
return w.r.Read(p)
}
func (w *putObjectV2Writer) Write(p []byte) (int, error) { func (w *putObjectV2Writer) Write(p []byte) (int, error) {
w.chunkPart.SetChunk(p) w.chunkPart.SetChunk(p)
@ -272,8 +280,10 @@ func (c *Client) putObjectV2(ctx context.Context, p *PutObjectParams, opts ...Ca
stream: stream, stream: stream,
} }
r := &putObjectV2Reader{r: rPayload}
// copy payload from reader to stream writer // copy payload from reader to stream writer
_, err = io.CopyBuffer(w, rPayload, make([]byte, chunkSize)) _, err = io.CopyBuffer(w, r, make([]byte, chunkSize))
if err != nil && !errors.Is(errors.Cause(err), io.EOF) { if err != nil && !errors.Is(errors.Cause(err), io.EOF) {
return nil, errors.Wrap(err, "could not send payload bytes to Put object stream") return nil, errors.Wrap(err, "could not send payload bytes to Put object stream")
} }