diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..639900d1
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..c82fd70f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/scoutgw.iml b/.idea/scoutgw.iml
new file mode 100644
index 00000000..d6ebd480
--- /dev/null
+++ b/.idea/scoutgw.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..35eb1ddf
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/backend.go b/backend/backend.go
index fab1ee9f..6f53667d 100644
--- a/backend/backend.go
+++ b/backend/backend.go
@@ -15,23 +15,34 @@ type Backend interface {
Shutdown()
ListBuckets() (*s3response.ListAllMyBucketsList, s3err.ErrorCode)
+ HeadBucket(bucket string) (*s3response.HeadBucketResponse, s3err.ErrorCode)
+ GetBucketAcl(bucket string) (*s3response.GetBucketAclResponse, s3err.ErrorCode)
PutBucket(bucket string) s3err.ErrorCode
DeleteBucket(bucket string) s3err.ErrorCode
CreateMultipartUpload(*s3.CreateMultipartUploadInput) (*s3response.InitiateMultipartUploadResponse, s3err.ErrorCode)
CompleteMultipartUpload(bucket, object, uploadID string, parts []s3response.Part) (*s3response.CompleteMultipartUploadResponse, s3err.ErrorCode)
AbortMultipartUpload(*s3.AbortMultipartUploadInput) s3err.ErrorCode
- ListMultipartUploads(*s3.ListMultipartUploadsInput) (*s3response.ListMultipartUploadsResponse, s3err.ErrorCode)
+ ListMultipartUploads(*s3response.ListMultipartUploads) (*s3response.ListMultipartUploadsResponse, s3err.ErrorCode)
ListObjectParts(bucket, object, uploadID string, partNumberMarker int, maxParts int) (*s3response.ListPartsResponse, s3err.ErrorCode)
CopyPart(srcBucket, srcObject, DstBucket, uploadID, rangeHeader string, part int) (*s3response.CopyObjectPartResponse, s3err.ErrorCode)
PutObjectPart(bucket, object, uploadID string, part int, r io.Reader) (etag string, err s3err.ErrorCode)
PutObject(bucket, object string, r io.Reader) (string, s3err.ErrorCode)
+ HeadObject(bucket, object string, etag string) (*s3response.HeadObjectResponse, s3err.ErrorCode)
GetObject(bucket, object string, startOffset, length int64, writer io.Writer, etag string) (*s3response.GetObjectResponse, s3err.ErrorCode)
+ GetObjectAcl(bucket, object string) (*s3response.GetObjectAccessControlPolicyResponse, s3err.ErrorCode)
+ GetObjectAttributes(bucket, object string, attributes []string) (*s3response.GetObjectAttributesResponse, s3err.ErrorCode)
CopyObject(srcBucket, srcObject, DstBucket, dstObject string) (*s3response.CopyObjectResponse, s3err.ErrorCode)
ListObjects(bucket, prefix, marker, delim string, maxkeys int) (*s3response.ListBucketResult, s3err.ErrorCode)
ListObjectsV2(bucket, prefix, marker, delim string, maxkeys int) (*s3response.ListBucketResultV2, s3err.ErrorCode)
DeleteObject(bucket, object string) s3err.ErrorCode
+ DeleteObjects(bucket string, objects *s3response.DeleteObjectsInput) s3err.ErrorCode
+ PutBucketAcl(*s3.PutBucketAclInput) s3err.ErrorCode
+ PutObjectAcl(*s3.PutObjectAclInput) s3err.ErrorCode
+ RestoreObject(bucket, object string, restoreRequest *s3.RestoreRequest) s3err.ErrorCode
+ UploadPart(bucket, object, uploadId string, Body io.ReadSeeker) (*s3.UploadPartOutput, s3err.ErrorCode)
+ UploadPartCopy(*s3.UploadPartCopyInput) (*s3.UploadPartCopyOutput, s3err.ErrorCode)
IsTaggingSupported() bool
GetTags(bucket, object string) (map[string]string, error)
@@ -41,7 +52,9 @@ type Backend interface {
type BackendUnsupported struct{}
-var _ Backend = BackendUnsupported{}
+func New() Backend {
+ return &BackendUnsupported{}
+}
func (BackendUnsupported) GetIAMConfig() ([]byte, error) {
return nil, fmt.Errorf("not supported")
@@ -55,6 +68,27 @@ func (BackendUnsupported) String() string {
func (BackendUnsupported) ListBuckets() (*s3response.ListAllMyBucketsList, s3err.ErrorCode) {
return nil, s3err.ErrNotImplemented
}
+func (BackendUnsupported) PutBucketAcl(*s3.PutBucketAclInput) s3err.ErrorCode {
+ return s3err.ErrNotImplemented
+}
+func (BackendUnsupported) PutObjectAcl(*s3.PutObjectAclInput) s3err.ErrorCode {
+ return s3err.ErrNotImplemented
+}
+func (BackendUnsupported) RestoreObject(bucket, object string, restoreRequest *s3.RestoreRequest) s3err.ErrorCode {
+ return s3err.ErrNotImplemented
+}
+func (BackendUnsupported) UploadPartCopy(*s3.UploadPartCopyInput) (*s3.UploadPartCopyOutput, s3err.ErrorCode) {
+ return nil, s3err.ErrNotImplemented
+}
+func (BackendUnsupported) UploadPart(bucket, object, uploadId string, Body io.ReadSeeker) (*s3.UploadPartOutput, s3err.ErrorCode) {
+ return nil, s3err.ErrNotImplemented
+}
+func (BackendUnsupported) GetBucketAcl(bucket string) (*s3response.GetBucketAclResponse, s3err.ErrorCode) {
+ return nil, s3err.ErrNotImplemented
+}
+func (BackendUnsupported) HeadBucket(bucket string) (*s3response.HeadBucketResponse, s3err.ErrorCode) {
+ return nil, s3err.ErrNotImplemented
+}
func (BackendUnsupported) PutBucket(bucket string) s3err.ErrorCode {
return s3err.ErrNotImplemented
}
@@ -71,7 +105,7 @@ func (BackendUnsupported) CompleteMultipartUpload(bucket, object, uploadID strin
func (BackendUnsupported) AbortMultipartUpload(*s3.AbortMultipartUploadInput) s3err.ErrorCode {
return s3err.ErrNotImplemented
}
-func (BackendUnsupported) ListMultipartUploads(*s3.ListMultipartUploadsInput) (*s3response.ListMultipartUploadsResponse, s3err.ErrorCode) {
+func (BackendUnsupported) ListMultipartUploads(*s3response.ListMultipartUploads) (*s3response.ListMultipartUploadsResponse, s3err.ErrorCode) {
return nil, s3err.ErrNotImplemented
}
func (BackendUnsupported) ListObjectParts(bucket, object, uploadID string, partNumberMarker int, maxParts int) (*s3response.ListPartsResponse, s3err.ErrorCode) {
@@ -90,9 +124,21 @@ func (BackendUnsupported) PutObject(buket, object string, r io.Reader) (string,
func (BackendUnsupported) DeleteObject(bucket, object string) s3err.ErrorCode {
return s3err.ErrNotImplemented
}
+func (BackendUnsupported) DeleteObjects(bucket string, objects *s3response.DeleteObjectsInput) s3err.ErrorCode {
+ return s3err.ErrNotImplemented
+}
func (BackendUnsupported) GetObject(bucket, object string, startOffset, length int64, writer io.Writer, etag string) (*s3response.GetObjectResponse, s3err.ErrorCode) {
return nil, s3err.ErrNotImplemented
}
+func (BackendUnsupported) HeadObject(bucket, object string, etag string) (*s3response.HeadObjectResponse, s3err.ErrorCode) {
+ return nil, s3err.ErrNotImplemented
+}
+func (BackendUnsupported) GetObjectAcl(bucket, object string) (*s3response.GetObjectAccessControlPolicyResponse, s3err.ErrorCode) {
+ return nil, s3err.ErrNotImplemented
+}
+func (BackendUnsupported) GetObjectAttributes(bucket, object string, attributes []string) (*s3response.GetObjectAttributesResponse, s3err.ErrorCode) {
+ return nil, s3err.ErrNotImplemented
+}
func (BackendUnsupported) CopyObject(srcBucket, srcObject, DstBucket, dstObject string) (*s3response.CopyObjectResponse, s3err.ErrorCode) {
return nil, s3err.ErrNotImplemented
}
diff --git a/cmd/scoutgw/main.go b/cmd/scoutgw/main.go
index 79058077..5b42a5db 100644
--- a/cmd/scoutgw/main.go
+++ b/cmd/scoutgw/main.go
@@ -1,5 +1,18 @@
package main
-func main() {
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/versity/scoutgw/backend"
+ "github.com/versity/scoutgw/s3api"
+ "log"
+)
+func main() {
+ app := fiber.New(fiber.Config{})
+ back := backend.New()
+ if api, err := s3api.New(app, back, ":7070"); err != nil {
+ log.Fatalln(err)
+ } else if err = api.Serve(); err != nil {
+ log.Fatalln(err)
+ }
}
diff --git a/go.mod b/go.mod
index 45b0905f..ebd7ec7d 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,26 @@ module github.com/versity/scoutgw
go 1.20
-require github.com/aws/aws-sdk-go v1.44.258
+require (
+ github.com/aws/aws-sdk-go v1.44.258
+ github.com/gofiber/fiber/v2 v2.45.0
+)
-require github.com/jmespath/go-jmespath v0.4.0 // indirect
+require (
+ github.com/andybalholm/brotli v1.0.5 // indirect
+ github.com/google/uuid v1.3.0 // indirect
+ github.com/jmespath/go-jmespath v0.4.0 // indirect
+ github.com/klauspost/compress v1.16.3 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.18 // indirect
+ github.com/mattn/go-runewidth v0.0.14 // indirect
+ github.com/philhofer/fwd v1.1.2 // indirect
+ github.com/rivo/uniseg v0.2.0 // indirect
+ github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect
+ github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
+ github.com/tinylib/msgp v1.1.8 // indirect
+ github.com/valyala/bytebufferpool v1.0.0 // indirect
+ github.com/valyala/fasthttp v1.47.0 // indirect
+ github.com/valyala/tcplisten v1.0.0 // indirect
+ golang.org/x/sys v0.8.0 // indirect
+)
diff --git a/go.sum b/go.sum
index 913bfbc8..b22b39f3 100644
--- a/go.sum
+++ b/go.sum
@@ -1,44 +1,101 @@
+github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
+github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/aws/aws-sdk-go v1.44.258 h1:JVk1lgpsTnb1kvUw3eGhPLcTpEBp6HeSf1fxcYDs2Ho=
github.com/aws/aws-sdk-go v1.44.258/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gofiber/fiber/v2 v2.45.0 h1:p4RpkJT9GAW6parBSbcNFH2ApnAuW3OzaQzbOCoDu+s=
+github.com/gofiber/fiber/v2 v2.45.0/go.mod h1:DNl0/c37WLe0g92U6lx1VMQuxGUQY5V7EIaVoEsUffc=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
+github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
+github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
+github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
+github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
+github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4=
+github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8=
+github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4=
+github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk=
+github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw=
+github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
+github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c=
+github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
+github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
+github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/internal/type.go b/internal/type.go
new file mode 100644
index 00000000..18f5f025
--- /dev/null
+++ b/internal/type.go
@@ -0,0 +1,3 @@
+package internal
+
+type Any any
diff --git a/s3api/controllers/base.go b/s3api/controllers/base.go
new file mode 100644
index 00000000..db9f8a82
--- /dev/null
+++ b/s3api/controllers/base.go
@@ -0,0 +1,325 @@
+package controllers
+
+import (
+ "bytes"
+ "encoding/xml"
+ "errors"
+ "io"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/aws/aws-sdk-go/service/s3"
+ "github.com/gofiber/fiber/v2"
+ "github.com/versity/scoutgw/backend"
+ "github.com/versity/scoutgw/internal"
+ "github.com/versity/scoutgw/s3err"
+ "github.com/versity/scoutgw/s3response"
+)
+
+type S3ApiController struct {
+ be backend.Backend
+}
+
+func New(be backend.Backend) S3ApiController {
+ return S3ApiController{be: be}
+}
+
+func (c S3ApiController) ListBuckets(ctx *fiber.Ctx) error {
+ res, code := c.be.ListBuckets()
+ return responce[*s3response.ListAllMyBucketsList](ctx, res, code)
+}
+
+func (c S3ApiController) GetActions(ctx *fiber.Ctx) error {
+ bucket, key, keyEnd, uploadId, maxPartsStr, partNumberMarkerStr := ctx.Params("bucket"), ctx.Params("key"), ctx.Params("*1"), ctx.Query("uploadId"), ctx.Query("max-parts"), ctx.Query("part-number-marker")
+ if keyEnd != "" {
+ key = strings.Join([]string{key, keyEnd}, "/")
+ }
+
+ if uploadId != "" {
+ maxParts, err := strconv.Atoi(maxPartsStr)
+ if err != nil && maxPartsStr != "" {
+ return errors.New("wrong api call")
+ }
+
+ partNumberMarker, err := strconv.Atoi(partNumberMarkerStr)
+ if err != nil && partNumberMarkerStr != "" {
+ return errors.New("wrong api call")
+ }
+
+ res, code := c.be.ListObjectParts(bucket, "", uploadId, partNumberMarker, maxParts)
+ return responce[*s3response.ListPartsResponse](ctx, res, code)
+ }
+
+ if ctx.Request().URI().QueryArgs().Has("acl") {
+ res, code := c.be.GetObjectAcl(bucket, key)
+ return responce[*s3response.GetObjectAccessControlPolicyResponse](ctx, res, code)
+ }
+
+ if attrs := ctx.Get("X-Amz-Object-Attributes"); attrs != "" {
+ res, code := c.be.GetObjectAttributes(bucket, key, strings.Split(attrs, ","))
+ return responce[*s3response.GetObjectAttributesResponse](ctx, res, code)
+ }
+
+ bRangeSl := strings.Split(ctx.Get("Range"), "=")
+ if len(bRangeSl) < 2 {
+ return errors.New("wrong api call")
+ }
+
+ bRange := strings.Split(bRangeSl[1], "-")
+ if len(bRange) < 2 {
+ return errors.New("wrong api call")
+ }
+
+ startOffset, err := strconv.Atoi(bRange[0])
+ if err != nil {
+ return errors.New("wrong api call")
+ }
+
+ length, err := strconv.Atoi(bRange[1])
+ if err != nil {
+ return errors.New("wrong api call")
+ }
+
+ res, code := c.be.GetObject(bucket, key, int64(startOffset), int64(length), ctx.Response().BodyWriter(), "")
+ return responce[*s3response.GetObjectResponse](ctx, res, code)
+}
+
+func (c S3ApiController) ListActions(ctx *fiber.Ctx) error {
+ if ctx.Request().URI().QueryArgs().Has("acl") {
+ res, code := c.be.GetBucketAcl(ctx.Params("bucket"))
+ return responce[*s3response.GetBucketAclResponse](ctx, res, code)
+ }
+
+ if ctx.Request().URI().QueryArgs().Has("uploads") {
+ res, code := c.be.ListMultipartUploads(&s3response.ListMultipartUploads{Bucket: ctx.Params("bucket")})
+ return responce[*s3response.ListMultipartUploadsResponse](ctx, res, code)
+ }
+
+ if ctx.QueryInt("list-type") == 2 {
+ res, code := c.be.ListObjectsV2(ctx.Params("bucket"), "", "", "", 1)
+ return responce[*s3response.ListBucketResultV2](ctx, res, code)
+ }
+
+ res, code := c.be.ListObjects(ctx.Params("bucket"), "", "", "", 1)
+ return responce[*s3response.ListBucketResult](ctx, res, code)
+}
+
+func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error {
+ bucket, acl, grantFullControl, grantRead, grantReadACP, granWrite, grantWriteACP :=
+ ctx.Params("bucket"),
+ ctx.Get("X-Amz-Acl"),
+ ctx.Get("X-Amz-Grant-Full-Control"),
+ ctx.Get("X-Amz-Grant-Read"),
+ ctx.Get("X-Amz-Grant-Read-Acp"),
+ ctx.Get("X-Amz-Grant-Write"),
+ ctx.Get("X-Amz-Grant-Write-Acp")
+
+ grants := grantFullControl + grantRead + grantReadACP + granWrite + grantWriteACP
+
+ if grants != "" || acl != "" {
+ if grants != "" && acl != "" {
+ return errors.New("wrong api call")
+ }
+ code := c.be.PutBucketAcl(&s3.PutBucketAclInput{
+ Bucket: &bucket,
+ ACL: &acl,
+ GrantFullControl: &grantFullControl,
+ GrantRead: &grantRead,
+ GrantReadACP: &grantReadACP,
+ GrantWrite: &granWrite,
+ GrantWriteACP: &grantWriteACP,
+ })
+
+ return responce[internal.Any](ctx, nil, code)
+ }
+
+ code := c.be.PutBucket(bucket)
+ return responce[internal.Any](ctx, nil, code)
+}
+
+func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
+ dstBucket, dstKeyStart, dstKeyEnd, uploadId, partNumberStr := ctx.Params("bucket"), ctx.Params("key"), ctx.Params("*1"), ctx.Query("uploadId"), ctx.Query("partNumber")
+ copySource, copySrcIfMatch, copySrcIfNoneMatch,
+ copySrcModifSince, copySrcUnmodifSince, acl,
+ grantFullControl, grantRead, grantReadACP,
+ granWrite, grantWriteACP :=
+ // Copy source headers
+ ctx.Get("X-Amz-Copy-Source"),
+ ctx.Get("X-Amz-Copy-Source-If-Match"),
+ ctx.Get("X-Amz-Copy-Source-If-None-Match"),
+ ctx.Get("X-Amz-Copy-Source-If-Modified-Since"),
+ ctx.Get("X-Amz-Copy-Source-If-Unmodified-Since"),
+ // Permission headers
+ ctx.Get("X-Amz-Acl"),
+ ctx.Get("X-Amz-Grant-Full-Control"),
+ ctx.Get("X-Amz-Grant-Read"),
+ ctx.Get("X-Amz-Grant-Read-Acp"),
+ ctx.Get("X-Amz-Grant-Write"),
+ ctx.Get("X-Amz-Grant-Write-Acp")
+
+ grants := grantFullControl + grantRead + grantReadACP + granWrite + grantWriteACP
+
+ if dstKeyEnd != "" {
+ dstKeyStart = strings.Join([]string{dstKeyStart, dstKeyEnd}, "/")
+ }
+
+ if partNumberStr != "" {
+ copySrcModifSinceDate, err := time.Parse(time.RFC3339, copySrcModifSince)
+ if err != nil && copySrcModifSince != "" {
+ return errors.New("wrong api call")
+ }
+
+ copySrcUnmodifSinceDate, err := time.Parse(time.RFC3339, copySrcUnmodifSince)
+ if err != nil && copySrcUnmodifSince != "" {
+ return errors.New("wrong api call")
+ }
+
+ partNumber, err := strconv.ParseInt(partNumberStr, 10, 64)
+ if err != nil {
+ return errors.New("wrong api call")
+ }
+
+ res, code := c.be.UploadPartCopy(&s3.UploadPartCopyInput{
+ Bucket: &dstBucket,
+ Key: &dstKeyStart,
+ PartNumber: &partNumber,
+ UploadId: &uploadId,
+ CopySource: ©Source,
+ CopySourceIfMatch: ©SrcIfMatch,
+ CopySourceIfNoneMatch: ©SrcIfNoneMatch,
+ CopySourceIfModifiedSince: ©SrcModifSinceDate,
+ CopySourceIfUnmodifiedSince: ©SrcUnmodifSinceDate,
+ })
+
+ return responce[*s3.UploadPartCopyOutput](ctx, res, code)
+ }
+
+ if uploadId != "" {
+ body := io.ReadSeeker(bytes.NewReader([]byte(ctx.Body())))
+ res, code := c.be.UploadPart(dstBucket, dstKeyStart, uploadId, body)
+ return responce[*s3.UploadPartOutput](ctx, res, code)
+ }
+
+ if grants != "" || acl != "" {
+ if grants != "" && acl != "" {
+ return errors.New("wrong api call")
+ }
+
+ code := c.be.PutObjectAcl(&s3.PutObjectAclInput{
+ Bucket: &dstBucket,
+ Key: &dstKeyStart,
+ ACL: &acl,
+ GrantFullControl: &grantFullControl,
+ GrantRead: &grantRead,
+ GrantReadACP: &grantReadACP,
+ GrantWrite: &granWrite,
+ GrantWriteACP: &grantWriteACP,
+ })
+ return responce[internal.Any](ctx, nil, code)
+ }
+
+ if copySource != "" {
+ copySourceSplit := strings.Split(copySource, "/")
+ srcBucket, srcObject := copySourceSplit[0], copySourceSplit[1:]
+
+ res, code := c.be.CopyObject(srcBucket, strings.Join(srcObject, "/"), dstBucket, dstKeyStart)
+ return responce[*s3response.CopyObjectResponse](ctx, res, code)
+ }
+
+ res, code := c.be.PutObject(dstBucket, dstKeyStart, bytes.NewReader(ctx.Request().Body()))
+ return responce[string](ctx, res, code)
+}
+
+func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) error {
+ code := c.be.DeleteBucket(ctx.Params("bucket"))
+ return responce[internal.Any](ctx, nil, code)
+}
+
+func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) error {
+ var dObj s3response.DeleteObjectEntry
+ if err := xml.Unmarshal(ctx.Body(), &dObj); err != nil {
+ return errors.New("wrong api call")
+ }
+
+ code := c.be.DeleteObjects(ctx.Params("bucket"), &s3response.DeleteObjectsInput{Delete: dObj})
+ return responce[internal.Any](ctx, nil, code)
+}
+
+func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error {
+ bucket, key, keyEnd, uploadId := ctx.Params("bucket"), ctx.Params("key"), ctx.Params("*1"), ctx.Query("uploadId")
+
+ if keyEnd != "" {
+ key = strings.Join([]string{key, keyEnd}, "/")
+ }
+
+ if uploadId != "" {
+ expectedBucketOwner, requestPayer := ctx.Get("X-Amz-Expected-Bucket-Owner"), ctx.Get("X-Amz-Request-Payer")
+
+ code := c.be.AbortMultipartUpload(&s3.AbortMultipartUploadInput{
+ UploadId: &uploadId,
+ Bucket: &bucket,
+ Key: &key,
+ ExpectedBucketOwner: &expectedBucketOwner,
+ RequestPayer: &requestPayer,
+ })
+ return responce[internal.Any](ctx, nil, code)
+ }
+
+ code := c.be.DeleteObject(bucket, key)
+ return responce[internal.Any](ctx, nil, code)
+}
+
+func (c S3ApiController) HeadBucket(ctx *fiber.Ctx) error {
+ res, code := c.be.HeadBucket(ctx.Params("bucket"))
+ return responce[*s3response.HeadBucketResponse](ctx, res, code)
+}
+
+func (c S3ApiController) HeadObject(ctx *fiber.Ctx) error {
+ bucket, key, keyEnd := ctx.Params("bucket"), ctx.Params("key"), ctx.Params("*1")
+ if keyEnd != "" {
+ key = strings.Join([]string{key, keyEnd}, "/")
+ }
+
+ res, code := c.be.HeadObject(bucket, key, "")
+ return responce[*s3response.HeadObjectResponse](ctx, res, code)
+}
+
+func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error {
+ bucket, key, keyEnd, uploadId := ctx.Params("bucket"), ctx.Params("key"), ctx.Params("*1"), ctx.Query("uploadId")
+ var restoreRequest s3.RestoreRequest
+
+ if keyEnd != "" {
+ key = strings.Join([]string{key, keyEnd}, "/")
+ }
+
+ if err := xml.Unmarshal(ctx.Body(), &restoreRequest); err == nil {
+ code := c.be.RestoreObject(bucket, key, &restoreRequest)
+ return responce[internal.Any](ctx, nil, code)
+ }
+
+ if uploadId != "" {
+ var parts []s3response.Part
+
+ if err := xml.Unmarshal(ctx.Body(), &parts); err != nil {
+ return errors.New("wrong api call")
+ }
+
+ res, code := c.be.CompleteMultipartUpload(bucket, "", uploadId, parts)
+ return responce[*s3response.CompleteMultipartUploadResponse](ctx, res, code)
+ }
+ res, code := c.be.CreateMultipartUpload(&s3.CreateMultipartUploadInput{Bucket: &bucket, Key: &key})
+ return responce[*s3response.InitiateMultipartUploadResponse](ctx, res, code)
+}
+
+func responce[R comparable](ctx *fiber.Ctx, resp R, code s3err.ErrorCode) error {
+ if code != 0 {
+ err := s3err.GetAPIError(code)
+ ctx.Status(err.HTTPStatusCode)
+ return ctx.Send(s3err.GetAPIErrorResponse(err, "", "", ""))
+ } else if b, err := xml.Marshal(resp); err != nil {
+ return err
+ } else {
+ return ctx.Send(b)
+ }
+}
diff --git a/s3api/router.go b/s3api/router.go
new file mode 100644
index 00000000..a9ac81a0
--- /dev/null
+++ b/s3api/router.go
@@ -0,0 +1,51 @@
+package s3api
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/versity/scoutgw/backend"
+ "github.com/versity/scoutgw/s3api/controllers"
+)
+
+type S3ApiRouter struct{}
+
+func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend) {
+ s3ApiController := controllers.New(be)
+ // ListBuckets action
+ app.Get("/", s3ApiController.ListBuckets)
+
+ // PutBucket action
+ // PutBucketAcl action
+ app.Put("/:bucket", s3ApiController.PutBucketActions)
+
+ // DeleteBucket action
+ app.Delete("/:bucket", s3ApiController.DeleteBucket)
+
+ // HeadBucket
+ app.Head("/:bucket", s3ApiController.HeadBucket)
+ // GetBucketAcl action
+ // ListMultipartUploads action
+ // ListObjects action
+ // ListObjectsV2 action
+ app.Get("/:bucket", s3ApiController.ListActions)
+
+ // HeadObject action
+ app.Head("/:bucket/:key/*", s3ApiController.HeadObject)
+ // GetObjectAcl action
+ // GetObject action
+ // ListObjectParts action
+ app.Get("/:bucket/:key/*", s3ApiController.GetActions)
+ // DeleteObject action
+ // AbortMultipartUpload action
+ app.Delete("/:bucket/:key/*", s3ApiController.DeleteActions)
+ // DeleteObjects action
+ app.Post("/:bucket", s3ApiController.DeleteObjects)
+ // CompleteMultipartUpload action
+ // CreateMultipartUpload
+ // RestoreObject action
+ app.Post("/:bucket/:key/*", s3ApiController.CreateActions)
+ // CopyObject action
+ // PutObject action
+ // UploadPart action
+ // UploadPartCopy action
+ app.Put("/:bucket/:key/*", s3ApiController.PutActions)
+}
diff --git a/s3api/server.go b/s3api/server.go
index 2d2d29b3..afe69fbe 100644
--- a/s3api/server.go
+++ b/s3api/server.go
@@ -1,19 +1,40 @@
package s3api
import (
+ "encoding/xml"
+ "fmt"
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/logger"
"github.com/versity/scoutgw/backend"
+ "github.com/versity/scoutgw/s3response"
)
type S3ApiServer struct {
- be backend.Backend
- port int
+ app *fiber.App
+ backend backend.Backend
+ router *S3ApiRouter
+ port string
}
-func New(be backend.Backend, port int) (s3ApiServer *S3ApiServer, err error) {
- s3ApiServer = &S3ApiServer{
- be: be,
- port: port,
- }
+func New(app *fiber.App, be backend.Backend, port string) (s3ApiServer *S3ApiServer, err error) {
+ s3ApiServer = &S3ApiServer{app, be, new(S3ApiRouter), port}
- return s3ApiServer, nil
+ app.Use(logger.New())
+
+ s3ApiServer.router.Init(app, be)
+ app.All("/*", func(ctx *fiber.Ctx) error {
+
+ fmt.Println(ctx.Method())
+ listBucket := new(s3response.ListBucket)
+ if b, err := xml.Marshal(listBucket); err != nil {
+ return err
+ } else {
+ return ctx.Send(b)
+ }
+ })
+ return
+}
+
+func (sa *S3ApiServer) Serve() (err error) {
+ return sa.app.Listen(sa.port)
}
diff --git a/s3err/s3err.go b/s3err/s3err.go
index aaf6d4de..ca16eb06 100644
--- a/s3err/s3err.go
+++ b/s3err/s3err.go
@@ -1,6 +1,10 @@
package s3err
-import "net/http"
+import (
+ "bytes"
+ "encoding/xml"
+ "net/http"
+)
// APIError structure
type APIError struct {
@@ -9,6 +13,27 @@ type APIError struct {
HTTPStatusCode int
}
+// APIErrorResponse - error response format
+type APIErrorResponse struct {
+ XMLName xml.Name `xml:"Error" json:"-"`
+ Code string
+ Message string
+ Key string `xml:"Key,omitempty" json:"Key,omitempty"`
+ BucketName string `xml:"BucketName,omitempty" json:"BucketName,omitempty"`
+ Resource string
+ Region string `xml:"Region,omitempty" json:"Region,omitempty"`
+ RequestID string `xml:"RequestId" json:"RequestId"`
+ HostID string `xml:"HostId" json:"HostId"`
+}
+
+func (A APIError) Error() []byte {
+ var bytesBuffer bytes.Buffer
+ bytesBuffer.WriteString(xml.Header)
+ e := xml.NewEncoder(&bytesBuffer)
+ _ = e.Encode(A)
+ return bytesBuffer.Bytes()
+}
+
// ErrorCode type of error status.
type ErrorCode int
@@ -345,3 +370,27 @@ var errorCodeResponse = map[ErrorCode]APIError{
func GetAPIError(code ErrorCode) APIError {
return errorCodeResponse[code]
}
+
+// getErrorResponse gets in standard error and resource value and
+// provides a encodable populated response values
+func GetAPIErrorResponse(err APIError, resource, requestID, hostID string) []byte {
+ return encodeResponse(APIErrorResponse{
+ Code: err.Code,
+ Message: err.Description,
+ BucketName: "",
+ Key: "",
+ Resource: resource,
+ Region: "",
+ RequestID: requestID,
+ HostID: hostID,
+ })
+}
+
+// Encodes the response headers into XML format.
+func encodeResponse(response interface{}) []byte {
+ var bytesBuffer bytes.Buffer
+ bytesBuffer.WriteString(xml.Header)
+ e := xml.NewEncoder(&bytesBuffer)
+ e.Encode(response)
+ return bytesBuffer.Bytes()
+}
diff --git a/s3response/AmazonS3-additions.xsd b/s3response/AmazonS3-additions.xsd
new file mode 100644
index 00000000..02cc84fa
--- /dev/null
+++ b/s3response/AmazonS3-additions.xsd
@@ -0,0 +1,989 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/s3response/README.txt b/s3response/README.txt
index 99fafb23..5a515b83 100644
--- a/s3response/README.txt
+++ b/s3response/README.txt
@@ -4,3 +4,4 @@ see https://blog.aqwari.net/xml-schema-go/
go install aqwari.net/xml/cmd/xsdgen@latest
xsdgen -o s3api_xsd_generated.go -pkg s3response AmazonS3.xsd
+xsdgen -o s3api_xsd_generated.go -pkg s3response AmazonS3-additions.xsd
diff --git a/s3response/s3api_xsd_generated.go b/s3response/s3api_xsd_generated.go
index 729786e8..63042991 100644
--- a/s3response/s3api_xsd_generated.go
+++ b/s3response/s3api_xsd_generated.go
@@ -22,6 +22,385 @@ type AmazonCustomerByEmail struct {
EmailAddress string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ EmailAddress"`
}
+type Anon1 struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"`
+ ContentLength int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentLength"`
+ AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,omitempty"`
+ StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass,omitempty"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *Anon1) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon1
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon1) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon1
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon10 struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix,omitempty"`
+ Marker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Marker,omitempty"`
+ MaxKeys int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxKeys,omitempty"`
+ Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter,omitempty"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *Anon10) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon10
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon10) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon10
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon11 struct {
+ ListBucketResponse ListBucketResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResponse"`
+}
+
+type Anon12 struct {
+ ListVersionsResponse ListVersionsResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListVersionsResponse"`
+}
+
+type Anon13 struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter"`
+ EncodingType string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ EncodingType"`
+ KeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ KeyMarker"`
+ MaxUploads string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxUploads"`
+ Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"`
+ UploadIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ UploadIdMarker"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *Anon13) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon13
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon13) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon13
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon14 struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ KeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ KeyMarker"`
+ UploadIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ UploadIdMarker"`
+ NextKeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextKeyMarker"`
+ Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"`
+ Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter"`
+ NextUploadIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextUploadIdMarker"`
+ MaxUploads int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxUploads"`
+ IsTruncated bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsTruncated"`
+ Upload UploadEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Upload"`
+ CommonPrefixes CommonPrefixes `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CommonPrefixes"`
+ EncodingType string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ EncodingType"`
+}
+
+type Anon15 struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ CacheControl string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CacheControl"`
+ ContentDisposition string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentDisposition"`
+ ContentEncoding string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentEncoding"`
+ ContentLanguage string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentLanguage"`
+ ContentType string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentType"`
+ Expires time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Expires"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *Anon15) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon15
+ var layout struct {
+ *T
+ Expires *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Expires"`
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Expires = (*xsdDateTime)(&layout.T.Expires)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon15) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon15
+ var overlay struct {
+ *T
+ Expires *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Expires"`
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Expires = (*xsdDateTime)(&overlay.T.Expires)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon16 struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ UploadId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ UploadId"`
+}
+
+type Anon17 struct {
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+}
+
+func (t *Anon17) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon17
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon17) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon17
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon18 struct {
+ ListAllMyBucketsResponse ListAllMyBucketsResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResponse"`
+}
+
+type Anon19 struct {
+ Location string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Location"`
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"`
+}
+
+type Anon2 struct {
+ PutObjectResponse PutObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PutObjectResponse"`
+}
+
+type Anon20 struct {
+ SourceBucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ SourceBucket"`
+ SourceKey string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ SourceKey"`
+ DestinationBucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DestinationBucket"`
+ DestinationKey string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DestinationKey"`
+ MetadataDirective MetadataDirective `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MetadataDirective,omitempty"`
+ Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"`
+ AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,omitempty"`
+ CopySourceIfModifiedSince time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfModifiedSince,omitempty"`
+ CopySourceIfUnmodifiedSince time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfUnmodifiedSince,omitempty"`
+ CopySourceIfMatch []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfMatch,omitempty"`
+ CopySourceIfNoneMatch []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfNoneMatch,omitempty"`
+ StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass,omitempty"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *Anon20) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon20
+ var layout struct {
+ *T
+ CopySourceIfModifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfModifiedSince,omitempty"`
+ CopySourceIfUnmodifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfUnmodifiedSince,omitempty"`
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.CopySourceIfModifiedSince = (*xsdDateTime)(&layout.T.CopySourceIfModifiedSince)
+ layout.CopySourceIfUnmodifiedSince = (*xsdDateTime)(&layout.T.CopySourceIfUnmodifiedSince)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon20) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon20
+ var overlay struct {
+ *T
+ CopySourceIfModifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfModifiedSince,omitempty"`
+ CopySourceIfUnmodifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfUnmodifiedSince,omitempty"`
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.CopySourceIfModifiedSince = (*xsdDateTime)(&overlay.T.CopySourceIfModifiedSince)
+ overlay.CopySourceIfUnmodifiedSince = (*xsdDateTime)(&overlay.T.CopySourceIfUnmodifiedSince)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon21 struct {
+ CopyObjectResult CopyObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopyObjectResult"`
+}
+
+type Anon3 struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"`
+ Data []byte `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data"`
+ ContentLength int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentLength"`
+ AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,omitempty"`
+ StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass,omitempty"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *Anon3) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon3
+ var layout struct {
+ *T
+ Data *xsdBase64Binary `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data"`
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Data = (*xsdBase64Binary)(&layout.T.Data)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon3) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon3
+ var overlay struct {
+ *T
+ Data *xsdBase64Binary `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data"`
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Data = (*xsdBase64Binary)(&overlay.T.Data)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon4 struct {
+ PutObjectInlineResponse PutObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PutObjectInlineResponse"`
+}
+
+type Anon5 struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *Anon5) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon5
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon5) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon5
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon6 struct {
+ DeleteObjectResponse Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteObjectResponse"`
+}
+
+type Anon7 struct {
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *Anon7) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T Anon7
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *Anon7) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T Anon7
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type Anon8 struct {
+ Delete DeleteObjectEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delete"`
+}
+
+type Anon9 struct {
+ Deleted DeletedEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Deleted"`
+ Error Error `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Error"`
+}
+
type BucketLoggingStatus struct {
LoggingEnabled LoggingSettings `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LoggingEnabled,omitempty"`
}
@@ -31,6 +410,17 @@ type CanonicalUser struct {
DisplayName string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DisplayName,omitempty"`
}
+type Checksum struct {
+ ChecksumCRC32 string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumCRC32"`
+ ChecksumCRC32C string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumCRC32C"`
+ ChecksumSHA1 string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumSHA1"`
+ ChecksumSHA256 string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumSHA256"`
+}
+
+type CommonPrefixes struct {
+ Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"`
+}
+
type CopyObject struct {
SourceBucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ SourceBucket"`
SourceKey string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ SourceKey"`
@@ -150,6 +540,52 @@ type CreateBucketResult struct {
BucketName string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ BucketName"`
}
+type CreateMultipartUpload struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ CacheControl string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CacheControl"`
+ ContentDisposition string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentDisposition"`
+ ContentEncoding string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentEncoding"`
+ ContentLanguage string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentLanguage"`
+ ContentType string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentType"`
+ Expires time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Expires"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *CreateMultipartUpload) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T CreateMultipartUpload
+ var layout struct {
+ *T
+ Expires *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Expires"`
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Expires = (*xsdDateTime)(&layout.T.Expires)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *CreateMultipartUpload) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T CreateMultipartUpload
+ var overlay struct {
+ *T
+ Expires *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Expires"`
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Expires = (*xsdDateTime)(&overlay.T.Expires)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type CreateMultipartUploadResponse struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ UploadId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ UploadId"`
+}
+
type DeleteBucket struct {
Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
@@ -242,10 +678,67 @@ func (t *DeleteObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) erro
return d.DecodeElement(&overlay, &start)
}
+type DeleteObjectEntry struct {
+ Object ObjectIdentifier `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Object"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ Quiet bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Quiet"`
+}
+
type DeleteObjectResponse struct {
DeleteObjectResponse Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteObjectResponse"`
}
+type DeleteObjects struct {
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *DeleteObjects) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T DeleteObjects
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *DeleteObjects) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T DeleteObjects
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type DeleteObjectsInput struct {
+ Delete DeleteObjectEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delete"`
+}
+
+type DeleteObjectsResponse struct {
+ Deleted DeletedEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Deleted"`
+ Error Error `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Error"`
+}
+
+type DeletedEntry struct {
+ DeleteMarker bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteMarker"`
+ DeleteMarkerVersionId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteMarkerVersionId"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ VersionId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersionId"`
+}
+
+type Error struct {
+ Code string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Code"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ Message string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Message"`
+ VersionId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersionId"`
+}
+
type GetBucketAccessControlPolicy struct {
Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
@@ -279,6 +772,65 @@ type GetBucketAccessControlPolicyResponse struct {
GetBucketAccessControlPolicyResponse AccessControlPolicy `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetBucketAccessControlPolicyResponse"`
}
+type GetBucketAcl struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *GetBucketAcl) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T GetBucketAcl
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *GetBucketAcl) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T GetBucketAcl
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type GetBucketAclResponse struct {
+ CanonicalUser CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CanonicalUser"`
+ AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *GetBucketAclResponse) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T GetBucketAclResponse
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *GetBucketAclResponse) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T GetBucketAclResponse
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
type GetBucketLoggingStatus struct {
Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
@@ -379,6 +931,82 @@ type GetObjectAccessControlPolicyResponse struct {
GetObjectAccessControlPolicyResponse AccessControlPolicy `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetObjectAccessControlPolicyResponse"`
}
+type GetObjectAcl struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *GetObjectAcl) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T GetObjectAcl
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *GetObjectAcl) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T GetObjectAcl
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type GetObjectAclResponse struct {
+ Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner"`
+ Grants AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Grants"`
+ RequestCharged string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ RequestCharged"`
+}
+
+type GetObjectAttributes struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ Attributes string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Attributes"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *GetObjectAttributes) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T GetObjectAttributes
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *GetObjectAttributes) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T GetObjectAttributes
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type GetObjectAttributesResponse struct {
+ Etag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Etag"`
+ Checksum Checksum `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Checksum"`
+ RequestCharged string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ RequestCharged"`
+ ObjectParts ObjectParts `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ObjectParts"`
+ StorageClass string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass"`
+ ObjectSize int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ObjectSize"`
+}
+
type GetObjectExtended struct {
Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
@@ -480,6 +1108,126 @@ type Group struct {
URI string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ URI"`
}
+type HeadBucket struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *HeadBucket) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T HeadBucket
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *HeadBucket) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T HeadBucket
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type HeadBucketResponse struct {
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *HeadBucketResponse) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T HeadBucketResponse
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *HeadBucketResponse) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T HeadBucketResponse
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type HeadObject struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *HeadObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T HeadObject
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *HeadObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T HeadObject
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type HeadObjectResponse struct {
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *HeadObjectResponse) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T HeadObjectResponse
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *HeadObjectResponse) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T HeadObjectResponse
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type InitiatorEntry struct {
+ DisplayName string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DisplayName"`
+ ID string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ID"`
+}
+
type ListAllMyBuckets struct {
AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
@@ -626,6 +1374,56 @@ func (t *ListEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
return d.DecodeElement(&overlay, &start)
}
+type ListMultipartUploads struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter"`
+ EncodingType string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ EncodingType"`
+ KeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ KeyMarker"`
+ MaxUploads string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxUploads"`
+ Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"`
+ UploadIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ UploadIdMarker"`
+ AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"`
+ Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"`
+ Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"`
+}
+
+func (t *ListMultipartUploads) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T ListMultipartUploads
+ var layout struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ layout.T = (*T)(t)
+ layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp)
+ return e.EncodeElement(layout, start)
+}
+func (t *ListMultipartUploads) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T ListMultipartUploads
+ var overlay struct {
+ *T
+ Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp)
+ return d.DecodeElement(&overlay, &start)
+}
+
+type ListMultipartUploadsResponse struct {
+ Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"`
+ KeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ KeyMarker"`
+ UploadIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ UploadIdMarker"`
+ NextKeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextKeyMarker"`
+ Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"`
+ Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter"`
+ NextUploadIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextUploadIdMarker"`
+ MaxUploads int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxUploads"`
+ IsTruncated bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsTruncated"`
+ Upload UploadEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Upload"`
+ CommonPrefixes CommonPrefixes `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CommonPrefixes"`
+ EncodingType string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ EncodingType"`
+}
+
type ListVersionsResponse struct {
ListVersionsResponse ListVersionsResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListVersionsResponse"`
}
@@ -667,6 +1465,29 @@ type NotificationConfiguration struct {
TopicConfiguration []TopicConfiguration `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TopicConfiguration,omitempty"`
}
+type ObjectIdentifier struct {
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ VersionId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersionId"`
+}
+
+type ObjectParts struct {
+ IsTruncated bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsTruncated"`
+ MaxParts int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxParts"`
+ NextPartNumberMarker int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextPartNumberMarker"`
+ PartNumberMarker int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PartNumberMarker"`
+ Part Part `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Part"`
+ PartsCount int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PartsCount"`
+}
+
+type Part struct {
+ ChecksumCRC32 string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumCRC32"`
+ ChecksumCRC32C string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumCRC32C"`
+ ChecksumSHA1 string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumSHA1"`
+ ChecksumSHA256 string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumSHA256"`
+ PartNumber int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PartNumber"`
+ Size int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Size"`
+}
+
// May be one of BucketOwner, Requester
type Payer string
@@ -912,6 +1733,37 @@ type TopicConfiguration struct {
Event []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Event"`
}
+type UploadEntry struct {
+ ChecksumAlgorithm string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ChecksumAlgorithm"`
+ Initiated time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Initiated"`
+ Initiator InitiatorEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Initiator"`
+ Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"`
+ Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner"`
+ StorageClass string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass"`
+ UploadId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ UploadId"`
+}
+
+func (t *UploadEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ type T UploadEntry
+ var layout struct {
+ *T
+ Initiated *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Initiated"`
+ }
+ layout.T = (*T)(t)
+ layout.Initiated = (*xsdDateTime)(&layout.T.Initiated)
+ return e.EncodeElement(layout, start)
+}
+func (t *UploadEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ type T UploadEntry
+ var overlay struct {
+ *T
+ Initiated *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Initiated"`
+ }
+ overlay.T = (*T)(t)
+ overlay.Initiated = (*xsdDateTime)(&overlay.T.Initiated)
+ return d.DecodeElement(&overlay, &start)
+}
+
type User struct {
}
diff --git a/s3response/s3response.go b/s3response/s3response.go
index 0b7337b4..00c7b8b4 100644
--- a/s3response/s3response.go
+++ b/s3response/s3response.go
@@ -25,14 +25,6 @@ type LocationResponse struct {
Location string `xml:",chardata"`
}
-// Part container for part metadata.
-type Part struct {
- PartNumber int
- LastModified string
- ETag string
- Size int64
-}
-
// ListPartsResponse - format for list parts response.
type ListPartsResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListPartsResult" json:"-"`
@@ -41,7 +33,7 @@ type ListPartsResponse struct {
Key string
UploadID string `xml:"UploadId"`
- Initiator Initiator
+ Initiator CanonicalUser
Owner Owner
// The class of storage used to store the object.
@@ -56,38 +48,6 @@ type ListPartsResponse struct {
Parts []Part `xml:"Part"`
}
-// ListMultipartUploadsResponse - format for list multipart uploads response.
-type ListMultipartUploadsResponse struct {
- XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListMultipartUploadsResult" json:"-"`
-
- Bucket string
- KeyMarker string
- UploadIDMarker string `xml:"UploadIdMarker"`
- NextKeyMarker string
- NextUploadIDMarker string `xml:"NextUploadIdMarker"`
- Delimiter string
- Prefix string
- EncodingType string `xml:"EncodingType,omitempty"`
- MaxUploads int
- IsTruncated bool
-
- // List of pending uploads.
- Uploads []Upload `xml:"Upload"`
-
- // Delimed common prefixes.
- CommonPrefixes []CommonPrefix
-}
-
-// Upload container for in progress multipart upload
-type Upload struct {
- Key string
- UploadID string `xml:"UploadId"`
- Initiator Initiator
- Owner Owner
- StorageClass string
- Initiated string
-}
-
// CommonPrefix container for prefix response in ListObjectsResponse
type CommonPrefix struct {
Prefix string
@@ -175,9 +135,6 @@ type CopyObjectPartResponse struct {
ETag string // md5sum of the copied object part.
}
-// Initiator inherit from Owner struct, fields are same
-type Initiator Owner
-
// Owner - bucket owner/principal
type Owner struct {
ID string
@@ -210,14 +167,3 @@ type DeleteError struct {
Key string
VersionID string `xml:"VersionId"`
}
-
-// DeleteObjectsResponse container for multiple object deletes.
-type DeleteObjectsResponse struct {
- XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteResult" json:"-"`
-
- // Collection of all deleted objects
- DeletedObjects []DeleteObject `xml:"Deleted,omitempty"`
-
- // Collection of errors deleting certain objects.
- Errors []DeleteError `xml:"Error,omitempty"`
-}