From 2167ba0111d485a6531e6d05c3042ac47ef15c53 Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Thu, 21 Jan 2021 08:43:03 -0800 Subject: [PATCH] Feed correct part number to sio (#11326) When offsets were specified we relied on the first part number to be correct. Recalculate based on offset. --- cmd/object-api-utils.go | 12 ++++++++---- cmd/object-api-utils_test.go | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/cmd/object-api-utils.go b/cmd/object-api-utils.go index f93d0dcbc..4dc596d43 100644 --- a/cmd/object-api-utils.go +++ b/cmd/object-api-utils.go @@ -519,7 +519,7 @@ func partNumberToRangeSpec(oi ObjectInfo, partNumber int) *HTTPRangeSpec { // Returns the compressed offset which should be skipped. // If encrypted offsets are adjusted for encrypted block headers/trailers. // Since de-compression is after decryption encryption overhead is only added to compressedOffset. -func getCompressedOffsets(objectInfo ObjectInfo, offset int64) (compressedOffset int64, partSkip int64) { +func getCompressedOffsets(objectInfo ObjectInfo, offset int64) (compressedOffset int64, partSkip int64, firstPart int) { var skipLength int64 var cumulativeActualSize int64 var firstPartIdx int @@ -535,12 +535,13 @@ func getCompressedOffsets(objectInfo ObjectInfo, offset int64) (compressedOffset } } } + if isEncryptedMultipart(objectInfo) && firstPartIdx > 0 { off, _, _, _, _, err := objectInfo.GetDecryptedRange(partNumberToRangeSpec(objectInfo, firstPartIdx)) logger.LogIf(context.Background(), err) compressedOffset += off } - return compressedOffset, offset - skipLength + return compressedOffset, offset - skipLength, firstPartIdx } // GetObjectReader is a type that wraps a reader with a lock to @@ -608,6 +609,7 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, opts ObjectOptions, cl if opts.TransitionStatus == lifecycle.TransitionPending && isEncrypted { isEncrypted = false } + var firstPart = opts.PartNumber var skipLen int64 // Calculate range to read (different for encrypted/compressed objects) switch { @@ -626,7 +628,7 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, opts ObjectOptions, cl return nil, 0, 0, err } // In case of range based queries on multiparts, the offset and length are reduced. - off, decOff = getCompressedOffsets(oi, off) + off, decOff, firstPart = getCompressedOffsets(oi, off) decLength = length length = oi.Size - off @@ -652,7 +654,7 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, opts ObjectOptions, cl if isEncrypted { copySource := h.Get(xhttp.AmzServerSideEncryptionCopyCustomerAlgorithm) != "" // Attach decrypter on inputReader - inputReader, err = DecryptBlocksRequestR(inputReader, h, 0, opts.PartNumber, oi, copySource) + inputReader, err = DecryptBlocksRequestR(inputReader, h, 0, firstPart, oi, copySource) if err != nil { // Call the cleanup funcs for i := len(cFns) - 1; i >= 0; i-- { @@ -660,6 +662,8 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, opts ObjectOptions, cl } return nil, err } + oi.Size = decLength + } // Decompression reader. s2Reader := s2.NewReader(inputReader) diff --git a/cmd/object-api-utils_test.go b/cmd/object-api-utils_test.go index a98c3fa70..58be5dde1 100644 --- a/cmd/object-api-utils_test.go +++ b/cmd/object-api-utils_test.go @@ -519,8 +519,9 @@ func TestGetCompressedOffsets(t *testing.T) { offset int64 startOffset int64 snappyStartOffset int64 + firstPart int }{ - { + 0: { objInfo: ObjectInfo{ Parts: []ObjectPartInfo{ { @@ -536,8 +537,9 @@ func TestGetCompressedOffsets(t *testing.T) { offset: 79109865, startOffset: 39235668, snappyStartOffset: 12001001, + firstPart: 1, }, - { + 1: { objInfo: ObjectInfo{ Parts: []ObjectPartInfo{ { @@ -554,7 +556,7 @@ func TestGetCompressedOffsets(t *testing.T) { startOffset: 0, snappyStartOffset: 19109865, }, - { + 2: { objInfo: ObjectInfo{ Parts: []ObjectPartInfo{ { @@ -573,14 +575,18 @@ func TestGetCompressedOffsets(t *testing.T) { }, } for i, test := range testCases { - startOffset, snappyStartOffset := getCompressedOffsets(test.objInfo, test.offset) + startOffset, snappyStartOffset, firstPart := getCompressedOffsets(test.objInfo, test.offset) if startOffset != test.startOffset { t.Errorf("Test %d - expected startOffset %d but received %d", - i+1, test.startOffset, startOffset) + i, test.startOffset, startOffset) } if snappyStartOffset != test.snappyStartOffset { t.Errorf("Test %d - expected snappyOffset %d but received %d", - i+1, test.snappyStartOffset, snappyStartOffset) + i, test.snappyStartOffset, snappyStartOffset) + } + if firstPart != test.firstPart { + t.Errorf("Test %d - expected firstPart %d but received %d", + i, test.firstPart, firstPart) } } }