From 05953d63775ec2aa6d07dccf43a466dd676419d0 Mon Sep 17 00:00:00 2001 From: Ben McClelland Date: Sat, 10 Feb 2024 23:02:28 -0800 Subject: [PATCH] fix: correct xml response encoding for list-buckets --- s3api/controllers/base.go | 1123 +++++++++++++++++++++-------- s3api/utils/auth-reader.go | 23 +- s3api/utils/auth_test.go | 22 +- s3response/README.txt | 6 - s3response/s3api_xsd_generated.go | 1007 -------------------------- s3response/s3response.go | 59 +- 6 files changed, 913 insertions(+), 1327 deletions(-) delete mode 100644 s3response/README.txt delete mode 100644 s3response/s3api_xsd_generated.go diff --git a/s3api/controllers/base.go b/s3api/controllers/base.go index 2063ea1fe..0a4de65df 100644 --- a/s3api/controllers/base.go +++ b/s3api/controllers/base.go @@ -56,7 +56,11 @@ func New(be backend.Backend, iam auth.IAMService, logger s3log.AuditLogger, evs func (c S3ApiController) ListBuckets(ctx *fiber.Ctx) error { acct := ctx.Locals("account").(auth.Account) res, err := c.be.ListBuckets(ctx.Context(), acct.Access, acct.Role == "admin") - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "ListBucket"}) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListBucket", + }) } func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { @@ -75,36 +79,73 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { } if ctx.Request().URI().QueryArgs().Has("tagging") { - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetObjectTagging", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObjectTagging", + BucketOwner: parsedAcl.Owner, + }) } tags, err := c.be.GetObjectTagging(ctx.Context(), bucket, key) if err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetObjectTagging", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObjectTagging", + BucketOwner: parsedAcl.Owner, + }) + } + res := s3response.Tagging{ + TagSet: s3response.TagSet{Tags: []s3response.Tag{}}, } - resp := s3response.Tagging{TagSet: s3response.TagSet{Tags: []s3response.Tag{}}} for key, val := range tags { - resp.TagSet.Tags = append(resp.TagSet.Tags, s3response.Tag{Key: key, Value: val}) + res.TagSet.Tags = append(res.TagSet.Tags, + s3response.Tag{Key: key, Value: val}) } - return SendXMLResponse(ctx, resp, nil, &MetaOpts{Logger: c.logger, Action: "GetObjectTagging", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, res, nil, + &MetaOpts{ + Logger: c.logger, + Action: "GetObjectTagging", + BucketOwner: parsedAcl.Owner, + }) } if uploadId != "" { if maxParts < 0 && ctx.Request().URI().QueryArgs().Has("max-parts") { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidMaxParts), &MetaOpts{Logger: c.logger, Action: "ListParts", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidMaxParts), + &MetaOpts{ + Logger: c.logger, + Action: "ListParts", + BucketOwner: parsedAcl.Owner, + }) } if partNumberMarker != "" { n, err := strconv.Atoi(partNumberMarker) if err != nil || n < 0 { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidPartNumberMarker), &MetaOpts{Logger: c.logger, Action: "ListParts", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidPartNumberMarker), + &MetaOpts{ + Logger: c.logger, + Action: "ListParts", + BucketOwner: parsedAcl.Owner, + }) } } - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "ListParts", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListParts", + BucketOwner: parsedAcl.Owner, + }) } var mxParts *int32 if ctx.Request().URI().QueryArgs().Has("max-parts") { @@ -118,38 +159,72 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { PartNumberMarker: &partNumberMarker, MaxParts: mxParts, }) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "ListParts", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListParts", + BucketOwner: parsedAcl.Owner, + }) } if ctx.Request().URI().QueryArgs().Has("acl") { - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ_ACP", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetObjectAcl", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ_ACP", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObjectAcl", + BucketOwner: parsedAcl.Owner, + }) } res, err := c.be.GetObjectAcl(ctx.Context(), &s3.GetObjectAclInput{ Bucket: &bucket, Key: &key, }) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "GetObjectAcl", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObjectAcl", + BucketOwner: parsedAcl.Owner, + }) } if attrs := ctx.Get("X-Amz-Object-Attributes"); attrs != "" { - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetObjectAttributes", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObjectAttributes", + BucketOwner: parsedAcl.Owner, + }) } var oattrs []types.ObjectAttributes for _, a := range strings.Split(attrs, ",") { oattrs = append(oattrs, types.ObjectAttributes(a)) } - res, err := c.be.GetObjectAttributes(ctx.Context(), &s3.GetObjectAttributesInput{ - Bucket: &bucket, - Key: &key, - ObjectAttributes: oattrs, - }) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "GetObjectAttributes", BucketOwner: parsedAcl.Owner}) + res, err := c.be.GetObjectAttributes(ctx.Context(), + &s3.GetObjectAttributesInput{ + Bucket: &bucket, + Key: &key, + ObjectAttributes: oattrs, + }) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObjectAttributes", + BucketOwner: parsedAcl.Owner, + }) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ_ACP", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "GetObject", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ_ACP", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObject", + BucketOwner: parsedAcl.Owner, + }) } ctx.Locals("logResBody", false) @@ -159,10 +234,20 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { Range: &acceptRange, }, ctx.Response().BodyWriter()) if err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "GetObject", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObject", + BucketOwner: parsedAcl.Owner, + }) } if res == nil { - return SendResponse(ctx, fmt.Errorf("get object nil response"), &MetaOpts{Logger: c.logger, Action: "GetObject", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, fmt.Errorf("get object nil response"), + &MetaOpts{ + Logger: c.logger, + Action: "GetObject", + BucketOwner: parsedAcl.Owner, + }) } utils.SetMetaHeaders(ctx, res.Metadata) @@ -215,7 +300,12 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { }) } - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "GetObject", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetObject", + BucketOwner: parsedAcl.Owner, + }) } func getstring(s *string) string { @@ -248,40 +338,77 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { parsedAcl := ctx.Locals("parsedAcl").(auth.ACL) if ctx.Request().URI().QueryArgs().Has("tagging") { - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetBucketTagging", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetBucketTagging", + BucketOwner: parsedAcl.Owner, + }) } tags, err := c.be.GetBucketTagging(ctx.Context(), bucket) if err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetBucketTagging", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetBucketTagging", + BucketOwner: parsedAcl.Owner, + }) + } + resp := s3response.Tagging{ + TagSet: s3response.TagSet{Tags: []s3response.Tag{}}, } - resp := s3response.Tagging{TagSet: s3response.TagSet{Tags: []s3response.Tag{}}} for key, val := range tags { - resp.TagSet.Tags = append(resp.TagSet.Tags, s3response.Tag{Key: key, Value: val}) + resp.TagSet.Tags = append(resp.TagSet.Tags, + s3response.Tag{Key: key, Value: val}) } - return SendXMLResponse(ctx, resp, nil, &MetaOpts{Logger: c.logger, Action: "GetBucketTagging", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, resp, nil, + &MetaOpts{ + Logger: c.logger, + Action: "GetBucketTagging", + BucketOwner: parsedAcl.Owner, + }) } if ctx.Request().URI().QueryArgs().Has("acl") { - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ_ACP", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "GetBucketAcl", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ_ACP", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } - data, err := c.be.GetBucketAcl(ctx.Context(), &s3.GetBucketAclInput{Bucket: &bucket}) + data, err := c.be.GetBucketAcl(ctx.Context(), + &s3.GetBucketAclInput{Bucket: &bucket}) if err != nil { return SendResponse(ctx, err, &MetaOpts{Logger: c.logger}) } res, err := auth.ParseACLOutput(data) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "GetBucketAcl", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + Action: "GetBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } if ctx.Request().URI().QueryArgs().Has("uploads") { - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "ListMultipartUploads", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListMultipartUploads", + BucketOwner: parsedAcl.Owner, + }) } maxUploads, err := utils.ParseUint(maxUploadsStr) if err != nil { @@ -291,74 +418,108 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error { BucketOwner: parsedAcl.Owner, }) } - res, err := c.be.ListMultipartUploads(ctx.Context(), &s3.ListMultipartUploadsInput{ - Bucket: &bucket, - Delimiter: &delimiter, - Prefix: &prefix, - UploadIdMarker: &uploadIdMarker, - MaxUploads: &maxUploads, - KeyMarker: &keyMarker, - }) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "ListMultipartUploads", BucketOwner: parsedAcl.Owner}) + res, err := c.be.ListMultipartUploads(ctx.Context(), + &s3.ListMultipartUploadsInput{ + Bucket: &bucket, + Delimiter: &delimiter, + Prefix: &prefix, + UploadIdMarker: &uploadIdMarker, + MaxUploads: &maxUploads, + KeyMarker: &keyMarker, + }) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListMultipartUploads", + BucketOwner: parsedAcl.Owner, + }) } if ctx.QueryInt("list-type") == 2 { - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "ListObjectsV2", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListObjectsV2", + BucketOwner: parsedAcl.Owner, + }) } maxkeys, err := utils.ParseUint(maxkeysStr) if err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{ + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListObjectsV2", + BucketOwner: parsedAcl.Owner, + }) + } + res, err := c.be.ListObjectsV2(ctx.Context(), + &s3.ListObjectsV2Input{ + Bucket: &bucket, + Prefix: &prefix, + ContinuationToken: &cToken, + Delimiter: &delimiter, + MaxKeys: &maxkeys, + StartAfter: &sAfter, + }) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ Logger: c.logger, Action: "ListObjectsV2", BucketOwner: parsedAcl.Owner, }) - } - res, err := c.be.ListObjectsV2(ctx.Context(), &s3.ListObjectsV2Input{ - Bucket: &bucket, - Prefix: &prefix, - ContinuationToken: &cToken, - Delimiter: &delimiter, - MaxKeys: &maxkeys, - StartAfter: &sAfter, - }) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "ListObjectsV2", BucketOwner: parsedAcl.Owner}) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "ListObjects", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListObjects", + BucketOwner: parsedAcl.Owner, + }) } maxkeys, err := utils.ParseUint(maxkeysStr) if err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{ + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "ListObjects", + BucketOwner: parsedAcl.Owner, + }) + } + + res, err := c.be.ListObjects(ctx.Context(), + &s3.ListObjectsInput{ + Bucket: &bucket, + Prefix: &prefix, + Marker: &marker, + Delimiter: &delimiter, + MaxKeys: &maxkeys, + }) + return SendXMLResponse(ctx, struct { + *s3.ListObjectsOutput + XMLName struct{} `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResult"` + }{ListObjectsOutput: res}, err, + &MetaOpts{ Logger: c.logger, Action: "ListObjects", BucketOwner: parsedAcl.Owner, }) - } - - res, err := c.be.ListObjects(ctx.Context(), &s3.ListObjectsInput{ - Bucket: &bucket, - Prefix: &prefix, - Marker: &marker, - Delimiter: &delimiter, - MaxKeys: &maxkeys, - }) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "ListObjects", BucketOwner: parsedAcl.Owner}) } func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { - bucket, acl, grantFullControl, grantRead, grantReadACP, granWrite, grantWriteACP, acct, isRoot := - 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"), - ctx.Locals("account").(auth.Account), - ctx.Locals("isRoot").(bool) + bucket := ctx.Params("bucket") + acl := ctx.Get("X-Amz-Acl") + grantFullControl := ctx.Get("X-Amz-Grant-Full-Control") + grantRead := ctx.Get("X-Amz-Grant-Read") + grantReadACP := ctx.Get("X-Amz-Grant-Read-Acp") + granWrite := ctx.Get("X-Amz-Grant-Write") + grantWriteACP := ctx.Get("X-Amz-Grant-Write-Acp") + acct := ctx.Locals("account").(auth.Account) + isRoot := ctx.Locals("isRoot").(bool) if ctx.Request().URI().QueryArgs().Has("tagging") { parsedAcl := ctx.Locals("parsedAcl").(auth.ACL) @@ -366,24 +527,45 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { var bucketTagging s3response.Tagging err := xml.Unmarshal(ctx.Body(), &bucketTagging) if err != nil { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutBucketTagging", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketTagging", + BucketOwner: parsedAcl.Owner, + }) } tags := make(map[string]string, len(bucketTagging.TagSet.Tags)) for _, tag := range bucketTagging.TagSet.Tags { if len(tag.Key) > 128 || len(tag.Value) > 256 { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidTag), &MetaOpts{Logger: c.logger, Action: "PutBucketTagging", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidTag), + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketTagging", + BucketOwner: parsedAcl.Owner, + }) } tags[tag.Key] = tag.Value } - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "PutBucketTagging", BucketOwner: parsedAcl.Owner}) + err = auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketTagging", + BucketOwner: parsedAcl.Owner, + }) } err = c.be.PutBucketTagging(ctx.Context(), bucket, tags) - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "PutBucketTagging", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketTagging", + BucketOwner: parsedAcl.Owner, + }) } grants := grantFullControl + grantRead + grantReadACP + granWrite + grantWriteACP @@ -393,90 +575,161 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error { var accessControlPolicy auth.AccessControlPolicy parsedAcl := ctx.Locals("parsedAcl").(auth.ACL) - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE_ACP", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE_ACP", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } - err := xml.Unmarshal(ctx.Body(), &accessControlPolicy) + err = xml.Unmarshal(ctx.Body(), &accessControlPolicy) if err != nil { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } if len(accessControlPolicy.AccessControlList.Grants) > 0 { if grants+acl != "" { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } input = &s3.PutBucketAclInput{ - Bucket: &bucket, - ACL: "", - AccessControlPolicy: &types.AccessControlPolicy{Owner: &accessControlPolicy.Owner, Grants: accessControlPolicy.AccessControlList.Grants}, + Bucket: &bucket, + ACL: "", + AccessControlPolicy: &types.AccessControlPolicy{ + Owner: &accessControlPolicy.Owner, + Grants: accessControlPolicy.AccessControlList.Grants, + }, } } if acl != "" { if acl != "private" && acl != "public-read" && acl != "public-read-write" { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } if len(accessControlPolicy.AccessControlList.Grants) > 0 || grants != "" { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } input = &s3.PutBucketAclInput{ - Bucket: &bucket, - ACL: types.BucketCannedACL(acl), - AccessControlPolicy: &types.AccessControlPolicy{Owner: &accessControlPolicy.Owner}, + Bucket: &bucket, + ACL: types.BucketCannedACL(acl), + AccessControlPolicy: &types.AccessControlPolicy{ + Owner: &accessControlPolicy.Owner, + }, } } if grants != "" { input = &s3.PutBucketAclInput{ - Bucket: &bucket, - GrantFullControl: &grantFullControl, - GrantRead: &grantRead, - GrantReadACP: &grantReadACP, - GrantWrite: &granWrite, - GrantWriteACP: &grantWriteACP, - AccessControlPolicy: &types.AccessControlPolicy{Owner: &accessControlPolicy.Owner}, - ACL: "", + Bucket: &bucket, + GrantFullControl: &grantFullControl, + GrantRead: &grantRead, + GrantReadACP: &grantReadACP, + GrantWrite: &granWrite, + GrantWriteACP: &grantWriteACP, + AccessControlPolicy: &types.AccessControlPolicy{ + Owner: &accessControlPolicy.Owner, + }, + ACL: "", } } updAcl, err := auth.UpdateACL(input, parsedAcl, c.iam) if err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } err = c.be.PutBucketAcl(ctx.Context(), bucket, updAcl) - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketAcl", + BucketOwner: parsedAcl.Owner, + }) } if ok := utils.IsValidBucketName(bucket); !ok { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidBucketName), &MetaOpts{Logger: c.logger, Action: "CreateBucket"}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidBucketName), + &MetaOpts{ + Logger: c.logger, + Action: "CreateBucket", + }) } if acl != "" && grants != "" { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutBucketAcl", BucketOwner: acct.Access}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutBucketAcl", + BucketOwner: acct.Access, + }) } - defACL := auth.ACL{ACL: "private", Owner: acct.Access, Grantees: []auth.Grantee{}} + defACL := auth.ACL{ + ACL: "private", + Owner: acct.Access, + Grantees: []auth.Grantee{}, + } updAcl, err := auth.UpdateACL(&s3.PutBucketAclInput{ - GrantFullControl: &grantFullControl, - GrantRead: &grantRead, - GrantReadACP: &grantReadACP, - GrantWrite: &granWrite, - GrantWriteACP: &grantWriteACP, - AccessControlPolicy: &types.AccessControlPolicy{Owner: &types.Owner{ID: &acct.Access}}, - ACL: types.BucketCannedACL(acl), + GrantFullControl: &grantFullControl, + GrantRead: &grantRead, + GrantReadACP: &grantReadACP, + GrantWrite: &granWrite, + GrantWriteACP: &grantWriteACP, + AccessControlPolicy: &types.AccessControlPolicy{Owner: &types.Owner{ + ID: &acct.Access, + }}, + ACL: types.BucketCannedACL(acl), }, defACL, c.iam) if err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "CreateBucket", BucketOwner: acct.Access}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "CreateBucket", + BucketOwner: acct.Access, + }) } err = c.be.CreateBucket(ctx.Context(), &s3.CreateBucketInput{ Bucket: &bucket, ObjectOwnership: types.ObjectOwnership(acct.Access), }, updAcl) - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "CreateBucket", BucketOwner: acct.Access}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "CreateBucket", + BucketOwner: acct.Access, + }) } func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { @@ -523,20 +776,36 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { var objTagging s3response.Tagging err := xml.Unmarshal(ctx.Body(), &objTagging) if err != nil { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutObjectTagging", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectTagging", + BucketOwner: parsedAcl.Owner, + }) } tags := make(map[string]string, len(objTagging.TagSet.Tags)) for _, tag := range objTagging.TagSet.Tags { if len(tag.Key) > 128 || len(tag.Value) > 256 { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidTag), &MetaOpts{Logger: c.logger, Action: "PutObjectTagging", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidTag), + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectTagging", + BucketOwner: parsedAcl.Owner, + }) } tags[tag.Key] = tag.Value } - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "PutObjectTagging", BucketOwner: parsedAcl.Owner}) + err = auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectTagging", + BucketOwner: parsedAcl.Owner, + }) } err = c.be.PutObjectTagging(ctx.Context(), bucket, keyStart, tags) @@ -549,10 +818,18 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { }) } - if ctx.Request().URI().QueryArgs().Has("uploadId") && ctx.Request().URI().QueryArgs().Has("partNumber") && copySource != "" { + if ctx.Request().URI().QueryArgs().Has("uploadId") && + ctx.Request().URI().QueryArgs().Has("partNumber") && + copySource != "" { partNumber := int32(ctx.QueryInt("partNumber", -1)) if partNumber < 1 || partNumber > 10000 { - return SendXMLResponse(ctx, nil, s3err.GetAPIError(s3err.ErrInvalidPart), &MetaOpts{Logger: c.logger, Action: "UploadPartCopy", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, nil, + s3err.GetAPIError(s3err.ErrInvalidPart), + &MetaOpts{ + Logger: c.logger, + Action: "UploadPartCopy", + BucketOwner: parsedAcl.Owner, + }) } resp, err := c.be.UploadPartCopy(ctx.Context(), &s3.UploadPartCopyInput{ @@ -564,22 +841,44 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { ExpectedBucketOwner: &bucketOwner, CopySourceRange: ©SrcRange, }) - return SendXMLResponse(ctx, resp, err, &MetaOpts{Logger: c.logger, Action: "UploadPartCopy", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, resp, err, + &MetaOpts{ + Logger: c.logger, + Action: "UploadPartCopy", + BucketOwner: parsedAcl.Owner, + }) } - if ctx.Request().URI().QueryArgs().Has("uploadId") && ctx.Request().URI().QueryArgs().Has("partNumber") { + if ctx.Request().URI().QueryArgs().Has("uploadId") && + ctx.Request().URI().QueryArgs().Has("partNumber") { partNumber := int32(ctx.QueryInt("partNumber", -1)) if partNumber < 1 || partNumber > 10000 { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidPart), &MetaOpts{Logger: c.logger, Action: "UploadPart", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidPart), + &MetaOpts{ + Logger: c.logger, + Action: "UploadPart", + BucketOwner: parsedAcl.Owner, + }) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "UploadPart", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "UploadPart", + BucketOwner: parsedAcl.Owner, + }) } contentLength, err := strconv.ParseInt(contentLengthStr, 10, 64) if err != nil { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "UploadPart", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "UploadPart", + BucketOwner: parsedAcl.Owner, + }) } var body io.Reader @@ -591,16 +890,22 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { } ctx.Locals("logReqBody", false) - etag, err := c.be.UploadPart(ctx.Context(), &s3.UploadPartInput{ - Bucket: &bucket, - Key: &keyStart, - UploadId: &uploadId, - PartNumber: &partNumber, - ContentLength: &contentLength, - Body: body, - }) + etag, err := c.be.UploadPart(ctx.Context(), + &s3.UploadPartInput{ + Bucket: &bucket, + Key: &keyStart, + UploadId: &uploadId, + PartNumber: &partNumber, + ContentLength: &contentLength, + Body: body, + }) ctx.Response().Header.Set("Etag", etag) - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "UploadPart", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "UploadPart", + BucketOwner: parsedAcl.Owner, + }) } if ctx.Request().URI().QueryArgs().Has("acl") { @@ -608,48 +913,79 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { if len(ctx.Body()) > 0 { if grants+acl != "" { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutObjectAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectAcl", + BucketOwner: parsedAcl.Owner, + }) } var accessControlPolicy auth.AccessControlPolicy err := xml.Unmarshal(ctx.Body(), &accessControlPolicy) if err != nil { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutObjectAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectAcl", + BucketOwner: parsedAcl.Owner, + }) } input = &s3.PutObjectAclInput{ - Bucket: &bucket, - Key: &keyStart, - ACL: "", - AccessControlPolicy: &types.AccessControlPolicy{Owner: &accessControlPolicy.Owner, Grants: accessControlPolicy.AccessControlList.Grants}, + Bucket: &bucket, + Key: &keyStart, + ACL: "", + AccessControlPolicy: &types.AccessControlPolicy{ + Owner: &accessControlPolicy.Owner, + Grants: accessControlPolicy.AccessControlList.Grants, + }, } } if acl != "" { if acl != "private" && acl != "public-read" && acl != "public-read-write" { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutObjectAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectAcl", + BucketOwner: parsedAcl.Owner, + }) } if len(ctx.Body()) > 0 || grants != "" { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutObjectAcl", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, + s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutObjectAcl", + BucketOwner: parsedAcl.Owner, + }) } input = &s3.PutObjectAclInput{ - Bucket: &bucket, - Key: &keyStart, - ACL: types.ObjectCannedACL(acl), - AccessControlPolicy: &types.AccessControlPolicy{Owner: &types.Owner{ID: &bucketOwner}}, + Bucket: &bucket, + Key: &keyStart, + ACL: types.ObjectCannedACL(acl), + AccessControlPolicy: &types.AccessControlPolicy{ + Owner: &types.Owner{ID: &bucketOwner}, + }, } } if grants != "" { input = &s3.PutObjectAclInput{ - Bucket: &bucket, - Key: &keyStart, - GrantFullControl: &grantFullControl, - GrantRead: &grantRead, - GrantReadACP: &grantReadACP, - GrantWrite: &granWrite, - GrantWriteACP: &grantWriteACP, - AccessControlPolicy: &types.AccessControlPolicy{Owner: &types.Owner{ID: &bucketOwner}}, - ACL: "", + Bucket: &bucket, + Key: &keyStart, + GrantFullControl: &grantFullControl, + GrantRead: &grantRead, + GrantReadACP: &grantReadACP, + GrantWrite: &granWrite, + GrantWriteACP: &grantWriteACP, + AccessControlPolicy: &types.AccessControlPolicy{ + Owner: &types.Owner{ID: &bucketOwner}, + }, + ACL: "", } } @@ -664,8 +1000,14 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { } if copySource != "" { - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "CopyObject", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "CopyObject", + BucketOwner: parsedAcl.Owner, + }) } var mtime *time.Time @@ -673,14 +1015,26 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { if copySrcModifSince != "" { tm, err := time.Parse(iso8601Format, copySrcModifSince) if err != nil { - return SendXMLResponse(ctx, nil, s3err.GetAPIError(s3err.ErrInvalidCopySource), &MetaOpts{Logger: c.logger, Action: "CopyObject", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, nil, + s3err.GetAPIError(s3err.ErrInvalidCopySource), + &MetaOpts{ + Logger: c.logger, + Action: "CopyObject", + BucketOwner: parsedAcl.Owner, + }) } mtime = &tm } if copySrcUnmodifSince != "" { tm, err := time.Parse(iso8601Format, copySrcUnmodifSince) if err != nil { - return SendXMLResponse(ctx, nil, s3err.GetAPIError(s3err.ErrInvalidCopySource), &MetaOpts{Logger: c.logger, Action: "CopyObject", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, nil, + s3err.GetAPIError(s3err.ErrInvalidCopySource), + &MetaOpts{ + Logger: c.logger, + Action: "CopyObject", + BucketOwner: parsedAcl.Owner, + }) } umtime = &tm } @@ -719,13 +1073,24 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { metadata := utils.GetUserMetaData(&ctx.Request().Header) - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "PutObject", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "PutObject", + BucketOwner: parsedAcl.Owner, + }) } contentLength, err := strconv.ParseInt(contentLengthStr, 10, 64) if err != nil { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "PutObject", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "PutObject", + BucketOwner: parsedAcl.Owner, + }) } var body io.Reader @@ -758,46 +1123,94 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { } func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) error { - bucket, acct, isRoot, parsedAcl := ctx.Params("bucket"), ctx.Locals("account").(auth.Account), ctx.Locals("isRoot").(bool), ctx.Locals("parsedAcl").(auth.ACL) + bucket := ctx.Params("bucket") + acct := ctx.Locals("account").(auth.Account) + isRoot := ctx.Locals("isRoot").(bool) + parsedAcl := ctx.Locals("parsedAcl").(auth.ACL) if ctx.Request().URI().QueryArgs().Has("tagging") { - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "DeleteBucketTagging", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "DeleteBucketTagging", + BucketOwner: parsedAcl.Owner, + }) } - err := c.be.DeleteBucketTagging(ctx.Context(), bucket) - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "DeleteBucketTagging", BucketOwner: parsedAcl.Owner, Status: http.StatusNoContent}) + err = c.be.DeleteBucketTagging(ctx.Context(), bucket) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "DeleteBucketTagging", + BucketOwner: parsedAcl.Owner, + Status: http.StatusNoContent, + }) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "DeleteBucket", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "DeleteBucket", + BucketOwner: parsedAcl.Owner, + }) } - err := c.be.DeleteBucket(ctx.Context(), &s3.DeleteBucketInput{ + err = c.be.DeleteBucket(ctx.Context(), &s3.DeleteBucketInput{ Bucket: &bucket, }) - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "DeleteBucket", BucketOwner: parsedAcl.Owner, Status: http.StatusNoContent}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "DeleteBucket", + BucketOwner: parsedAcl.Owner, + Status: http.StatusNoContent, + }) } func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) error { - bucket, acct, isRoot, parsedAcl := ctx.Params("bucket"), ctx.Locals("account").(auth.Account), ctx.Locals("isRoot").(bool), ctx.Locals("parsedAcl").(auth.ACL) + bucket := ctx.Params("bucket") + acct := ctx.Locals("account").(auth.Account) + isRoot := ctx.Locals("isRoot").(bool) + parsedAcl := ctx.Locals("parsedAcl").(auth.ACL) var dObj s3response.DeleteObjects - if err := xml.Unmarshal(ctx.Body(), &dObj); err != nil { - return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{Logger: c.logger, Action: "DeleteObjects", BucketOwner: parsedAcl.Owner}) + err := xml.Unmarshal(ctx.Body(), &dObj) + if err != nil { + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), + &MetaOpts{ + Logger: c.logger, + Action: "DeleteObjects", + BucketOwner: parsedAcl.Owner, + }) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "DeleteObjects", BucketOwner: parsedAcl.Owner}) + err = auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "DeleteObjects", + BucketOwner: parsedAcl.Owner, + }) } - res, err := c.be.DeleteObjects(ctx.Context(), &s3.DeleteObjectsInput{ - Bucket: &bucket, - Delete: &types.Delete{ - Objects: dObj.Objects, - }, - }) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "DeleteObjects", BucketOwner: parsedAcl.Owner}) + res, err := c.be.DeleteObjects(ctx.Context(), + &s3.DeleteObjectsInput{ + Bucket: &bucket, + Delete: &types.Delete{ + Objects: dObj.Objects, + }, + }) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + Action: "DeleteObjects", + BucketOwner: parsedAcl.Owner, + }) } func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error { @@ -814,11 +1227,17 @@ func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error { } if ctx.Request().URI().QueryArgs().Has("tagging") { - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "RemoveObjectTagging", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "RemoveObjectTagging", + BucketOwner: parsedAcl.Owner, + }) } - err := c.be.DeleteObjectTagging(ctx.Context(), bucket, key) + err = c.be.DeleteObjectTagging(ctx.Context(), bucket, key) return SendResponse(ctx, err, &MetaOpts{ Status: http.StatusNoContent, Logger: c.logger, @@ -830,52 +1249,88 @@ func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error { } if uploadId != "" { - expectedBucketOwner, requestPayer := ctx.Get("X-Amz-Expected-Bucket-Owner"), ctx.Get("X-Amz-Request-Payer") + expectedBucketOwner := ctx.Get("X-Amz-Expected-Bucket-Owner") + requestPayer := ctx.Get("X-Amz-Request-Payer") - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "AbortMultipartUpload", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "AbortMultipartUpload", + BucketOwner: parsedAcl.Owner, + }) } - err := c.be.AbortMultipartUpload(ctx.Context(), &s3.AbortMultipartUploadInput{ - UploadId: &uploadId, - Bucket: &bucket, - Key: &key, - ExpectedBucketOwner: &expectedBucketOwner, - RequestPayer: types.RequestPayer(requestPayer), - }) - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "AbortMultipartUpload", BucketOwner: parsedAcl.Owner, Status: 204}) + err = c.be.AbortMultipartUpload(ctx.Context(), + &s3.AbortMultipartUploadInput{ + UploadId: &uploadId, + Bucket: &bucket, + Key: &key, + ExpectedBucketOwner: &expectedBucketOwner, + RequestPayer: types.RequestPayer(requestPayer), + }) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "AbortMultipartUpload", + BucketOwner: parsedAcl.Owner, + Status: http.StatusNoContent, + }) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "DeleteObject", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "DeleteObject", + BucketOwner: parsedAcl.Owner, + }) } - err := c.be.DeleteObject(ctx.Context(), &s3.DeleteObjectInput{ - Bucket: &bucket, - Key: &key, - }) - return SendResponse(ctx, err, &MetaOpts{ - Logger: c.logger, - EvSender: c.evSender, - Action: "DeleteObject", - BucketOwner: parsedAcl.Owner, - EventName: s3event.EventObjectDelete, - Status: 204, - }) + err = c.be.DeleteObject(ctx.Context(), + &s3.DeleteObjectInput{ + Bucket: &bucket, + Key: &key, + }) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + EvSender: c.evSender, + Action: "DeleteObject", + BucketOwner: parsedAcl.Owner, + EventName: s3event.EventObjectDelete, + Status: http.StatusNoContent, + }) } func (c S3ApiController) HeadBucket(ctx *fiber.Ctx) error { - bucket, acct, isRoot, parsedAcl := ctx.Params("bucket"), ctx.Locals("account").(auth.Account), ctx.Locals("isRoot").(bool), ctx.Locals("parsedAcl").(auth.ACL) + bucket := ctx.Params("bucket") + acct := ctx.Locals("account").(auth.Account) + isRoot := ctx.Locals("isRoot").(bool) + parsedAcl := ctx.Locals("parsedAcl").(auth.ACL) - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "HeadBucket", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "HeadBucket", + BucketOwner: parsedAcl.Owner, + }) } - _, err := c.be.HeadBucket(ctx.Context(), &s3.HeadBucketInput{ + _, err = c.be.HeadBucket(ctx.Context(), &s3.HeadBucketInput{ Bucket: &bucket, }) // TODO: set bucket response headers - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "HeadBucket", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "HeadBucket", + BucketOwner: parsedAcl.Owner, + }) } const ( @@ -883,26 +1338,46 @@ const ( ) func (c S3ApiController) HeadObject(ctx *fiber.Ctx) error { - bucket, acct, isRoot, parsedAcl := ctx.Params("bucket"), ctx.Locals("account").(auth.Account), ctx.Locals("isRoot").(bool), ctx.Locals("parsedAcl").(auth.ACL) + bucket := ctx.Params("bucket") + acct := ctx.Locals("account").(auth.Account) + isRoot := ctx.Locals("isRoot").(bool) + parsedAcl := ctx.Locals("parsedAcl").(auth.ACL) key := ctx.Params("key") keyEnd := ctx.Params("*1") if keyEnd != "" { key = strings.Join([]string{key, keyEnd}, "/") } - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "HeadObject", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "HeadObject", + BucketOwner: parsedAcl.Owner, + }) } - res, err := c.be.HeadObject(ctx.Context(), &s3.HeadObjectInput{ - Bucket: &bucket, - Key: &key, - }) + res, err := c.be.HeadObject(ctx.Context(), + &s3.HeadObjectInput{ + Bucket: &bucket, + Key: &key, + }) if err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "HeadObject", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "HeadObject", + BucketOwner: parsedAcl.Owner, + }) } if res == nil { - return SendResponse(ctx, fmt.Errorf("head object nil response"), &MetaOpts{Logger: c.logger, Action: "HeadObject", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, fmt.Errorf("head object nil response"), + &MetaOpts{ + Logger: c.logger, + Action: "HeadObject", + BucketOwner: parsedAcl.Owner, + }) } utils.SetMetaHeaders(ctx, res.Metadata) @@ -941,7 +1416,12 @@ func (c S3ApiController) HeadObject(ctx *fiber.Ctx) error { }, }) - return SendResponse(ctx, nil, &MetaOpts{Logger: c.logger, Action: "HeadObject", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, nil, + &MetaOpts{ + Logger: c.logger, + Action: "HeadObject", + BucketOwner: parsedAcl.Owner, + }) } func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error { @@ -966,51 +1446,73 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error { if ctx.Request().URI().QueryArgs().Has("restore") { err := xml.Unmarshal(ctx.Body(), &restoreRequest) if err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "RestoreObject", BucketOwner: parsedAcl.Owner}) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "RestoreObject", + BucketOwner: parsedAcl.Owner, + }) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendResponse(ctx, err, &MetaOpts{Logger: c.logger, Action: "RestoreObject", BucketOwner: parsedAcl.Owner}) + err = auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + Action: "RestoreObject", + BucketOwner: parsedAcl.Owner, + }) } restoreRequest.Bucket = &bucket restoreRequest.Key = &key err = c.be.RestoreObject(ctx.Context(), &restoreRequest) - return SendResponse(ctx, err, &MetaOpts{ - Logger: c.logger, - EvSender: c.evSender, - Action: "RestoreObject", - BucketOwner: parsedAcl.Owner, - EventName: s3event.EventObjectRestoreCompleted, - }) + return SendResponse(ctx, err, + &MetaOpts{ + Logger: c.logger, + EvSender: c.evSender, + Action: "RestoreObject", + BucketOwner: parsedAcl.Owner, + EventName: s3event.EventObjectRestoreCompleted, + }) } if ctx.Request().URI().QueryArgs().Has("select") && ctx.Query("select-type") == "2" { var payload s3response.SelectObjectContentPayload - if err := xml.Unmarshal(ctx.Body(), &payload); err != nil { - return SendXMLResponse(ctx, nil, s3err.GetAPIError(s3err.ErrMalformedXML), &MetaOpts{ - Logger: c.logger, - Action: "SelectObjectContent", - BucketOwner: parsedAcl.Owner, - }) + err := xml.Unmarshal(ctx.Body(), &payload) + if err != nil { + return SendXMLResponse(ctx, nil, + s3err.GetAPIError(s3err.ErrMalformedXML), + &MetaOpts{ + Logger: c.logger, + Action: "SelectObjectContent", + BucketOwner: parsedAcl.Owner, + }) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "SelectObjectContent", BucketOwner: parsedAcl.Owner}) + err = auth.VerifyACL(parsedAcl, acct.Access, "READ", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "SelectObjectContent", + BucketOwner: parsedAcl.Owner, + }) } - sw := c.be.SelectObjectContent(ctx.Context(), &s3.SelectObjectContentInput{ - Bucket: &bucket, - Key: &key, - Expression: payload.Expression, - ExpressionType: payload.ExpressionType, - InputSerialization: payload.InputSerialization, - OutputSerialization: payload.OutputSerialization, - RequestProgress: payload.RequestProgress, - ScanRange: payload.ScanRange, - }) + sw := c.be.SelectObjectContent(ctx.Context(), + &s3.SelectObjectContentInput{ + Bucket: &bucket, + Key: &key, + Expression: payload.Expression, + ExpressionType: payload.ExpressionType, + InputSerialization: payload.InputSerialization, + OutputSerialization: payload.OutputSerialization, + RequestProgress: payload.RequestProgress, + ScanRange: payload.ScanRange, + }) ctx.Context().SetBodyStreamWriter(sw) @@ -1023,51 +1525,72 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error { }{} if err := xml.Unmarshal(ctx.Body(), &data); err != nil { - return SendXMLResponse(ctx, nil, s3err.GetAPIError(s3err.ErrMalformedXML), &MetaOpts{ - Logger: c.logger, - Action: "CompleteMultipartUpload", - BucketOwner: parsedAcl.Owner, - }) + return SendXMLResponse(ctx, nil, + s3err.GetAPIError(s3err.ErrMalformedXML), + &MetaOpts{ + Logger: c.logger, + Action: "CompleteMultipartUpload", + BucketOwner: parsedAcl.Owner, + }) } - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "CompleteMultipartUpload", BucketOwner: parsedAcl.Owner}) + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ + Logger: c.logger, + Action: "CompleteMultipartUpload", + BucketOwner: parsedAcl.Owner, + }) } - res, err := c.be.CompleteMultipartUpload(ctx.Context(), &s3.CompleteMultipartUploadInput{ - Bucket: &bucket, - Key: &key, - UploadId: &uploadId, - MultipartUpload: &types.CompletedMultipartUpload{ - Parts: data.Parts, - }, - }) + res, err := c.be.CompleteMultipartUpload(ctx.Context(), + &s3.CompleteMultipartUploadInput{ + Bucket: &bucket, + Key: &key, + UploadId: &uploadId, + MultipartUpload: &types.CompletedMultipartUpload{ + Parts: data.Parts, + }, + }) if err == nil { - return SendXMLResponse(ctx, res, err, &MetaOpts{ + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + EvSender: c.evSender, + Action: "CompleteMultipartUpload", + BucketOwner: parsedAcl.Owner, + ObjectETag: res.ETag, + EventName: s3event.EventCompleteMultipartUpload, + VersionId: res.VersionId, + }) + } + return SendXMLResponse(ctx, res, err, + &MetaOpts{ Logger: c.logger, - EvSender: c.evSender, Action: "CompleteMultipartUpload", BucketOwner: parsedAcl.Owner, - ObjectETag: res.ETag, - EventName: s3event.EventCompleteMultipartUpload, - VersionId: res.VersionId, }) - } else { - return SendXMLResponse(ctx, res, err, &MetaOpts{ + } + + err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot) + if err != nil { + return SendXMLResponse(ctx, nil, err, + &MetaOpts{ Logger: c.logger, - Action: "CompleteMultipartUpload", + Action: "CreateMultipartUpload", BucketOwner: parsedAcl.Owner, }) - } - } - - if err := auth.VerifyACL(parsedAcl, acct.Access, "WRITE", isRoot); err != nil { - return SendXMLResponse(ctx, nil, err, &MetaOpts{Logger: c.logger, Action: "CreateMultipartUpload", BucketOwner: parsedAcl.Owner}) } res, err := c.be.CreateMultipartUpload(ctx.Context(), &s3.CreateMultipartUploadInput{Bucket: &bucket, Key: &key}) - return SendXMLResponse(ctx, res, err, &MetaOpts{Logger: c.logger, Action: "CreateMultipartUpload", BucketOwner: parsedAcl.Owner}) + return SendXMLResponse(ctx, res, err, + &MetaOpts{ + Logger: c.logger, + Action: "CreateMultipartUpload", + BucketOwner: parsedAcl.Owner, + }) } type MetaOpts struct { @@ -1123,6 +1646,10 @@ func SendResponse(ctx *fiber.Ctx, err error, l *MetaOpts) error { return nil } +var ( + xmlhdr = []byte(`` + "\n") +) + func SendXMLResponse(ctx *fiber.Ctx, resp any, err error, l *MetaOpts) error { if err != nil { if l.Logger != nil { @@ -1177,5 +1704,9 @@ func SendXMLResponse(ctx *fiber.Ctx, resp any, err error, l *MetaOpts) error { }) } - return ctx.Send(b) + res := make([]byte, 0, len(xmlhdr)+len(b)) + res = append(res, xmlhdr...) + res = append(res, b...) + + return ctx.Send(res) } diff --git a/s3api/utils/auth-reader.go b/s3api/utils/auth-reader.go index 4b9c2194b..051062c87 100644 --- a/s3api/utils/auth-reader.go +++ b/s3api/utils/auth-reader.go @@ -126,16 +126,19 @@ func CheckValidSignature(ctx *fiber.Ctx, auth AuthData, secret, checksum string, signer := v4.NewSigner() - signErr := signer.SignHTTP(req.Context(), aws.Credentials{ - AccessKeyID: auth.Access, - SecretAccessKey: secret, - }, req, checksum, service, auth.Region, tdate, func(options *v4.SignerOptions) { - options.DisableURIPathEscaping = true - if debug { - options.LogSigning = true - options.Logger = logging.NewStandardLogger(os.Stderr) - } - }) + signErr := signer.SignHTTP(req.Context(), + aws.Credentials{ + AccessKeyID: auth.Access, + SecretAccessKey: secret, + }, + req, checksum, service, auth.Region, tdate, + func(options *v4.SignerOptions) { + options.DisableURIPathEscaping = true + if debug { + options.LogSigning = true + options.Logger = logging.NewStandardLogger(os.Stderr) + } + }) if signErr != nil { return fmt.Errorf("sign generated http request: %w", err) } diff --git a/s3api/utils/auth_test.go b/s3api/utils/auth_test.go index 107ce9e8f..c544ae21d 100644 --- a/s3api/utils/auth_test.go +++ b/s3api/utils/auth_test.go @@ -10,18 +10,26 @@ func TestAuthParse(t *testing.T) { authstr string // Authorization string algo string sig string - }{{ - name: "restic", - authstr: "AWS4-HMAC-SHA256 Credential=user/20240116/us-east-1/s3/aws4_request,SignedHeaders=content-md5;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length,Signature=d5199fc7f3aa35dd3d400427be2ae4c98bfad390785280cbb9eea015b51e12ac", - algo: "AWS4-HMAC-SHA256", - sig: "d5199fc7f3aa35dd3d400427be2ae4c98bfad390785280cbb9eea015b51e12ac", - }, + }{ + { + name: "restic", + authstr: "AWS4-HMAC-SHA256 Credential=user/20240116/us-east-1/s3/aws4_request,SignedHeaders=content-md5;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length,Signature=d5199fc7f3aa35dd3d400427be2ae4c98bfad390785280cbb9eea015b51e12ac", + algo: "AWS4-HMAC-SHA256", + sig: "d5199fc7f3aa35dd3d400427be2ae4c98bfad390785280cbb9eea015b51e12ac", + }, { name: "aws eaxample", authstr: "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request, SignedHeaders=host;range;x-amz-date, Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024", algo: "AWS4-HMAC-SHA256", sig: "fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024", - }} + }, + { + name: "s3browser", + authstr: "AWS4-HMAC-SHA256 Credential=access_key/20240206/us-east-1/s3/aws4_request,SignedHeaders=host;user-agent;x-amz-content-sha256;x-amz-date, Signature=37a35d96998d786113ad420c57c22c5433f6aca74f88f26566caa047fc3601c6", + algo: "AWS4-HMAC-SHA256", + sig: "37a35d96998d786113ad420c57c22c5433f6aca74f88f26566caa047fc3601c6", + }, + } for _, v := range vectors { t.Run(v.name, func(t *testing.T) { diff --git a/s3response/README.txt b/s3response/README.txt deleted file mode 100644 index 99fafb23c..000000000 --- a/s3response/README.txt +++ /dev/null @@ -1,6 +0,0 @@ -https://doc.s3.amazonaws.com/2006-03-01/AmazonS3.xsd - -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 diff --git a/s3response/s3api_xsd_generated.go b/s3response/s3api_xsd_generated.go deleted file mode 100644 index 729786e89..000000000 --- a/s3response/s3api_xsd_generated.go +++ /dev/null @@ -1,1007 +0,0 @@ -// Code generated by xsdgen. DO NOT EDIT. - -package s3response - -import ( - "bytes" - "encoding/base64" - "encoding/xml" - "time" -) - -type AccessControlList struct { - Grant []Grant `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Grant,omitempty"` -} - -type AccessControlPolicy struct { - Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner"` - AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList"` -} - -type AmazonCustomerByEmail struct { - EmailAddress string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ EmailAddress"` -} - -type BucketLoggingStatus struct { - LoggingEnabled LoggingSettings `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LoggingEnabled,omitempty"` -} - -type CanonicalUser struct { - ID string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ID"` - DisplayName string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DisplayName,omitempty"` -} - -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"` - 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 *CopyObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T CopyObject - 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 *CopyObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T CopyObject - 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 CopyObjectResponse struct { - CopyObjectResult CopyObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopyObjectResult"` -} - -type CopyObjectResult struct { - LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` -} - -func (t *CopyObjectResult) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T CopyObjectResult - var layout struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - layout.T = (*T)(t) - layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) - return e.EncodeElement(layout, start) -} -func (t *CopyObjectResult) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T CopyObjectResult - var overlay struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - overlay.T = (*T)(t) - overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) - return d.DecodeElement(&overlay, &start) -} - -type CreateBucket struct { - Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` - AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,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"` -} - -func (t *CreateBucket) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T CreateBucket - 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 *CreateBucket) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T CreateBucket - 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 CreateBucketConfiguration struct { - LocationConstraint string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LocationConstraint"` -} - -type CreateBucketResponse struct { - CreateBucketReturn CreateBucketResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreateBucketReturn"` -} - -type CreateBucketResult struct { - BucketName string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ BucketName"` -} - -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"` - 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 *DeleteBucket) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T DeleteBucket - 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 *DeleteBucket) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T DeleteBucket - 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 DeleteBucketResponse struct { - DeleteBucketResponse Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteBucketResponse"` -} - -type DeleteMarkerEntry 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"` - IsLatest bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsLatest"` - LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner,omitempty"` -} - -func (t *DeleteMarkerEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T DeleteMarkerEntry - var layout struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - layout.T = (*T)(t) - layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) - return e.EncodeElement(layout, start) -} -func (t *DeleteMarkerEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T DeleteMarkerEntry - var overlay struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - overlay.T = (*T)(t) - overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) - return d.DecodeElement(&overlay, &start) -} - -type DeleteObject 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 *DeleteObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T DeleteObject - 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 *DeleteObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T DeleteObject - 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 DeleteObjectResponse struct { - DeleteObjectResponse Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteObjectResponse"` -} - -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"` - 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 *GetBucketAccessControlPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T GetBucketAccessControlPolicy - 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 *GetBucketAccessControlPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T GetBucketAccessControlPolicy - 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 GetBucketAccessControlPolicyResponse struct { - GetBucketAccessControlPolicyResponse AccessControlPolicy `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetBucketAccessControlPolicyResponse"` -} - -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"` - 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 *GetBucketLoggingStatus) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T GetBucketLoggingStatus - 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 *GetBucketLoggingStatus) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T GetBucketLoggingStatus - 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 GetBucketLoggingStatusResponse struct { - GetBucketLoggingStatusResponse BucketLoggingStatus `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetBucketLoggingStatusResponse"` -} - -type GetObject 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"` - GetMetadata bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetMetadata"` - GetData bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetData"` - InlineData bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ InlineData"` - 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 *GetObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T GetObject - 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 *GetObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T GetObject - 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 GetObjectAccessControlPolicy 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 *GetObjectAccessControlPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T GetObjectAccessControlPolicy - 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 *GetObjectAccessControlPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T GetObjectAccessControlPolicy - 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 GetObjectAccessControlPolicyResponse struct { - GetObjectAccessControlPolicyResponse AccessControlPolicy `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetObjectAccessControlPolicyResponse"` -} - -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"` - GetMetadata bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetMetadata"` - GetData bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetData"` - InlineData bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ InlineData"` - ByteRangeStart int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ByteRangeStart,omitempty"` - ByteRangeEnd int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ByteRangeEnd,omitempty"` - IfModifiedSince time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfModifiedSince,omitempty"` - IfUnmodifiedSince time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfUnmodifiedSince,omitempty"` - IfMatch []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfMatch,omitempty"` - IfNoneMatch []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfNoneMatch,omitempty"` - ReturnCompleteObjectOnConditionFailure bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ReturnCompleteObjectOnConditionFailure,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 *GetObjectExtended) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T GetObjectExtended - var layout struct { - *T - IfModifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfModifiedSince,omitempty"` - IfUnmodifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfUnmodifiedSince,omitempty"` - Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` - } - layout.T = (*T)(t) - layout.IfModifiedSince = (*xsdDateTime)(&layout.T.IfModifiedSince) - layout.IfUnmodifiedSince = (*xsdDateTime)(&layout.T.IfUnmodifiedSince) - layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) - return e.EncodeElement(layout, start) -} -func (t *GetObjectExtended) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T GetObjectExtended - var overlay struct { - *T - IfModifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfModifiedSince,omitempty"` - IfUnmodifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfUnmodifiedSince,omitempty"` - Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` - } - overlay.T = (*T)(t) - overlay.IfModifiedSince = (*xsdDateTime)(&overlay.T.IfModifiedSince) - overlay.IfUnmodifiedSince = (*xsdDateTime)(&overlay.T.IfUnmodifiedSince) - overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) - return d.DecodeElement(&overlay, &start) -} - -type GetObjectExtendedResponse struct { - GetObjectResponse GetObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetObjectResponse"` -} - -type GetObjectResponse struct { - GetObjectResponse GetObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetObjectResponse"` -} - -type GetObjectResult struct { - Status Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Status"` - 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,omitempty"` - LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` -} - -func (t *GetObjectResult) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T GetObjectResult - var layout struct { - *T - Data *xsdBase64Binary `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data,omitempty"` - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - layout.T = (*T)(t) - layout.Data = (*xsdBase64Binary)(&layout.T.Data) - layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) - return e.EncodeElement(layout, start) -} -func (t *GetObjectResult) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T GetObjectResult - var overlay struct { - *T - Data *xsdBase64Binary `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data,omitempty"` - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - overlay.T = (*T)(t) - overlay.Data = (*xsdBase64Binary)(&overlay.T.Data) - overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) - return d.DecodeElement(&overlay, &start) -} - -type Grant struct { - Grantee Grantee `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Grantee"` - Permission Permission `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Permission"` -} - -type Grantee struct { -} - -type Group struct { - URI string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ URI"` -} - -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"` - Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` -} - -func (t *ListAllMyBuckets) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T ListAllMyBuckets - 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 *ListAllMyBuckets) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T ListAllMyBuckets - 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 ListAllMyBucketsEntry struct { - Name string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Name"` - CreationDate time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreationDate"` -} - -func (t *ListAllMyBucketsEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T ListAllMyBucketsEntry - var layout struct { - *T - CreationDate *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreationDate"` - } - layout.T = (*T)(t) - layout.CreationDate = (*xsdDateTime)(&layout.T.CreationDate) - return e.EncodeElement(layout, start) -} -func (t *ListAllMyBucketsEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T ListAllMyBucketsEntry - var overlay struct { - *T - CreationDate *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreationDate"` - } - overlay.T = (*T)(t) - overlay.CreationDate = (*xsdDateTime)(&overlay.T.CreationDate) - return d.DecodeElement(&overlay, &start) -} - -type ListAllMyBucketsList struct { - Bucket []ListAllMyBucketsEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket,omitempty"` -} - -type ListAllMyBucketsResponse struct { - ListAllMyBucketsResponse ListAllMyBucketsResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResponse"` -} - -type ListAllMyBucketsResult struct { - Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner"` - Buckets ListAllMyBucketsList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Buckets"` -} - -type ListBucket 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 *ListBucket) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T ListBucket - 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 *ListBucket) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T ListBucket - 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 ListBucketResponse struct { - ListBucketResponse ListBucketResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResponse"` -} - -type ListBucketResult struct { - Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"` - Name string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Name"` - Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"` - Marker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Marker"` - NextMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextMarker,omitempty"` - MaxKeys int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxKeys"` - Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter,omitempty"` - IsTruncated bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsTruncated"` - Contents []ListEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Contents,omitempty"` - CommonPrefixes []PrefixEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CommonPrefixes,omitempty"` -} - -type ListEntry struct { - Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` - LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` - Size int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Size"` - Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner,omitempty"` - StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass"` -} - -func (t *ListEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T ListEntry - var layout struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - layout.T = (*T)(t) - layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) - return e.EncodeElement(layout, start) -} -func (t *ListEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T ListEntry - var overlay struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - overlay.T = (*T)(t) - overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) - return d.DecodeElement(&overlay, &start) -} - -type ListVersionsResponse struct { - ListVersionsResponse ListVersionsResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListVersionsResponse"` -} - -type ListVersionsResult struct { - Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"` - Name string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Name"` - Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"` - KeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ KeyMarker"` - VersionIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersionIdMarker"` - NextKeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextKeyMarker,omitempty"` - NextVersionIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextVersionIdMarker,omitempty"` - MaxKeys int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxKeys"` - Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter,omitempty"` - IsTruncated bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsTruncated"` - Version VersionEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Version,omitempty"` - DeleteMarker DeleteMarkerEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteMarker,omitempty"` - CommonPrefixes []PrefixEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CommonPrefixes,omitempty"` -} - -type LoggingSettings struct { - TargetBucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TargetBucket"` - TargetPrefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TargetPrefix"` - TargetGrants AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TargetGrants,omitempty"` -} - -// May be one of COPY, REPLACE -type MetadataDirective string - -type MetadataEntry struct { - Name string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Name"` - Value string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Value"` -} - -// May be one of Enabled, Disabled -type MfaDeleteStatus string - -type NotificationConfiguration struct { - TopicConfiguration []TopicConfiguration `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TopicConfiguration,omitempty"` -} - -// May be one of BucketOwner, Requester -type Payer string - -// May be one of READ, WRITE, READ_ACP, WRITE_ACP, FULL_CONTROL -type Permission string - -type PostResponse 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 PrefixEntry struct { - Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"` -} - -type PutObject 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 *PutObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T PutObject - 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 *PutObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T PutObject - 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 PutObjectInline 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 *PutObjectInline) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T PutObjectInline - 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 *PutObjectInline) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T PutObjectInline - 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 PutObjectInlineResponse struct { - PutObjectInlineResponse PutObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PutObjectInlineResponse"` -} - -type PutObjectResponse struct { - PutObjectResponse PutObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PutObjectResponse"` -} - -type PutObjectResult struct { - ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` - LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` -} - -func (t *PutObjectResult) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T PutObjectResult - var layout struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - layout.T = (*T)(t) - layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) - return e.EncodeElement(layout, start) -} -func (t *PutObjectResult) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T PutObjectResult - var overlay struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - overlay.T = (*T)(t) - overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) - return d.DecodeElement(&overlay, &start) -} - -type RequestPaymentConfiguration struct { - Payer Payer `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Payer"` -} - -type Result struct { - Status Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Status"` -} - -type SetBucketAccessControlPolicy struct { - Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` - AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,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 *SetBucketAccessControlPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T SetBucketAccessControlPolicy - 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 *SetBucketAccessControlPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T SetBucketAccessControlPolicy - 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 SetBucketAccessControlPolicyResponse struct { -} - -type SetBucketLoggingStatus 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"` - BucketLoggingStatus BucketLoggingStatus `xml:"http://s3.amazonaws.com/doc/2006-03-01/ BucketLoggingStatus"` -} - -func (t *SetBucketLoggingStatus) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T SetBucketLoggingStatus - 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 *SetBucketLoggingStatus) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T SetBucketLoggingStatus - 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 SetBucketLoggingStatusResponse struct { -} - -type SetObjectAccessControlPolicy 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"` - 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 *SetObjectAccessControlPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T SetObjectAccessControlPolicy - 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 *SetObjectAccessControlPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T SetObjectAccessControlPolicy - 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 SetObjectAccessControlPolicyResponse struct { -} - -type Status struct { - Code int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Code"` - Description string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Description"` -} - -// May be one of STANDARD, REDUCED_REDUNDANCY, GLACIER, UNKNOWN -type StorageClass string - -type TopicConfiguration struct { - Topic string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Topic"` - Event []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Event"` -} - -type User struct { -} - -type VersionEntry 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"` - IsLatest bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsLatest"` - LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` - Size int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Size"` - Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner,omitempty"` - StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass"` -} - -func (t *VersionEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type T VersionEntry - var layout struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - layout.T = (*T)(t) - layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) - return e.EncodeElement(layout, start) -} -func (t *VersionEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type T VersionEntry - var overlay struct { - *T - LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` - } - overlay.T = (*T)(t) - overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) - return d.DecodeElement(&overlay, &start) -} - -type VersioningConfiguration struct { - Status VersioningStatus `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Status,omitempty"` - MfaDelete MfaDeleteStatus `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MfaDelete,omitempty"` -} - -// May be one of Enabled, Suspended -type VersioningStatus string - -type xsdBase64Binary []byte - -func (b *xsdBase64Binary) UnmarshalText(text []byte) (err error) { - *b, err = base64.StdEncoding.DecodeString(string(text)) - return -} -func (b xsdBase64Binary) MarshalText() ([]byte, error) { - var buf bytes.Buffer - enc := base64.NewEncoder(base64.StdEncoding, &buf) - enc.Write([]byte(b)) - enc.Close() - return buf.Bytes(), nil -} - -type xsdDateTime time.Time - -func (t *xsdDateTime) UnmarshalText(text []byte) error { - return _unmarshalTime(text, (*time.Time)(t), "2006-01-02T15:04:05.999999999") -} -func (t xsdDateTime) MarshalText() ([]byte, error) { - return _marshalTime((time.Time)(t), "2006-01-02T15:04:05.999999999") -} -func (t xsdDateTime) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - if (time.Time)(t).IsZero() { - return nil - } - m, err := t.MarshalText() - if err != nil { - return err - } - return e.EncodeElement(m, start) -} -func (t xsdDateTime) MarshalXMLAttr(name xml.Name) (xml.Attr, error) { - if (time.Time)(t).IsZero() { - return xml.Attr{}, nil - } - m, err := t.MarshalText() - return xml.Attr{Name: name, Value: string(m)}, err -} -func _unmarshalTime(text []byte, t *time.Time, format string) (err error) { - s := string(bytes.TrimSpace(text)) - *t, err = time.Parse(format, s) - if _, ok := err.(*time.ParseError); ok { - *t, err = time.Parse(format+"Z07:00", s) - } - return err -} -func _marshalTime(t time.Time, format string) ([]byte, error) { - return []byte(t.Format(format + "Z07:00")), nil -} diff --git a/s3response/s3response.go b/s3response/s3response.go index cb0b401f7..c3a14b51b 100644 --- a/s3response/s3response.go +++ b/s3response/s3response.go @@ -16,6 +16,7 @@ package s3response import ( "encoding/xml" + "time" "github.com/aws/aws-sdk-go-v2/service/s3/types" ) @@ -107,7 +108,8 @@ type TagSet struct { } type Tagging struct { - TagSet TagSet `xml:"TagSet"` + XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Tagging" json:"-"` + TagSet TagSet `xml:"TagSet"` } type DeleteObjects struct { @@ -139,3 +141,58 @@ type Bucket struct { Name string `json:"name"` Owner string `json:"owner"` } + +type ListAllMyBucketsResult struct { + XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResult" json:"-"` + Owner CanonicalUser + Buckets ListAllMyBucketsList +} + +type ListAllMyBucketsEntry struct { + Name string + CreationDate time.Time +} + +type ListAllMyBucketsList struct { + Bucket []ListAllMyBucketsEntry +} + +type CanonicalUser struct { + ID string + DisplayName string +} + +type CopyObjectResult struct { + XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopyObjectResult" json:"-"` + LastModified time.Time + ETag string +} + +type AccessControlPolicy struct { + XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlPolicy" json:"-"` + Owner CanonicalUser + AccessControlList AccessControlList +} + +type AccessControlList struct { + Grant []Grant +} + +type Grant struct { + Grantee Grantee + Permission string +} + +// Set the following to encode correctly: +// +// Grantee: s3response.Grantee{ +// Xsi: "http://www.w3.org/2001/XMLSchema-instance", +// Type: "CanonicalUser", +// }, +type Grantee struct { + XMLName xml.Name `xml:"Grantee"` + Xsi string `xml:"xmlns:xsi,attr,omitempty"` + Type string `xml:"xsi:type,attr,omitempty"` + ID string + DisplayName string +}