feat: add object versioning support

Implements object versioning capabilities (v0.15.0) including:
- Bucket APIs: PutBucketVersioning, GetBucketVersioning
- Object Listing: ListVersions (lists versions and delete markers)
- Object Operations: Updated FileDownload, FileDelete, and FileDetails to support VersionId
- Integration tests covering the full versioning workflow (enable, upload versions, list, download specific version, delete specific version)

Documentation updated in README.md and ROADMAP.md.

"I have implemented Object Versioning (v0.15.0) as per the roadmap."
This commit is contained in:
Rohan Verma
2025-11-27 16:48:58 +05:30
parent 11cad3573f
commit 9219b63613
6 changed files with 677 additions and 9 deletions
+68
View File
@@ -16,6 +16,7 @@ using AWS Signature Version 4.
- **Simple List API** with pagination, prefix filtering, and delimiter grouping
- **Iterator-based ListAll** for memory-efficient large bucket iteration (Go 1.23+)
- **Presigned URL generation** for secure browser uploads/downloads (including multipart)
- **Object Versioning** - Enable versioning, list versions, and access specific object versions
- **IAM credential support** for EC2 instances
- **Comprehensive test coverage**
- **Zero dependencies** - uses only Go standard library
@@ -417,6 +418,73 @@ Note: Tag support during upload varies by operation:
- **FileUpload** (POST): ⚠️ AWS S3 supported, MinIO limited (does not support tags in POST policy)
- **CopyObject**: ✅ Full support (handles MinIO/R2 signature quirks automatically)
### Object Versioning
Enable and manage object versions to protect against accidental deletion or overwrite.
#### Enable Versioning
```go
err := s3.PutBucketVersioning(simples3.PutBucketVersioningInput{
Bucket: "my-bucket",
Status: "Enabled", // or "Suspended"
})
if err != nil {
log.Fatal(err)
}
// Check status
config, err := s3.GetBucketVersioning("my-bucket")
fmt.Printf("Versioning status: %s\n", config.Status)
```
#### List Object Versions
List all versions of objects in a bucket:
```go
result, err := s3.ListVersions(simples3.ListVersionsInput{
Bucket: "my-bucket",
Prefix: "important-file.txt",
})
if err != nil {
log.Fatal(err)
}
for _, version := range result.Versions {
fmt.Printf("Key: %s, VersionId: %s, IsLatest: %v\n",
version.Key, version.VersionId, version.IsLatest)
}
```
#### Download Specific Version
Retrieve a specific version of an object:
```go
file, err := s3.FileDownload(simples3.DownloadInput{
Bucket: "my-bucket",
ObjectKey: "my-file.txt",
VersionId: "v1-version-id",
})
if err != nil {
log.Fatal(err)
}
// Use file (io.ReadCloser) normally
```
#### Delete Specific Version
Delete a specific version of an object:
```go
err := s3.FileDelete(simples3.DeleteInput{
Bucket: "my-bucket",
ObjectKey: "my-file.txt",
VersionId: "v1-version-id",
})
```
### Multipart Upload
For large files (>100MB), use multipart upload for better performance, resumability, and parallel uploads.