diff --git a/cmd/api-headers.go b/cmd/api-headers.go index 115b39071..7b72b739b 100644 --- a/cmd/api-headers.go +++ b/cmd/api-headers.go @@ -200,6 +200,9 @@ func setObjectHeaders(w http.ResponseWriter, objInfo ObjectInfo, rs *HTTPRangeSp fmt.Sprintf(`expiry-date="%s", rule-id="%s"`, expiryTime.Format(http.TimeFormat), ruleID), } } + if objInfo.TransitionStatus == lifecycle.TransitionComplete { + w.Header()[xhttp.AmzStorageClass] = []string{objInfo.StorageClass} + } } return nil diff --git a/cmd/bucket-lifecycle.go b/cmd/bucket-lifecycle.go index 90d1ccf77..03d64d4ec 100644 --- a/cmd/bucket-lifecycle.go +++ b/cmd/bucket-lifecycle.go @@ -168,6 +168,23 @@ func validateTransitionDestination(ctx context.Context, bucket string, targetLab return sameTarget, arn.Bucket, nil } +// transitionSC returns storage class label for this bucket +func transitionSC(ctx context.Context, bucket string) string { + cfg, err := globalBucketMetadataSys.GetLifecycleConfig(bucket) + if err != nil { + return "" + } + for _, rule := range cfg.Rules { + if rule.Status == Disabled { + continue + } + if rule.Transition.StorageClass != "" { + return rule.Transition.StorageClass + } + } + return "" +} + // return true if ARN representing transition storage class is present in a active rule // for the lifecycle configured on this bucket func transitionSCInUse(ctx context.Context, lfc *lifecycle.Lifecycle, bucket, arnStr string) bool { diff --git a/cmd/erasure-object.go b/cmd/erasure-object.go index 94c2d2291..e88688140 100644 --- a/cmd/erasure-object.go +++ b/cmd/erasure-object.go @@ -424,8 +424,14 @@ func (er erasureObjects) getObjectInfo(ctx context.Context, bucket, object strin // Make sure to return object info to provide extra information. return objInfo, toObjectErr(errMethodNotAllowed, bucket, object) } - - return fi.ToObjectInfo(bucket, object), nil + oi := fi.ToObjectInfo(bucket, object) + if oi.TransitionStatus == lifecycle.TransitionComplete { + // overlay storage class for transitioned objects with transition tier SC Label + if sc := transitionSC(ctx, bucket); sc != "" { + oi.StorageClass = sc + } + } + return oi, nil } func undoRename(disks []StorageAPI, srcBucket, srcEntry, dstBucket, dstEntry string, isDir bool, errs []error) {