Fix PutObject Trailing checksum (#20456)

PutObject would verify trailing checksums, but not store them.

Fixes #20455
This commit is contained in:
Klaus Post 2024-09-19 05:59:07 -07:00 committed by GitHub
parent e1c2344591
commit 05a6c170bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 21 additions and 5 deletions

View File

@ -1329,10 +1329,6 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st
} }
fi.DataDir = mustGetUUID() fi.DataDir = mustGetUUID()
fi.Checksum = opts.WantChecksum.AppendTo(nil, nil)
if opts.EncryptFn != nil {
fi.Checksum = opts.EncryptFn("object-checksum", fi.Checksum)
}
if ckSum := userDefined[ReplicationSsecChecksumHeader]; ckSum != "" { if ckSum := userDefined[ReplicationSsecChecksumHeader]; ckSum != "" {
if v, err := base64.StdEncoding.DecodeString(ckSum); err == nil { if v, err := base64.StdEncoding.DecodeString(ckSum); err == nil {
fi.Checksum = v fi.Checksum = v
@ -1460,7 +1456,13 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st
actualSize = n actualSize = n
} }
} }
if fi.Checksum == nil {
// Trailing headers checksums should now be filled.
fi.Checksum = opts.WantChecksum.AppendTo(nil, nil)
if opts.EncryptFn != nil {
fi.Checksum = opts.EncryptFn("object-checksum", fi.Checksum)
}
}
for i, w := range writers { for i, w := range writers {
if w == nil { if w == nil {
onlineDisks[i] = nil onlineDisks[i] = nil
@ -1474,6 +1476,7 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st
// No need to add checksum to part. We already have it on the object. // No need to add checksum to part. We already have it on the object.
partsMetadata[i].AddObjectPart(1, "", n, actualSize, modTime, compIndex, nil) partsMetadata[i].AddObjectPart(1, "", n, actualSize, modTime, compIndex, nil)
partsMetadata[i].Versioned = opts.Versioned || opts.VersionSuspended partsMetadata[i].Versioned = opts.Versioned || opts.VersionSuspended
partsMetadata[i].Checksum = fi.Checksum
} }
userDefined["etag"] = r.MD5CurrentHexString() userDefined["etag"] = r.MD5CurrentHexString()

View File

@ -1960,6 +1960,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
return return
} }
opts.IndexCB = idxCb opts.IndexCB = idxCb
opts.WantChecksum = hashReader.Checksum()
if opts.PreserveETag != "" || if opts.PreserveETag != "" ||
r.Header.Get(xhttp.IfMatch) != "" || r.Header.Get(xhttp.IfMatch) != "" ||

View File

@ -335,6 +335,10 @@ func (c *Checksum) AppendTo(b []byte, parts []byte) []byte {
var tmp [binary.MaxVarintLen32]byte var tmp [binary.MaxVarintLen32]byte
n := binary.PutUvarint(tmp[:], uint64(c.Type)) n := binary.PutUvarint(tmp[:], uint64(c.Type))
crc := c.Raw crc := c.Raw
if c.Type.Trailing() {
// When we serialize we don't care if it was trailing.
c.Type ^= ChecksumTrailing
}
if len(crc) != c.Type.RawByteLen() { if len(crc) != c.Type.RawByteLen() {
return b return b
} }

View File

@ -366,6 +366,14 @@ func (r *Reader) ContentCRC() map[string]string {
return map[string]string{r.contentHash.Type.String(): r.contentHash.Encoded} return map[string]string{r.contentHash.Type.String(): r.contentHash.Encoded}
} }
// Checksum returns the content checksum if set.
func (r *Reader) Checksum() *Checksum {
if !r.contentHash.Type.IsSet() || !r.contentHash.Valid() {
return nil
}
return &r.contentHash
}
var _ io.Closer = (*Reader)(nil) // compiler check var _ io.Closer = (*Reader)(nil) // compiler check
// Close and release resources. // Close and release resources.