diff options
Diffstat (limited to 'weed/s3api')
| -rw-r--r-- | weed/s3api/s3_constants/extend_key.go | 4 | ||||
| -rw-r--r-- | weed/s3api/s3_constants/header.go | 3 | ||||
| -rw-r--r-- | weed/s3api/s3api_bucket_handlers.go | 42 |
3 files changed, 49 insertions, 0 deletions
diff --git a/weed/s3api/s3_constants/extend_key.go b/weed/s3api/s3_constants/extend_key.go index e7eee0cc1..edfa4fe1d 100644 --- a/weed/s3api/s3_constants/extend_key.go +++ b/weed/s3api/s3_constants/extend_key.go @@ -35,4 +35,8 @@ const ( // Object lock enabled status ObjectLockEnabled = "Enabled" + + // Bucket versioning status + VersioningEnabled = "Enabled" + VersioningSuspended = "Suspended" ) diff --git a/weed/s3api/s3_constants/header.go b/weed/s3api/s3_constants/header.go index 48e4609e0..e0db5ef9a 100644 --- a/weed/s3api/s3_constants/header.go +++ b/weed/s3api/s3_constants/header.go @@ -51,6 +51,9 @@ const ( AmzAclReadAcp = "X-Amz-Grant-Read-Acp" AmzAclWriteAcp = "X-Amz-Grant-Write-Acp" + // S3 Object Lock headers + AmzBucketObjectLockEnabled = "X-Amz-Bucket-Object-Lock-Enabled" + // S3 conditional copy headers AmzCopySourceIfMatch = "X-Amz-Copy-Source-If-Match" AmzCopySourceIfNoneMatch = "X-Amz-Copy-Source-If-None-Match" diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go index ecc6af2ac..e9dc10cff 100644 --- a/weed/s3api/s3api_bucket_handlers.go +++ b/weed/s3api/s3api_bucket_handlers.go @@ -136,6 +136,48 @@ func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request) s3err.WriteErrorResponse(w, r, s3err.ErrInternalError) return } + + // Check for x-amz-bucket-object-lock-enabled header (S3 standard compliance) + if objectLockHeaderValue := r.Header.Get(s3_constants.AmzBucketObjectLockEnabled); strings.EqualFold(objectLockHeaderValue, "true") { + glog.V(3).Infof("PutBucketHandler: enabling Object Lock and Versioning for bucket %s due to x-amz-bucket-object-lock-enabled header", bucket) + + // Atomically update the configuration of the specified bucket. See the updateBucketConfig + // function definition for detailed documentation on parameters and behavior. + errCode := s3a.updateBucketConfig(bucket, func(bucketConfig *BucketConfig) error { + // Enable versioning (required for Object Lock) + bucketConfig.Versioning = s3_constants.VersioningEnabled + + // Enable Object Lock configuration + if bucketConfig.Entry.Extended == nil { + bucketConfig.Entry.Extended = make(map[string][]byte) + } + + // Create basic Object Lock configuration (enabled without default retention) + // The ObjectLockConfiguration struct is defined below in this file. + objectLockConfig := &ObjectLockConfiguration{ + ObjectLockEnabled: s3_constants.ObjectLockEnabled, + } + + // Store the configuration as XML in extended attributes + configXML, err := xml.Marshal(objectLockConfig) + if err != nil { + return fmt.Errorf("failed to marshal Object Lock configuration to XML: %v", err) + } + + bucketConfig.Entry.Extended[s3_constants.ExtObjectLockConfigKey] = configXML + bucketConfig.Entry.Extended[s3_constants.ExtObjectLockEnabledKey] = []byte(s3_constants.ObjectLockEnabled) + + return nil + }) + + if errCode != s3err.ErrNone { + glog.Errorf("PutBucketHandler: failed to enable Object Lock for bucket %s: %v", bucket, errCode) + s3err.WriteErrorResponse(w, r, errCode) + return + } + glog.V(3).Infof("PutBucketHandler: enabled Object Lock and Versioning for bucket %s", bucket) + } + w.Header().Set("Location", "/"+bucket) writeSuccessResponseEmpty(w, r) } |
