aboutsummaryrefslogtreecommitdiff
path: root/weed
diff options
context:
space:
mode:
Diffstat (limited to 'weed')
-rw-r--r--weed/s3api/s3_constants/extend_key.go4
-rw-r--r--weed/s3api/s3_constants/header.go3
-rw-r--r--weed/s3api/s3api_bucket_handlers.go42
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)
}