mirror of https://github.com/minio/minio.git
azure/s3 gateways: Pass ETag during GET call to avoid data corruption (#11024)
Both Azure & S3 gateways call for object information before returning the stream of the object, however, the object content/length could be modified meanwhile, which means it can return a corrupted object. Use ETag to ensure that the object was not modified during the GET call
This commit is contained in:
parent
970ddb424b
commit
cffdb01279
|
@ -812,7 +812,7 @@ func (a *azureObjects) GetObjectNInfo(ctx context.Context, bucket, object string
|
|||
|
||||
pr, pw := io.Pipe()
|
||||
go func() {
|
||||
err := a.GetObject(ctx, bucket, object, startOffset, length, pw, objInfo.ETag, opts)
|
||||
err := a.GetObject(ctx, bucket, object, startOffset, length, pw, objInfo.InnerETag, opts)
|
||||
pw.CloseWithError(err)
|
||||
}()
|
||||
// Setup cleanup function to cause the above go-routine to
|
||||
|
@ -833,8 +833,13 @@ func (a *azureObjects) GetObject(ctx context.Context, bucket, object string, sta
|
|||
return azureToObjectError(minio.InvalidRange{}, bucket, object)
|
||||
}
|
||||
|
||||
accessCond := azblob.BlobAccessConditions{}
|
||||
if etag != "" {
|
||||
accessCond.ModifiedAccessConditions.IfMatch = azblob.ETag(etag)
|
||||
}
|
||||
|
||||
blobURL := a.client.NewContainerURL(bucket).NewBlobURL(object)
|
||||
blob, err := blobURL.Download(ctx, startOffset, length, azblob.BlobAccessConditions{}, false)
|
||||
blob, err := blobURL.Download(ctx, startOffset, length, accessCond, false)
|
||||
if err != nil {
|
||||
return azureToObjectError(err, bucket, object)
|
||||
}
|
||||
|
@ -855,6 +860,8 @@ func (a *azureObjects) GetObjectInfo(ctx context.Context, bucket, object string,
|
|||
return objInfo, azureToObjectError(err, bucket, object)
|
||||
}
|
||||
|
||||
realETag := string(blob.ETag())
|
||||
|
||||
// Populate correct ETag's if possible, this code primarily exists
|
||||
// because AWS S3 indicates that
|
||||
//
|
||||
|
@ -866,7 +873,7 @@ func (a *azureObjects) GetObjectInfo(ctx context.Context, bucket, object string,
|
|||
//
|
||||
// Some applications depend on this behavior refer https://github.com/minio/minio/issues/6550
|
||||
// So we handle it here and make this consistent.
|
||||
etag := minio.ToS3ETag(string(blob.ETag()))
|
||||
etag := minio.ToS3ETag(realETag)
|
||||
metadata := blob.NewMetadata()
|
||||
contentMD5 := blob.ContentMD5()
|
||||
switch {
|
||||
|
@ -881,6 +888,7 @@ func (a *azureObjects) GetObjectInfo(ctx context.Context, bucket, object string,
|
|||
Bucket: bucket,
|
||||
UserDefined: azurePropertiesToS3Meta(metadata, blob.NewHTTPHeaders(), blob.ContentLength()),
|
||||
ETag: etag,
|
||||
InnerETag: realETag,
|
||||
ModTime: blob.LastModified(),
|
||||
Name: object,
|
||||
Size: blob.ContentLength(),
|
||||
|
|
|
@ -431,6 +431,11 @@ func (l *s3Objects) GetObject(ctx context.Context, bucket string, key string, st
|
|||
return minio.ErrorRespToObjectError(err, bucket, key)
|
||||
}
|
||||
}
|
||||
|
||||
if etag != "" {
|
||||
opts.SetMatchETag(etag)
|
||||
}
|
||||
|
||||
object, _, _, err := l.Client.GetObject(ctx, bucket, key, opts)
|
||||
if err != nil {
|
||||
return minio.ErrorRespToObjectError(err, bucket, key)
|
||||
|
|
|
@ -168,6 +168,9 @@ type ObjectInfo struct {
|
|||
// Hex encoded unique entity tag of the object.
|
||||
ETag string
|
||||
|
||||
// The ETag stored in the gateway backend
|
||||
InnerETag string
|
||||
|
||||
// Version ID of this object.
|
||||
VersionID string
|
||||
|
||||
|
|
Loading…
Reference in New Issue