diff --git a/src/content/docs/r2/api/s3/api.mdx b/src/content/docs/r2/api/s3/api.mdx index 4915b8902e5f8dc..5b110959868e378 100644 --- a/src/content/docs/r2/api/s3/api.mdx +++ b/src/content/docs/r2/api/s3/api.mdx @@ -3,10 +3,9 @@ title: S3 API compatibility pcx_content_type: reference sidebar: order: 1 - --- -import { Details } from "~/components" +import { Details } from "~/components"; R2 implements the S3 API to allow users and their applications to migrate with ease. When comparing to AWS S3, Cloudflare has removed some API operations' features and added others. The S3 API operations are listed below with their current implementation status. Feature implementation is currently in progress. Refer back to this page for updates. The API is available via the `https://.r2.cloudflarestorage.com` endpoint. Find your [account ID in the Cloudflare dashboard](/fundamentals/setup/find-account-and-zone-ids/). @@ -37,79 +36,71 @@ The following tables are related to bucket-level operations. Below is a list of implemented bucket-level operations. Refer to the Feature column to review which features have been implemented (✅) and have not been implemented (❌). - - -| API Name | Feature | -| ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ✅ [ListBuckets](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) | | -| ✅ [HeadBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [CreateBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) | ❌ ACL:
  ❌ x-amz-acl
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write
  ❌ x-amz-grant-write-acp
❌ Object Locking:
  ❌ x-amz-bucket-object-lock-enabled
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [DeleteBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [DeleteBucketCors](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [GetBucketCors](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [GetBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [GetBucketLocation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) | ❌ Bucket Owner:
❌ x-amz-expected-bucket-owner | -| ✅ [PutBucketCors](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html) | ❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [PutBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) | ❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | - - +| API Name | Feature | +| ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ✅ [ListBuckets](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) | | +| ✅ [HeadBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [CreateBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) | ❌ ACL:
  ❌ x-amz-acl
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write
  ❌ x-amz-grant-write-acp
❌ Object Locking:
  ❌ x-amz-bucket-object-lock-enabled
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [DeleteBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [DeleteBucketCors](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [GetBucketCors](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [GetBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [GetBucketLocation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) | ❌ Bucket Owner:
❌ x-amz-expected-bucket-owner | +| ✅ [PutBucketCors](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html) | ❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [PutBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) | ❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | ### Unimplemented bucket-level operations -
- - -| API Name | Feature | -| --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ❌ [GetBucketAccelerateConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAccelerateConfiguration.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketAcl](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketAnalyticsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAnalyticsConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketIntelligentTieringConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketIntelligentTieringConfiguration.html) | ❌ id | -| ❌ [GetBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketLifecycle](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycle.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketLogging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketNotification](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotification.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketNotificationConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketOwnershipControls](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketOwnershipControls.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketPolicy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicy.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketPolicyStatus](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicyStatus.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketReplication](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketRequestPayment](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketRequestPayment.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetBucketWebsite](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketWebsite.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetObjectLockConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLockConfiguration.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [GetPublicAccessBlock](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [ListBucketAnalyticsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html) | ❌ Query Parameters:
  ❌ continuation-token
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [ListBucketIntelligentTieringConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html) | ❌ Query Parameters:
  ❌ continuation-token
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [ListBucketInventoryConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html) | ❌ Query Parameters:
  ❌ continuation-token
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html) | ❌ Query Parameters:
  ❌ continuation-token
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketAccelerateConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAccelerateConfiguration.html) | ❌ Checksums:
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| API Name | Feature | +| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ❌ [GetBucketAccelerateConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAccelerateConfiguration.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketAcl](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketAnalyticsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAnalyticsConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketIntelligentTieringConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketIntelligentTieringConfiguration.html) | ❌ id | +| ❌ [GetBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketLifecycle](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycle.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketLogging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketNotification](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotification.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketNotificationConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketOwnershipControls](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketOwnershipControls.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketPolicy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicy.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketPolicyStatus](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicyStatus.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketReplication](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketRequestPayment](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketRequestPayment.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetBucketWebsite](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketWebsite.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetObjectLockConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLockConfiguration.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [GetPublicAccessBlock](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [ListBucketAnalyticsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html) | ❌ Query Parameters:
  ❌ continuation-token
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [ListBucketIntelligentTieringConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html) | ❌ Query Parameters:
  ❌ continuation-token
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [ListBucketInventoryConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html) | ❌ Query Parameters:
  ❌ continuation-token
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html) | ❌ Query Parameters:
  ❌ continuation-token
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketAccelerateConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAccelerateConfiguration.html) | ❌ Checksums:
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | | ❌ [PutBucketAcl](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html) | ❌ Permissions:
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write
  ❌ x-amz-grant-write-acp
❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketAnalyticsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) | ❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketIntelligentTieringConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketLifecycle](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) | ❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketLogging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketNotification](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotification.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:  
❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketNotificationConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotificationConfiguration.html) | ❌ Validation:
  ❌ x-amz-skip-destination-validation
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketOwnershipControls](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketOwnershipControls.html) | ❌ Checksums:
  ❌ Content-MD5
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketPolicy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html) | ❌ Validation:
  ❌ x-amz-confirm-remove-self-bucket-access
❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketReplication](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html) | ❌ Object Locking:
  ❌ x-amz-bucket-object-lock-token
❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketRequestPayment](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketRequestPayment.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html) | ❌ Multi-factor authentication:
  ❌ x-amz-mfa
❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutBucketWebsite](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketWebsite.html) | ❌ Checksums:
  ❌ Content-MD5
❌ Bucket Owner:
❌ x-amz-expected-bucket-owner | -| ❌ [PutObjectLockConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectLockConfiguration.html) | ❌ Object Locking:
  ❌ x-amz-bucket-object-lock-token
❌ Checksums:
  ❌ Content-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ❌ [PutPublicAccessBlock](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | - - +| ❌ [PutBucketAnalyticsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) | ❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketIntelligentTieringConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketLifecycle](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) | ❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketLogging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) | ❌ id
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketNotification](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotification.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:  
❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketNotificationConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotificationConfiguration.html) | ❌ Validation:
  ❌ x-amz-skip-destination-validation
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketOwnershipControls](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketOwnershipControls.html) | ❌ Checksums:
  ❌ Content-MD5
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketPolicy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html) | ❌ Validation:
  ❌ x-amz-confirm-remove-self-bucket-access
❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketReplication](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html) | ❌ Object Locking:
  ❌ x-amz-bucket-object-lock-token
❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketRequestPayment](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketRequestPayment.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html) | ❌ Multi-factor authentication:
  ❌ x-amz-mfa
❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutBucketWebsite](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketWebsite.html) | ❌ Checksums:
  ❌ Content-MD5
❌ Bucket Owner:
❌ x-amz-expected-bucket-owner | +| ❌ [PutObjectLockConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectLockConfiguration.html) | ❌ Object Locking:
  ❌ x-amz-bucket-object-lock-token
❌ Checksums:
  ❌ Content-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ❌ [PutPublicAccessBlock](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html) | ❌ Checksums:
  ❌ Content-MD5
  ❌ x-amz-sdk-checksum-algorithm
  ❌ x-amz-checksum-algorithm
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +
## Object-level operations @@ -120,48 +111,38 @@ The following tables are related to object-level operations. Below is a list of implemented object-level operations. Refer to the Feature column to review which features have been implemented (✅) and have not been implemented (❌). - - -| API Name | Feature | -| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| ✅ [HeadObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) | ✅ Conditional Operations:
  ✅ If-Match
  ✅ If-Modified-Since
  ✅ If-None-Match
  ✅ If-Unmodified-Since
✅ Range:
  ✅ Range (has no effect in HeadObject)
  ✅ partNumber
❌ SSE-C:
  ❌ x-amz-server-side-encryption-customer-algorithm
  ❌ x-amz-server-side-encryption-customer-key
  ❌ x-amz-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [ListObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) | Query Parameters:
  ✅ delimiter
  ✅ encoding-type
  ✅ marker
  ✅ max-keys
  ✅ prefix
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [ListObjectsV2](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) | Query Parameters:
  ✅ list-type
  ✅ continuation-token
  ✅ delimiter
  ✅ encoding-type
  ✅ fetch-owner
  ✅ max-keys
  ✅ prefix
  ✅ start-after
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) | ✅ Conditional Operations:
  ✅ If-Match
  ✅ If-Modified-Since
  ✅ If-None-Match
  ✅ If-Unmodified-Since
✅ Range:
  ✅ Range
  ✅ PartNumber
❌ SSE-C:
  ❌ x-amz-server-side-encryption-customer-algorithm
  ❌ x-amz-server-side-encryption-customer-key
  ❌ x-amz-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) | ✅ System Metadata:
  ✅ Content-Type
  ✅ Cache-Control
  ✅ Content-Disposition
  ✅ Content-Encoding
  ✅ Content-Language
  ✅ Expires
  ✅ Content-MD5
✅ Storage Class:
  ✅ x-amz-storage-class
    ✅ STANDARD
    ✅ STANDARD\_IA
❌ Object Lifecycle
❌ Website:
  ❌ x-amz-website-redirect-location
❌ SSE-C:
  ❌ x-amz-server-side-encryption
  ❌ x-amz-server-side-encryption-customer-algorithm
  ❌ x-amz-server-side-encryption-customer-key
  ❌ x-amz-server-side-encryption-customer-key-MD5
  ❌ x-amz-server-side-encryption-aws-kms-key-id
  ❌ x-amz-server-side-encryption-context
  ❌ x-amz-server-side-encryption-bucket-key-enabled
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Tagging:
  ❌ x-amz-tagging
❌ Object Locking:
  ❌ x-amz-object-lock-mode
  ❌ x-amz-object-lock-retain-until-date
  ❌ x-amz-object-lock-legal-hold
❌ ACL:
  ❌ x-amz-acl
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write-acp
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [DeleteObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) | ❌ Multi-factor authentication:
  ❌ x-amz-mfa
❌ Object Locking:
  ❌ x-amz-bypass-governance-retention
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [DeleteObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) | ❌ Multi-factor authentication:
  ❌ x-amz-mfa
❌ Object Locking:
  ❌ x-amz-bypass-governance-retention
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [ListMultipartUploads](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) | ✅ Query Parameters:
  ✅ delimiter
  ✅ encoding-type
  ✅ key-marker
  ✅️ max-uploads
  ✅ prefix
  ✅ upload-id-marker | -| ✅ [CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) | ✅ System Metadata:
  ✅ Content-Type
  ✅ Cache-Control
  ✅ Content-Disposition
  ✅ Content-Encoding
  ✅ Content-Language
  ✅ Expires
  ✅ Content-MD5
✅ Storage Class:
  ✅ x-amz-storage-class
    ✅ STANDARD
    ✅ STANDARD\_IA
❌ Website:
  ❌ x-amz-website-redirect-location
❌ SSE-C:
  ❌ x-amz-server-side-encryption
  ❌ x-amz-server-side-encryption-customer-algorithm
  ❌ x-amz-server-side-encryption-customer-key
  ❌ x-amz-server-side-encryption-customer-key-MD5
  ❌ x-amz-server-side-encryption-aws-kms-key-id
  ❌ x-amz-server-side-encryption-context
  ❌ x-amz-server-side-encryption-bucket-key-enabled
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Tagging:
  ❌ x-amz-tagging
❌ Object Locking:
  ❌ x-amz-object-lock-mode
  ❌ x-amz-object-lock-retain-until-date
  ❌ x-amz-object-lock-legal-hold
❌ ACL:
  ❌ x-amz-acl
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write-acp
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
❌ Request Payer:
  ❌ x-amz-request-payer | -| ✅ [AbortMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) | ❌ Request Payer:
  ❌ x-amz-request-payer | -| ✅ [CopyObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) | ✅ Operation Metadata:
  ✅ x-amz-metadata-directive
✅ System Metadata:
  ✅ Content-Type
  ✅ Cache-Control
  ✅ Content-Disposition
  ✅ Content-Encoding
  ✅ Content-Language
  ✅ Expires
✅ Conditional Operations:
  ✅ x-amz-copy-source
  ✅ x-amz-copy-source-if-match
  ✅ x-amz-copy-source-if-modified-since
  ✅ x-amz-copy-source-if-none-match
  ✅ x-amz-copy-source-if-unmodified-since
✅ Storage Class:
  ✅ x-amz-storage-class
    ✅ STANDARD
    ✅ STANDARD\_IA
❌ ACL:
  ❌ x-amz-acl
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write-acp
❌ Website:
  ❌ x-amz-website-redirect-location
❌ SSE-C:
  ❌ x-amz-server-side-encryption
  ❌ x-amz-server-side-encryption-customer-algorithm
  ❌ x-amz-server-side-encryption-customer-key
  ❌ x-amz-server-side-encryption-customer-key-MD5
  ❌ x-amz-server-side-encryption-aws-kms-key-id
  ❌ x-amz-server-side-encryption-context
  ❌ x-amz-server-side-encryption-bucket-key-enabled
  ❌ x-amz-copy-source-server-side-encryption-customer-algorithm
  ❌ x-amz-copy-source-server-side-encryption-customer-key
  ❌ x-amz-copy-source-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Tagging:
  ❌ x-amz-tagging
  ❌ x-amz-tagging-directive
❌ Object Locking:
  ❌ x-amz-object-lock-mode
  ❌ x-amz-object-lock-retain-until-date
  ❌ x-amz-object-lock-legal-hold
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
  ❌ x-amz-source-expected-bucket-owner
❌ Checksums:
  ❌ x-amz-checksum-algorithm | -| ✅ [UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) | ✅ System Metadata:
  ✅ Content-MD5
❌ SSE-C:
  ❌ x-amz-server-side-encryption
  ❌ x-amz-server-side-encryption-customer-algorithm
  ❌ x-amz-server-side-encryption-customer-key
  ❌ x-amz-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | -| ✅ [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) | ❌ Conditional Operations:
  ❌ x-amz-copy-source
  ❌ x-amz-copy-source-if-match
  ❌ x-amz-copy-source-if-modified-since
  ❌ x-amz-copy-source-if-none-match
  ❌ x-amz-copy-source-if-unmodified-since
✅ Range:
  ✅ x-amz-copy-source-range
❌ SSE-C:
  ❌ x-amz-server-side-encryption-customer-algorithm
  ❌ x-amz-server-side-encryption-customer-key
  ❌ x-amz-server-side-encryption-customer-key-MD5
  ❌ x-amz-copy-source-server-side-encryption-customer-algorithm
  ❌ x-amz-copy-source-server-side-encryption-customer-key
  ❌ x-amz-copy-source-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
  ❌ x-amz-source-expected-bucket-owner | -| ✅ [ListParts](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) | Query Parameters:
  ✅ max-parts
  ✅ part-number-marker
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | - - +| API Name | Feature | +| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| ✅ [HeadObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) | ✅ Conditional Operations:
  ✅ If-Match
  ✅ If-Modified-Since
  ✅ If-None-Match
  ✅ If-Unmodified-Since
✅ Range:
  ✅ Range (has no effect in HeadObject)
  ✅ partNumber
✅ SSE-C:
  ✅ x-amz-server-side-encryption-customer-algorithm
  ✅ x-amz-server-side-encryption-customer-key
  ✅ x-amz-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [ListObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) | Query Parameters:
  ✅ delimiter
  ✅ encoding-type
  ✅ marker
  ✅ max-keys
  ✅ prefix
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [ListObjectsV2](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) | Query Parameters:
  ✅ list-type
  ✅ continuation-token
  ✅ delimiter
  ✅ encoding-type
  ✅ fetch-owner
  ✅ max-keys
  ✅ prefix
  ✅ start-after
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) | ✅ Conditional Operations:
  ✅ If-Match
  ✅ If-Modified-Since
  ✅ If-None-Match
  ✅ If-Unmodified-Since
✅ Range:
  ✅ Range
  ✅ PartNumber
✅ SSE-C:
  ✅ x-amz-server-side-encryption-customer-algorithm
  ✅ x-amz-server-side-encryption-customer-key
  ✅ x-amz-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) | ✅ System Metadata:
  ✅ Content-Type
  ✅ Cache-Control
  ✅ Content-Disposition
  ✅ Content-Encoding
  ✅ Content-Language
  ✅ Expires
  ✅ Content-MD5
✅ Storage Class:
  ✅ x-amz-storage-class
    ✅ STANDARD
    ✅ STANDARD_IA
❌ Object Lifecycle
❌ Website:
  ❌ x-amz-website-redirect-location
❌ SSE:
  ❌ x-amz-server-side-encryption-aws-kms-key-id
  ❌ x-amz-server-side-encryption
  ❌ x-amz-server-side-encryption-context
  ❌ x-amz-server-side-encryption-bucket-key-enabled
✅ SSE-C:
  ✅ x-amz-server-side-encryption-customer-algorithm
  ✅ x-amz-server-side-encryption-customer-key
  ✅ x-amz-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Tagging:
  ❌ x-amz-tagging
❌ Object Locking:
  ❌ x-amz-object-lock-mode
  ❌ x-amz-object-lock-retain-until-date
  ❌ x-amz-object-lock-legal-hold
❌ ACL:
  ❌ x-amz-acl
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write-acp
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [DeleteObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) | ❌ Multi-factor authentication:
  ❌ x-amz-mfa
❌ Object Locking:
  ❌ x-amz-bypass-governance-retention
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [DeleteObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) | ❌ Multi-factor authentication:
  ❌ x-amz-mfa
❌ Object Locking:
  ❌ x-amz-bypass-governance-retention
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [ListMultipartUploads](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) | ✅ Query Parameters:
  ✅ delimiter
  ✅ encoding-type
  ✅ key-marker
  ✅️ max-uploads
  ✅ prefix
  ✅ upload-id-marker | +| ✅ [CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) | ✅ System Metadata:
  ✅ Content-Type
  ✅ Cache-Control
  ✅ Content-Disposition
  ✅ Content-Encoding
  ✅ Content-Language
  ✅ Expires
  ✅ Content-MD5
✅ Storage Class:
  ✅ x-amz-storage-class
    ✅ STANDARD
    ✅ STANDARD_IA
❌ Website:
  ❌ x-amz-website-redirect-location
❌ SSE:
  ❌ x-amz-server-side-encryption-aws-kms-key-id
  ❌ x-amz-server-side-encryption
  ❌ x-amz-server-side-encryption-context
  ❌ x-amz-server-side-encryption-bucket-key-enabled
✅ SSE-C:
  ✅ x-amz-server-side-encryption-customer-algorithm
  ✅ x-amz-server-side-encryption-customer-key
  ✅ x-amz-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Tagging:
  ❌ x-amz-tagging
❌ Object Locking:
  ❌ x-amz-object-lock-mode
  ❌ x-amz-object-lock-retain-until-date
  ❌ x-amz-object-lock-legal-hold
❌ ACL:
  ❌ x-amz-acl
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write-acp
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
❌ Request Payer:
  ❌ x-amz-request-payer | +| ✅ [AbortMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) | ❌ Request Payer:
  ❌ x-amz-request-payer | +| ✅ [CopyObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) | ✅ Operation Metadata:
  ✅ x-amz-metadata-directive
✅ System Metadata:
  ✅ Content-Type
  ✅ Cache-Control
  ✅ Content-Disposition
  ✅ Content-Encoding
  ✅ Content-Language
  ✅ Expires
✅ Conditional Operations:
  ✅ x-amz-copy-source
  ✅ x-amz-copy-source-if-match
  ✅ x-amz-copy-source-if-modified-since
  ✅ x-amz-copy-source-if-none-match
  ✅ x-amz-copy-source-if-unmodified-since
✅ Storage Class:
  ✅ x-amz-storage-class
    ✅ STANDARD
    ✅ STANDARD_IA
❌ ACL:
  ❌ x-amz-acl
  ❌ x-amz-grant-full-control
  ❌ x-amz-grant-read
  ❌ x-amz-grant-read-acp
  ❌ x-amz-grant-write-acp
❌ Website:
  ❌ x-amz-website-redirect-location
❌ SSE:
  ❌ x-amz-server-side-encryption
  ❌ x-amz-server-side-encryption-aws-kms-key-id
  ❌ x-amz-server-side-encryption-context
  ❌ x-amz-server-side-encryption-bucket-key-enabled
✅ SSE-C:
  ✅ x-amz-server-side-encryption-customer-algorithm
  ✅ x-amz-server-side-encryption-customer-key
  ✅ x-amz-server-side-encryption-customer-key-MD5
  ✅ x-amz-copy-source-server-side-encryption-customer-algorithm
  ✅ x-amz-copy-source-server-side-encryption-customer-key
  ✅ x-amz-copy-source-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Tagging:
  ❌ x-amz-tagging
  ❌ x-amz-tagging-directive
❌ Object Locking:
  ❌ x-amz-object-lock-mode
  ❌ x-amz-object-lock-retain-until-date
  ❌ x-amz-object-lock-legal-hold
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
  ❌ x-amz-source-expected-bucket-owner
❌ Checksums:
  ❌ x-amz-checksum-algorithm | +| ✅ [UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) | ✅ System Metadata:
  ✅ Content-MD5
❌ SSE:
  ❌ x-amz-server-side-encryption
✅ SSE-C:
  ✅ x-amz-server-side-encryption-customer-algorithm
  ✅ x-amz-server-side-encryption-customer-key
  ✅ x-amz-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | +| ✅ [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) | ❌ Conditional Operations:
  ❌ x-amz-copy-source
  ❌ x-amz-copy-source-if-match
  ❌ x-amz-copy-source-if-modified-since
  ❌ x-amz-copy-source-if-none-match
  ❌ x-amz-copy-source-if-unmodified-since
✅ Range:
  ✅ x-amz-copy-source-range
✅ SSE-C:
  ✅ x-amz-server-side-encryption-customer-algorithm
  ✅ x-amz-server-side-encryption-customer-key
  ✅ x-amz-server-side-encryption-customer-key-MD5
  ✅ x-amz-copy-source-server-side-encryption-customer-algorithm
  ✅ x-amz-copy-source-server-side-encryption-customer-key
  ✅ x-amz-copy-source-server-side-encryption-customer-key-MD5
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
  ❌ x-amz-source-expected-bucket-owner | +| ✅ [ListParts](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) | Query Parameters:
  ✅ max-parts
  ✅ part-number-marker
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | :::caution - Even though `ListObjects` is a supported operation, it is recommended that you use `ListObjectsV2` instead when developing applications. For more information, refer to [ListObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html). - ::: ### Unimplemented object-level operations -
+| API Name | Feature | +| ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ❌ [GetObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
❌ Request Payer:
  ❌ x-amz-request-payer | +| ❌ [PutObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm | +| ❌ [DeleteObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | - -| API Name | Feature | -| ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ❌ [GetObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
❌ Request Payer:
  ❌ x-amz-request-payer | -| ❌ [PutObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner
❌ Request Payer:
  ❌ x-amz-request-payer
❌ Checksums:
  ❌ x-amz-sdk-checksum-algorithm | -| ❌ [DeleteObjectTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html) | ❌ Bucket Owner:
  ❌ x-amz-expected-bucket-owner | - -
diff --git a/src/content/docs/r2/api/workers/workers-api-reference.mdx b/src/content/docs/r2/api/workers/workers-api-reference.mdx index 9a18d7760506eb0..104f2c27919019b 100644 --- a/src/content/docs/r2/api/workers/workers-api-reference.mdx +++ b/src/content/docs/r2/api/workers/workers-api-reference.mdx @@ -1,11 +1,11 @@ --- pcx_content_type: reference title: Workers API reference - --- + import { Type, MetaInfo } from "~/components"; -The in-Worker R2 API is accessed by binding an R2 bucket to a [Worker](/workers). The Worker you write can expose external access to buckets via a route or manipulate R2 objects internally. +The in-Worker R2 API is accessed by binding an R2 bucket to a [Worker](/workers). The Worker you write can expose external access to buckets via a route or manipulate R2 objects internally. The R2 API includes some extensions and semantic differences from the S3 API. If you need S3 compatibility, consider using the [S3-compatible API](/r2/api/s3/). @@ -17,12 +17,10 @@ R2 organizes the data you store, called objects, into containers, called buckets :::note[Bindings] - A binding is how your Worker interacts with external resources such as [KV Namespaces](/kv/concepts/kv-namespaces/), [Durable Objects](/durable-objects/), or [R2 Buckets](/r2/buckets/). A binding is a runtime variable that the Workers runtime provides to your code. You can declare a variable name in your `wrangler.toml` file that will be bound to these resources at runtime, and interact with them through this variable. Every binding's variable name and behavior is determined by you when deploying the Worker. Refer to [Environment Variables](/workers/configuration/environment-variables/) for more information. A binding is defined in the `wrangler.toml` file of your Worker project's directory. - ::: To bind your R2 bucket to your Worker, add the following to your `wrangler.toml` file. Update the `binding` property to a valid JavaScript variable identifier and `bucket_name` to the name of your R2 bucket: @@ -54,7 +52,7 @@ export default { const key = url.pathname.slice(1); switch (request.method) { - case 'PUT': + case "PUT": await env.MY_BUCKET.put(key, request.body); return new Response(`Put ${key} successfully!`); @@ -62,7 +60,7 @@ export default { return new Response(`${request.method} is not allowed.`, { status: 405, headers: { - Allow: 'PUT', + Allow: "PUT", }, }); } @@ -70,27 +68,27 @@ export default { }; ``` -* `head` +- `head` - * Retrieves the `R2Object` for the given key containing only object metadata, if the key exists, and `null` if the key does not exist. + - Retrieves the `R2Object` for the given key containing only object metadata, if the key exists, and `null` if the key does not exist. -* `get` +- `get` - * Retrieves the `R2ObjectBody` for the given key containing object metadata and the object body as a ReadableStream, if the key exists, and `null` if the key does not exist. - * In the event that a precondition specified in options fails, get() returns an R2Object with body undefined. + - Retrieves the `R2ObjectBody` for the given key containing object metadata and the object body as a ReadableStream, if the key exists, and `null` if the key does not exist. + - In the event that a precondition specified in options fails, get() returns an R2Object with body undefined. -* `put` +- `put` - * Stores the given value and metadata under the associated key. Once the write succeeds, returns an `R2Object` containing metadata about the stored Object. - * In the event that a precondition specified in options fails, put() returns `null`, and the object will not be stored. - * R2 writes are strongly consistent. Once the Promise resolves, all subsequent read operations will see this key value pair globally. + - Stores the given value and metadata under the associated key. Once the write succeeds, returns an `R2Object` containing metadata about the stored Object. + - In the event that a precondition specified in options fails, put() returns `null`, and the object will not be stored. + - R2 writes are strongly consistent. Once the Promise resolves, all subsequent read operations will see this key value pair globally. -* `delete` +- `delete` - * Deletes the given values and metadata under the associated keys. Once the delete succeeds, returns void. - * R2 deletes are strongly consistent. Once the Promise resolves, all subsequent read operations will no longer see the provided key value pairs globally. + - Deletes the given values and metadata under the associated keys. Once the delete succeeds, returns void. + - R2 deletes are strongly consistent. Once the Promise resolves, all subsequent read operations will no longer see the provided key value pairs globally. -* `list` +- `list` * Returns an R2Objects containing a list of R2Object contained within the bucket. * The returned list of objects is ordered lexicographically. @@ -99,108 +97,102 @@ export default { * `createMultipartUpload` - * Creates a multipart upload. - * Returns Promise which resolves to an `R2MultipartUpload` object representing the newly created multipart upload. Once the multipart upload has been created, the multipart upload can be immediately interacted with globally, either through the Workers API, or through the S3 API. - -* `resumeMultipartUpload` - - * Returns an object representing a multipart upload with the given key and uploadId. - * The resumeMultipartUpload operation does not perform any checks to ensure the validity of the uploadId, nor does it verify the existence of a corresponding active multipart upload. This is done to minimize latency before being able to call subsequent operations on the `R2MultipartUpload` object. + - Creates a multipart upload. + - Returns Promise which resolves to an `R2MultipartUpload` object representing the newly created multipart upload. Once the multipart upload has been created, the multipart upload can be immediately interacted with globally, either through the Workers API, or through the S3 API. +- `resumeMultipartUpload` + - Returns an object representing a multipart upload with the given key and uploadId. + - The resumeMultipartUpload operation does not perform any checks to ensure the validity of the uploadId, nor does it verify the existence of a corresponding active multipart upload. This is done to minimize latency before being able to call subsequent operations on the `R2MultipartUpload` object. ## `R2Object` definition `R2Object` is created when you `PUT` an object into an R2 bucket. `R2Object` represents the metadata of an object based on the information provided by the uploader. Every object that you `PUT` into an R2 bucket will have an `R2Object` created. +- `key` + - The object's key. -* `key` - - * The object's key. +- `version` -* `version` + - Random unique string associated with a specific upload of a key. - * Random unique string associated with a specific upload of a key. +- `size` -* `size` + - Size of the object in bytes. - * Size of the object in bytes. - -* `etag` +- `etag` :::note Cloudflare recommends using the `httpEtag` field when returning an etag in a response header. This ensures the etag is quoted and conforms to [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110#section-8.8.3). ::: -* The etag associated with the object upload. +- The etag associated with the object upload. -* `httpEtag` +- `httpEtag` - * The object's etag, in quotes so as to be returned as a header. + - The object's etag, in quotes so as to be returned as a header. -* `uploaded` +- `uploaded` - * A Date object representing the time the object was uploaded. + - A Date object representing the time the object was uploaded. -* `httpMetadata` +- `httpMetadata` - * Various HTTP headers associated with the object. Refer to [HTTP Metadata](#http-metadata). + - Various HTTP headers associated with the object. Refer to [HTTP Metadata](#http-metadata). -* `customMetadata` +- `customMetadata` - * A map of custom, user-defined metadata associated with the object. + - A map of custom, user-defined metadata associated with the object. -* `range` +- `range` - * A `R2Range` object containing the returned range of the object. + - A `R2Range` object containing the returned range of the object. -* `checksums` +- `checksums` - * A `R2Checksums` object containing the stored checksums of the object. Refer to [checksums](#checksums). + - A `R2Checksums` object containing the stored checksums of the object. Refer to [checksums](#checksums). -* `writeHttpMetadata` +- `writeHttpMetadata` - * Retrieves the `httpMetadata` from the `R2Object` and applies their corresponding HTTP headers to the `Headers` input object. Refer to [HTTP Metadata](#http-metadata). + - Retrieves the `httpMetadata` from the `R2Object` and applies their corresponding HTTP headers to the `Headers` input object. Refer to [HTTP Metadata](#http-metadata). -* `storageClass` +- `storageClass` - * The storage class associated with the object. Refer to [Storage Classes](#storage-class). + - The storage class associated with the object. Refer to [Storage Classes](#storage-class). +- `ssecKeyMd5` + - Hex-encoded MD5 hash of the [SSE-C](/r2/examples/ssec) key used for encryption (if one was provided). Hash can be used to identify which key is needed to decrypt object. ## `R2ObjectBody` definition `R2ObjectBody` represents an object's metadata combined with its body. It is returned when you `GET` an object from an R2 bucket. The full list of keys for `R2ObjectBody` includes the list below and all keys inherited from [`R2Object`](#r2object-definition). +- `body` + - The object's value. -* `body` - - * The object's value. - -* `bodyUsed` - - * Whether the object's value has been consumed or not. +- `bodyUsed` -* `arrayBuffer` + - Whether the object's value has been consumed or not. - * Returns a Promise that resolves to an `ArrayBuffer` containing the object's value. +- `arrayBuffer` -* `text` + - Returns a Promise that resolves to an `ArrayBuffer` containing the object's value. - * Returns a Promise that resolves to an string containing the object's value. +- `text` -* `json` + - Returns a Promise that resolves to an string containing the object's value. - * Returns a Promise that resolves to the given object containing the object's value. +- `json` -* `blob` - - * Returns a Promise that resolves to a binary Blob containing the object's value. + - Returns a Promise that resolves to the given object containing the object's value. +- `blob` + - Returns a Promise that resolves to a binary Blob containing the object's value. ## `R2MultipartUpload` definition @@ -210,54 +202,49 @@ Uncompleted multipart uploads will be automatically aborted after 7 days. :::note - An `R2MultipartUpload` object does not guarantee that there is an active underlying multipart upload corresponding to that object. A multipart upload can be completed or aborted at any time, either through the S3 API, or by a parallel invocation of your Worker. Therefore it is important to add the necessary error handling code around each operation on a `R2MultipartUpload` object in case the underlying multipart upload no longer exists. - ::: +- `key` + - The `key` for the multipart upload. -* `key` +- `uploadId` - * The `key` for the multipart upload. + - The `uploadId` for the multipart upload. -* `uploadId` +- `uploadPart` - * The `uploadId` for the multipart upload. + - Uploads a single part with the specified part number to this multipart upload. Each part must be uniform in size with an exception for the final part which can be smaller. + - Returns an `R2UploadedPart` object containing the `etag` and `partNumber`. These `R2UploadedPart` objects are required when completing the multipart upload. -* `uploadPart` +- `abort` - * Uploads a single part with the specified part number to this multipart upload. Each part must be uniform in size with an exception for the final part which can be smaller. - * Returns an `R2UploadedPart` object containing the `etag` and `partNumber`. These `R2UploadedPart` objects are required when completing the multipart upload. - -* `abort` - - * Aborts the multipart upload. Returns a Promise that resolves when the upload has been successfully aborted. - -* `complete` - - * Completes the multipart upload with the given parts. - * Returns a Promise that resolves when the complete operation has finished. Once this happens, the object is immediately accessible globally by any subsequent read operation. + - Aborts the multipart upload. Returns a Promise that resolves when the upload has been successfully aborted. +- `complete` + - Completes the multipart upload with the given parts. + - Returns a Promise that resolves when the complete operation has finished. Once this happens, the object is immediately accessible globally by any subsequent read operation. ## Method-specific types ### R2GetOptions +- `onlyIf` + - Specifies that the object should only be returned given satisfaction of certain conditions in the `R2Conditional` or in the conditional Headers. Refer to [Conditional operations](#conditional-operations). -* `onlyIf` +- `range` - * Specifies that the object should only be returned given satisfaction of certain conditions in the `R2Conditional` or in the conditional Headers. Refer to [Conditional operations](#conditional-operations). -* `range` - - * Specifies that only a specific length (from an optional offset) or suffix of bytes from the object should be returned. Refer to [Ranged reads](#ranged-reads). + - Specifies that only a specific length (from an optional offset) or suffix of bytes from the object should be returned. Refer to [Ranged reads](#ranged-reads). +- `ssecKey` + - Specifies a key to be used for [SSE-C](/r2/examples/ssec). Key must be 32 bytes in length, in the form of a hex-encoded string or an ArrayBuffer. #### Ranged reads @@ -265,127 +252,123 @@ A multipart upload can be completed or aborted at any time, either through the S There are 3 variations of arguments that can be used in a range: -* An offset with an optional length. -* An optional offset with a length. -* A suffix. - - +- An offset with an optional length. +- An optional offset with a length. +- A suffix. -* `offset` +- `offset` - * The byte to begin returning data from, inclusive. + - The byte to begin returning data from, inclusive. -* `length` +- `length` - * The number of bytes to return. If more bytes are requested than exist in the object, fewer bytes than this number may be returned. - -* `suffix` - - * The number of bytes to return from the end of the file, starting from the last byte. If more bytes are requested than exist in the object, fewer bytes than this number may be returned. + - The number of bytes to return. If more bytes are requested than exist in the object, fewer bytes than this number may be returned. +- `suffix` + - The number of bytes to return from the end of the file, starting from the last byte. If more bytes are requested than exist in the object, fewer bytes than this number may be returned. ### R2PutOptions +- `onlyIf` + - Specifies that the object should only be stored given satisfaction of certain conditions in the `R2Conditional`. Refer to [Conditional operations](#conditional-operations). -* `onlyIf` - - * Specifies that the object should only be stored given satisfaction of certain conditions in the `R2Conditional`. Refer to [Conditional operations](#conditional-operations). +- `httpMetadata` -* `httpMetadata` + - Various HTTP headers associated with the object. Refer to [HTTP Metadata](#http-metadata). - * Various HTTP headers associated with the object. Refer to [HTTP Metadata](#http-metadata). +- `customMetadata` -* `customMetadata` - - * A map of custom, user-defined metadata that will be stored with the object. + - A map of custom, user-defined metadata that will be stored with the object. :::note - Only a single hashing algorithm can be specified at once. - ::: -* `md5` +- `md5` - * A md5 hash to use to check the received object's integrity. + - A md5 hash to use to check the received object's integrity. -* `sha1` +- `sha1` - * A SHA-1 hash to use to check the received object's integrity. + - A SHA-1 hash to use to check the received object's integrity. -* `sha256` +- `sha256` - * A SHA-256 hash to use to check the received object's integrity. + - A SHA-256 hash to use to check the received object's integrity. -* `sha384` +- `sha384` - * A SHA-384 hash to use to check the received object's integrity. + - A SHA-384 hash to use to check the received object's integrity. -* `sha512` +- `sha512` - * A SHA-512 hash to use to check the received object's integrity. + - A SHA-512 hash to use to check the received object's integrity. -* `storageClass` +- `storageClass` - * Sets the storage class of the object if provided. Otherwise, the object will be stored in the default storage class associated with the bucket. Refer to [Storage Classes](#storage-class). + - Sets the storage class of the object if provided. Otherwise, the object will be stored in the default storage class associated with the bucket. Refer to [Storage Classes](#storage-class). +- `ssecKey` + - Specifies a key to be used for [SSE-C](/r2/examples/ssec). Key must be 32 bytes in length, in the form of a hex-encoded string or an ArrayBuffer. ### R2MultipartOptions +- `httpMetadata` + - Various HTTP headers associated with the object. Refer to [HTTP Metadata](#http-metadata). -* `httpMetadata` +- `customMetadata` - * Various HTTP headers associated with the object. Refer to [HTTP Metadata](#http-metadata). + - A map of custom, user-defined metadata that will be stored with the object. -* `customMetadata` +- `storageClass` - * A map of custom, user-defined metadata that will be stored with the object. + - Sets the storage class of the object if provided. Otherwise, the object will be stored in the default storage class associated with the bucket. Refer to [Storage Classes](#storage-class). -* `storageClass` +- `ssecKey` - * Sets the storage class of the object if provided. Otherwise, the object will be stored in the default storage class associated with the bucket. Refer to [Storage Classes](#storage-class). + - Specifies a key to be used for [SSE-C](/r2/examples/ssec). Key must be 32 bytes in length, in the form of a hex-encoded string or an ArrayBuffer. +### R2ListOptions +- `limit` -### R2ListOptions + - The number of results to return. Defaults to `1000`, with a maximum of `1000`. + - If `include` is set, you may receive fewer than `limit` results in your response to accommodate metadata. +- `prefix` -* `limit` - * The number of results to return. Defaults to `1000`, with a maximum of `1000`. + - The prefix to match keys against. Keys will only be returned if they start with given prefix. - * If `include` is set, you may receive fewer than `limit` results in your response to accommodate metadata. +- `cursor` -* `prefix` - * The prefix to match keys against. Keys will only be returned if they start with given prefix. + - An opaque token that indicates where to continue listing objects from. A cursor can be retrieved from a previous list operation. -* `cursor` - * An opaque token that indicates where to continue listing objects from. A cursor can be retrieved from a previous list operation. +- `delimiter` -* `delimiter` - * The character to use when grouping keys. + - The character to use when grouping keys. -* `include` +- `include` - * Can include `httpMetadata` and/or `customMetadata`. If included, items returned by the list will include the specified metadata. + - Can include `httpMetadata` and/or `customMetadata`. If included, items returned by the list will include the specified metadata. - * Note that there is a limit on the total amount of data that a single `list` operation can return. If you request data, you may receive fewer than `limit` results in your response to accommodate metadata. + - Note that there is a limit on the total amount of data that a single `list` operation can return. If you request data, you may receive fewer than `limit` results in your response to accommodate metadata. - * The [compatibility date](/workers/configuration/compatibility-dates/) must be set to `2022-08-04` or later in your `wrangler.toml` file. If not, then the `r2_list_honor_include` compatibility flag must be set. Otherwise it is treated as `include: ['httpMetadata', 'customMetadata']` regardless of what the `include` option provided actually is. + - The [compatibility date](/workers/configuration/compatibility-dates/) must be set to `2022-08-04` or later in your `wrangler.toml` file. If not, then the `r2_list_honor_include` compatibility flag must be set. Otherwise it is treated as `include: ['httpMetadata', 'customMetadata']` regardless of what the `include` option provided actually is. This means applications must be careful to avoid comparing the amount of returned objects against your `limit`. Instead, use the `truncated` property to determine if the `list` request has more data to be returned. ```js const options = { - limit: 500, - include: ['customMetadata'], -} + limit: 500, + include: ["customMetadata"], +}; const listed = await env.MY_BUCKET.list(options); @@ -395,76 +378,66 @@ let cursor = truncated ? listed.cursor : undefined; // ❌ - if your limit can't fit into a single response or your // bucket has less objects than the limit, it will get stuck here. while (listed.objects.length < options.limit) { - // ... + // ... } // ✅ - use the truncated property to check if there are more // objects to be returned while (truncated) { - const next = await env.MY_BUCKET.list({ - ...options, - cursor: cursor, - }); - listed.objects.push(...next.objects); - - truncated = next.truncated; - cursor = next.cursor + const next = await env.MY_BUCKET.list({ + ...options, + cursor: cursor, + }); + listed.objects.push(...next.objects); + + truncated = next.truncated; + cursor = next.cursor; } ``` - - ### R2Objects An object containing an `R2Object` array, returned by `BUCKET_BINDING.list()`. +- `objects` + - An array of objects matching the `list` request. -* `objects` - - * An array of objects matching the `list` request. +- `truncated` boolean -* `truncated` boolean + - If true, indicates there are more results to be retrieved for the current `list` request. - * If true, indicates there are more results to be retrieved for the current `list` request. +- `cursor` -* `cursor` + - A token that can be passed to future `list` calls to resume listing from that point. Only present if truncated is true. - * A token that can be passed to future `list` calls to resume listing from that point. Only present if truncated is true. - -* `delimitedPrefixes` - - * If a delimiter has been specified, contains all prefixes between the specified prefix and the next occurrence of the delimiter. - - * For example, if no prefix is provided and the delimiter is '/', `foo/bar/baz` would return `foo` as a delimited prefix. If `foo/` was passed as a prefix with the same structure and delimiter, `foo/bar` would be returned as a delimited prefix. +- `delimitedPrefixes` + - If a delimiter has been specified, contains all prefixes between the specified prefix and the next occurrence of the delimiter. + - For example, if no prefix is provided and the delimiter is '/', `foo/bar/baz` would return `foo` as a delimited prefix. If `foo/` was passed as a prefix with the same structure and delimiter, `foo/bar` would be returned as a delimited prefix. ### Conditional operations -You can pass an `R2Conditional` object to `R2GetOptions` and `R2PutOptions`. If the condition check for `get()` fails, the body will not be returned. This will make `get()` have lower latency. +You can pass an `R2Conditional` object to `R2GetOptions` and `R2PutOptions`. If the condition check for `get()` fails, the body will not be returned. This will make `get()` have lower latency. If the condition check for `put()` fails, `null` will be returned instead of the `R2Object`. +- `etagMatches` + - Performs the operation if the object's etag matches the given string. -* `etagMatches` - - * Performs the operation if the object's etag matches the given string. - -* `etagDoesNotMatch` - - * Performs the operation if the object's etag does not match the given string. +- `etagDoesNotMatch` -* `uploadedBefore` + - Performs the operation if the object's etag does not match the given string. - * Performs the operation if the object was uploaded before the given date. +- `uploadedBefore` -* `uploadedAfter` - - * Performs the operation if the object was uploaded after the given date. + - Performs the operation if the object was uploaded before the given date. +- `uploadedAfter` + - Performs the operation if the object was uploaded after the given date. Alternatively, you can pass a `Headers` object containing conditional headers to `R2GetOptions` and `R2PutOptions`. For information on these conditional headers, refer to [the MDN docs on conditional requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests#conditional_headers). All conditional headers aside from `If-Range` are supported. @@ -472,67 +445,55 @@ For more specific information about conditional requests, refer to [RFC 7232](ht ### HTTP Metadata -Generally, these fields match the HTTP metadata passed when the object was created. They can be overridden when issuing `GET` requests, in which case, the given values will be echoed back in the response. - - - -* `contentType` +Generally, these fields match the HTTP metadata passed when the object was created. They can be overridden when issuing `GET` requests, in which case, the given values will be echoed back in the response. -* `contentLanguage` +- `contentType` -* `contentDisposition` +- `contentLanguage` -* `contentEncoding` +- `contentDisposition` -* `cacheControl` - -* `cacheExpiry` +- `contentEncoding` +- `cacheControl` +- `cacheExpiry` ### Checksums If a checksum was provided when using the `put()` binding, it will be available on the returned object under the `checksums` property. The MD5 checksum will be included by default for non-multipart objects. +- `md5` + - The MD5 checksum of the object. -* `md5` - - * The MD5 checksum of the object. - -* `sha1` +- `sha1` - * The SHA-1 checksum of the object. + - The SHA-1 checksum of the object. -* `sha256` +- `sha256` - * The SHA-256 checksum of the object. + - The SHA-256 checksum of the object. -* `sha384` +- `sha384` - * The SHA-384 checksum of the object. - -* `sha512` - - * The SHA-512 checksum of the object. + - The SHA-384 checksum of the object. +- `sha512` + - The SHA-512 checksum of the object. ### `R2UploadedPart` An `R2UploadedPart` object represents a part that has been uploaded. `R2UploadedPart` objects are returned from `uploadPart` operations and must be passed to `completeMultipartUpload` operations. +- `partNumber` + - The number of the part. -* `partNumber` - - * The number of the part. - -* `etag` - - * The `etag` of the part. - +- `etag` + - The `etag` of the part. ### Storage Class diff --git a/src/content/docs/r2/examples/ssec.mdx b/src/content/docs/r2/examples/ssec.mdx new file mode 100644 index 000000000000000..60a07508920e148 --- /dev/null +++ b/src/content/docs/r2/examples/ssec.mdx @@ -0,0 +1,286 @@ +--- +title: Use SSE-C +pcx_content_type: tutorial +difficulty: Intermediate +content_type: 📝 Tutorial +updated: 2024-09-27 +--- + +import { Tabs, TabItem } from "~/components"; + +The following tutorial shows some snippets for how to use Server-Side Encryption with Customer-Provided Keys (SSE-C) on R2. + +## Before you begin + +- When using SSE-C, make sure you store your encryption key(s) in a safe place. In the event you misplace them, Cloudflare will be unable to recover the body of any objects encrypted using those keys. +- While SSE-C does provide MD5 hashes, this hash can be used for identification of keys only. The MD5 hash is not used in the encryption process itself. + +## Workers + + + + ```typescript + interface Environment { + R2: R2Bucket + /** + * In this example, your SSE-C is stored as a hexadecimal string (preferably a secret). + * The R2 API also supports providing an ArrayBuffer directly, if you want to generate/ + * store your keys dynamically. + */ + SSEC_KEY: string + } + export default { + async fetch(req: Request, env: Env) { + const { SSEC_KEY, R2 } = env; + const { pathname: filename } = new URL(req.url); + switch(req.method) { + case "GET": { + const maybeObj = await env.BUCKET.get(filename, { + onlyIf: req.headers, + ssecKey: SSEC_KEY, + }); + if(!maybeObj) { + return new Response("Not Found", { + status: 404 + }); + } + const headers = new Headers(); + maybeObj.writeHttpMetadata(headers); + return new Response(body, { + headers + }); + } + case 'POST': { + const multipartUpload = await env.BUCKET.createMultipartUpload(filename, { + httpMetadata: req.headers, + ssecKey: SSEC_KEY, + }); + /** + * This example only provides a single-part "multipart" upload. + * For multiple parts, the process is the same(the key must be provided) + * for every part. + */ + const partOne = await multipartUpload.uploadPart(1, req.body, ssecKey); + const obj = await multipartUpload.complete([partOne]); + const headers = new Headers(); + obj.writeHttpMetadata(headers); + return new Response(null, { + headers, + status: 201 + }); + } + case 'PUT': { + const obj = await env.BUCKET.put(filename, req.body, { + httpMetadata: req.headers, + ssecKey: SSEC_KEY, + }); + const headers = new Headers(); + maybeObj.writeHttpMetadata(headers); + return new Response(null, { + headers, + status: 201 + }); + } + default: { + return new Response("Method not allowed", { + status: 405 + }); + } + } + } + } + ``` + + + ```javascript + /** + * In this example, your SSE-C is stored as a hexadecimal string(preferably a secret). + * The R2 API also supports providing an ArrayBuffer directly, if you want to generate/ + * store your keys dynamically. + */ + export default { + async fetch(req, env) { + const { SSEC_KEY, R2 } = env; + const { pathname: filename } = new URL(req.url); + switch(req.method) { + case "GET": { + const maybeObj = await env.BUCKET.get(filename, { + onlyIf: req.headers, + ssecKey: SSEC_KEY, + }); + if(!maybeObj) { + return new Response("Not Found", { + status: 404 + }); + } + const headers = new Headers(); + maybeObj.writeHttpMetadata(headers); + return new Response(body, { + headers + }); + } + case 'POST': { + const multipartUpload = await env.BUCKET.createMultipartUpload(filename, { + httpMetadata: req.headers, + ssecKey: SSEC_KEY, + }); + /** + * This example only provides a single-part "multipart" upload. + * For multiple parts, the process is the same(the key must be provided) + * for every part. + */ + const partOne = await multipartUpload.uploadPart(1, req.body, ssecKey); + const obj = await multipartUpload.complete([partOne]); + const headers = new Headers(); + obj.writeHttpMetadata(headers); + return new Response(null, { + headers, + status: 201 + }); + } + case 'PUT': { + const obj = await env.BUCKET.put(filename, req.body, { + httpMetadata: req.headers, + ssecKey: SSEC_KEY, + }); + const headers = new Headers(); + maybeObj.writeHttpMetadata(headers); + return new Response(null, { + headers, + status: 201 + }); + } + default: { + return new Response("Method not allowed", { + status: 405 + }); + } + } + } + } + ``` + + + +## S3-API + + + + ```typescript + import { + UploadPartCommand, + PutObjectCommand, S3Client, + CompleteMultipartUploadCommand, + CreateMultipartUploadCommand, + type UploadPartCommandOutput + } from "@aws-sdk/client-s3"; + + const s3 = new S3Client({ + endpoint: process.env.R2_ENDPOINT, + credentials: { + accessKeyId: process.env.R2_ACCESS_KEY_ID, + secretAccessKey: process.env.R2_SECRET_ACCESS_KEY, + }, + }); + + const SSECustomerAlgorithm = "AES256"; + const SSECustomerKey = process.env.R2_SSEC_KEY; + const SSECustomerKeyMD5 = process.env.R2_SSEC_KEY_MD5; + + await s3.send( + new PutObjectCommand({ + Bucket: "your-bucket", + Key: "single-part", + Body: "BeepBoop", + SSECustomerAlgorithm, + SSECustomerKey, + SSECustomerKeyMD5, + }), + ); + + const multi = await s3.send( + new CreateMultipartUploadCommand({ + Bucket: "your-bucket", + Key: "multi-part", + SSECustomerAlgorithm, + SSECustomerKey, + SSECustomerKeyMD5, + }), + ); + const UploadId = multi.UploadId; + + const parts: UploadPartCommandOutput[] = []; + + parts.push( + await s3.send( + new UploadPartCommand({ + Bucket: "your-bucket", + Key: "multi-part", + UploadId, + // filledBuf()` generates some random data. + // Replace with a function/body of your choice. + Body: filledBuf(), + PartNumber: 1, + SSECustomerAlgorithm, + SSECustomerKey, + SSECustomerKeyMD5, + }), + ), + ); + parts.push( + await s3.send( + new UploadPartCommand({ + Bucket: "your-bucket", + Key: "multi-part", + UploadId, + // filledBuf()` generates some random data. + // Replace with a function/body of your choice. + Body: filledBuf(), + PartNumber: 2, + SSECustomerAlgorithm, + SSECustomerKey, + SSECustomerKeyMD5, + }), + ), + ); + await s3.send( + new CompleteMultipartUploadCommand({ + Bucket: "your-bucket", + Key: "multi-part", + UploadId, + MultipartUpload: { + Parts: parts.map(({ ETag }, PartNumber) => ({ + ETag, + PartNumber: PartNumber + 1, + })), + }, + SSECustomerAlgorithm, + SSECustomerKey, + SSECustomerKeyMD5, + }), + ); + + const HeadObjectOutput = await s3.send( + new HeadObjectCommand({ + Bucket: "your-bucket", + Key: "multi-part", + SSECustomerAlgorithm, + SSECustomerKey, + SSECustomerKeyMD5, + }), + ); + + const GetObjectOutput = await s3.send( + new GetObjectCommand({ + Bucket: "your-bucket", + Key: "single-part", + SSECustomerAlgorithm, + SSECustomerKey, + SSECustomerKeyMD5, + }), + ); + ``` + + + +