mirror of
https://github.com/versity/versitygw.git
synced 2025-12-23 05:05:16 +00:00
Closes #1595 This implementation diverges from AWS S3 behavior. The `CreateBucket` request body is no longer ignored. Based on the S3 request body schema, the gateway parses only the `LocationConstraint` and `Tags` fields. If the `LocationConstraint` does not match the gateway’s region, it returns an `InvalidLocationConstraint` error. In AWS S3, tagging during bucket creation is supported only for directory buckets. The gateway extends this support to general-purpose buckets. If the request body is malformed, the gateway returns a `MalformedXML` error.
736 lines
20 KiB
Go
736 lines
20 KiB
Go
// Copyright 2023 Versity Software
|
|
// This file is licensed under the Apache License, Version 2.0
|
|
// (the "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
package s3response
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"io"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
|
"github.com/versity/versitygw/s3err"
|
|
)
|
|
|
|
const (
|
|
iso8601TimeFormat = "2006-01-02T15:04:05.000Z"
|
|
iso8601TimeFormatExtended = "2006-01-02T15:04:05.000000Z"
|
|
iso8601TimeFormatWithTZ = "2006-01-02T15:04:05-0700"
|
|
)
|
|
|
|
type PutObjectOutput struct {
|
|
ETag string
|
|
VersionID string
|
|
ChecksumCRC32 *string
|
|
ChecksumCRC32C *string
|
|
ChecksumSHA1 *string
|
|
ChecksumSHA256 *string
|
|
ChecksumCRC64NVME *string
|
|
Size *int64
|
|
ChecksumType types.ChecksumType
|
|
}
|
|
|
|
// Part describes part metadata.
|
|
type Part struct {
|
|
PartNumber int
|
|
LastModified time.Time
|
|
ETag string
|
|
Size int64
|
|
ChecksumCRC32 *string
|
|
ChecksumCRC32C *string
|
|
ChecksumSHA1 *string
|
|
ChecksumSHA256 *string
|
|
ChecksumCRC64NVME *string
|
|
}
|
|
|
|
func (p Part) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
type Alias Part
|
|
aux := &struct {
|
|
LastModified string `xml:"LastModified"`
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(&p),
|
|
}
|
|
|
|
aux.LastModified = p.LastModified.UTC().Format(time.RFC3339)
|
|
|
|
return e.EncodeElement(aux, start)
|
|
}
|
|
|
|
// ListPartsResponse - s3 api list parts response.
|
|
type ListPartsResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListPartsResult" json:"-"`
|
|
|
|
Bucket string
|
|
Key string
|
|
UploadID string `xml:"UploadId"`
|
|
ChecksumAlgorithm types.ChecksumAlgorithm
|
|
ChecksumType types.ChecksumType
|
|
|
|
Initiator Initiator
|
|
Owner Owner
|
|
|
|
// The class of storage used to store the object.
|
|
StorageClass types.StorageClass
|
|
|
|
PartNumberMarker int
|
|
NextPartNumberMarker int
|
|
MaxParts int
|
|
IsTruncated bool
|
|
|
|
// List of parts.
|
|
Parts []Part `xml:"Part"`
|
|
}
|
|
|
|
type ObjectAttributes string
|
|
|
|
const (
|
|
ObjectAttributesEtag ObjectAttributes = "ETag"
|
|
ObjectAttributesChecksum ObjectAttributes = "Checksum"
|
|
ObjectAttributesObjectParts ObjectAttributes = "ObjectParts"
|
|
ObjectAttributesStorageClass ObjectAttributes = "StorageClass"
|
|
ObjectAttributesObjectSize ObjectAttributes = "ObjectSize"
|
|
)
|
|
|
|
func (o ObjectAttributes) IsValid() bool {
|
|
return o == ObjectAttributesChecksum ||
|
|
o == ObjectAttributesEtag ||
|
|
o == ObjectAttributesObjectParts ||
|
|
o == ObjectAttributesObjectSize ||
|
|
o == ObjectAttributesStorageClass
|
|
}
|
|
|
|
type GetObjectAttributesResponse struct {
|
|
ETag *string
|
|
ObjectSize *int64
|
|
StorageClass types.StorageClass `xml:",omitempty"`
|
|
ObjectParts *ObjectParts
|
|
Checksum *types.Checksum
|
|
|
|
// Not included in the response body
|
|
VersionId *string
|
|
LastModified *time.Time
|
|
DeleteMarker *bool
|
|
}
|
|
|
|
type ObjectParts struct {
|
|
PartNumberMarker int
|
|
NextPartNumberMarker int
|
|
MaxParts int
|
|
IsTruncated bool
|
|
Parts []types.ObjectPart `xml:"Part"`
|
|
}
|
|
|
|
// ListMultipartUploadsResponse - s3 api list multipart uploads response.
|
|
type ListMultipartUploadsResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListMultipartUploadsResult" json:"-"`
|
|
|
|
Bucket string
|
|
KeyMarker string
|
|
UploadIDMarker string `xml:"UploadIdMarker"`
|
|
NextKeyMarker string
|
|
NextUploadIDMarker string `xml:"NextUploadIdMarker"`
|
|
Delimiter string
|
|
Prefix string
|
|
EncodingType string `xml:"EncodingType,omitempty"`
|
|
MaxUploads int
|
|
IsTruncated bool
|
|
|
|
// List of pending uploads.
|
|
Uploads []Upload `xml:"Upload"`
|
|
|
|
// Delimed common prefixes.
|
|
CommonPrefixes []CommonPrefix
|
|
}
|
|
|
|
type ListObjectsResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResult" json:"-"`
|
|
Name *string
|
|
Prefix *string
|
|
Marker *string
|
|
NextMarker *string
|
|
MaxKeys *int32
|
|
Delimiter *string
|
|
IsTruncated *bool
|
|
Contents []Object
|
|
CommonPrefixes []types.CommonPrefix
|
|
EncodingType types.EncodingType
|
|
}
|
|
|
|
type ListObjectsV2Result struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResult" json:"-"`
|
|
Name *string
|
|
Prefix *string
|
|
StartAfter *string
|
|
ContinuationToken *string `xml:"ContinuationToken,omitempty"`
|
|
NextContinuationToken *string
|
|
KeyCount *int32
|
|
MaxKeys *int32
|
|
Delimiter *string
|
|
IsTruncated *bool
|
|
Contents []Object
|
|
CommonPrefixes []types.CommonPrefix
|
|
EncodingType types.EncodingType
|
|
}
|
|
|
|
type Object struct {
|
|
ChecksumAlgorithm []types.ChecksumAlgorithm
|
|
ChecksumType types.ChecksumType
|
|
ETag *string
|
|
Key *string
|
|
LastModified *time.Time
|
|
Owner *types.Owner
|
|
RestoreStatus *types.RestoreStatus
|
|
Size *int64
|
|
StorageClass types.ObjectStorageClass
|
|
}
|
|
|
|
func (o Object) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
type Alias Object
|
|
aux := &struct {
|
|
LastModified string `xml:"LastModified,omitempty"`
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(&o),
|
|
}
|
|
|
|
if o.LastModified != nil {
|
|
aux.LastModified = o.LastModified.UTC().Format(time.RFC3339)
|
|
}
|
|
|
|
return e.EncodeElement(aux, start)
|
|
}
|
|
|
|
// Upload describes in progress multipart upload
|
|
type Upload struct {
|
|
Key string
|
|
UploadID string `xml:"UploadId"`
|
|
Initiator Initiator
|
|
Owner Owner
|
|
StorageClass types.StorageClass
|
|
Initiated time.Time
|
|
ChecksumAlgorithm types.ChecksumAlgorithm
|
|
ChecksumType types.ChecksumType
|
|
}
|
|
|
|
func (u Upload) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
type Alias Upload
|
|
aux := &struct {
|
|
Initiated string `xml:"Initiated"`
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(&u),
|
|
}
|
|
|
|
aux.Initiated = u.Initiated.UTC().Format(time.RFC3339)
|
|
|
|
return e.EncodeElement(aux, start)
|
|
}
|
|
|
|
// CommonPrefix ListObjectsResponse common prefixes (directory abstraction)
|
|
type CommonPrefix struct {
|
|
Prefix string
|
|
}
|
|
|
|
// Initiator same fields as Owner
|
|
type Initiator Owner
|
|
|
|
// Owner bucket ownership
|
|
type Owner struct {
|
|
ID string
|
|
DisplayName string
|
|
}
|
|
|
|
type Tag struct {
|
|
Key string `xml:"Key"`
|
|
Value string `xml:"Value"`
|
|
}
|
|
|
|
type TagSet struct {
|
|
Tags []Tag `xml:"Tag"`
|
|
}
|
|
|
|
type Tagging struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Tagging" json:"-"`
|
|
TagSet TagSet `xml:"TagSet"`
|
|
}
|
|
|
|
type TaggingInput struct {
|
|
TagSet TagSet `xml:"TagSet"`
|
|
}
|
|
|
|
type DeleteObjects struct {
|
|
Objects []types.ObjectIdentifier `xml:"Object"`
|
|
}
|
|
|
|
type DeleteResult struct {
|
|
Deleted []types.DeletedObject
|
|
Error []types.Error
|
|
}
|
|
type SelectObjectContentPayload struct {
|
|
Expression *string
|
|
ExpressionType types.ExpressionType
|
|
RequestProgress *types.RequestProgress
|
|
InputSerialization *types.InputSerialization
|
|
OutputSerialization *types.OutputSerialization
|
|
ScanRange *types.ScanRange
|
|
}
|
|
|
|
type SelectObjectContentResult struct {
|
|
Records *types.RecordsEvent
|
|
Stats *types.StatsEvent
|
|
Progress *types.ProgressEvent
|
|
Cont *types.ContinuationEvent
|
|
End *types.EndEvent
|
|
}
|
|
|
|
type Bucket struct {
|
|
Name string `json:"name"`
|
|
Owner string `json:"owner"`
|
|
}
|
|
|
|
type ListBucketsInput struct {
|
|
Owner string
|
|
IsAdmin bool
|
|
ContinuationToken string
|
|
Prefix string
|
|
MaxBuckets int32
|
|
}
|
|
|
|
type ListAllMyBucketsResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResult" json:"-"`
|
|
Owner CanonicalUser
|
|
Buckets ListAllMyBucketsList
|
|
ContinuationToken string `xml:"ContinuationToken,omitempty"`
|
|
Prefix string `xml:"Prefix,omitempty"`
|
|
}
|
|
|
|
type ListAllMyBucketsEntry struct {
|
|
Name string
|
|
BucketRegion string
|
|
CreationDate time.Time
|
|
}
|
|
|
|
func (r ListAllMyBucketsEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
type Alias ListAllMyBucketsEntry
|
|
aux := &struct {
|
|
CreationDate string `xml:"CreationDate"`
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(&r),
|
|
}
|
|
|
|
aux.CreationDate = r.CreationDate.UTC().Format(time.RFC3339)
|
|
|
|
return e.EncodeElement(aux, start)
|
|
}
|
|
|
|
type ListAllMyBucketsList struct {
|
|
Bucket []ListAllMyBucketsEntry
|
|
}
|
|
|
|
type CanonicalUser struct {
|
|
ID string
|
|
DisplayName string
|
|
}
|
|
|
|
type CopyObjectOutput struct {
|
|
BucketKeyEnabled *bool
|
|
CopyObjectResult *CopyObjectResult
|
|
CopySourceVersionId *string
|
|
Expiration *string
|
|
SSECustomerAlgorithm *string
|
|
SSECustomerKeyMD5 *string
|
|
SSEKMSEncryptionContext *string
|
|
SSEKMSKeyId *string
|
|
ServerSideEncryption types.ServerSideEncryption
|
|
VersionId *string
|
|
}
|
|
|
|
type CopyObjectResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopyObjectResult" json:"-"`
|
|
ChecksumCRC32 *string
|
|
ChecksumCRC32C *string
|
|
ChecksumCRC64NVME *string
|
|
ChecksumSHA1 *string
|
|
ChecksumSHA256 *string
|
|
ChecksumType types.ChecksumType
|
|
ETag *string
|
|
LastModified *time.Time
|
|
}
|
|
|
|
func (r CopyObjectResult) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
type Alias CopyObjectResult
|
|
aux := &struct {
|
|
LastModified string `xml:"LastModified,omitempty"`
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(&r),
|
|
}
|
|
if r.LastModified != nil {
|
|
aux.LastModified = r.LastModified.UTC().Format(time.RFC3339)
|
|
}
|
|
|
|
return e.EncodeElement(aux, start)
|
|
}
|
|
|
|
type CopyPartResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopyPartResult" json:"-"`
|
|
LastModified time.Time
|
|
ETag *string
|
|
ChecksumCRC32 *string
|
|
ChecksumCRC32C *string
|
|
ChecksumSHA1 *string
|
|
ChecksumSHA256 *string
|
|
ChecksumCRC64NVME *string
|
|
|
|
// not included in the body
|
|
CopySourceVersionId string `xml:"-"`
|
|
}
|
|
|
|
func (r CopyPartResult) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
type Alias CopyPartResult
|
|
aux := &struct {
|
|
LastModified string `xml:"LastModified,omitempty"`
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(&r),
|
|
}
|
|
if !r.LastModified.IsZero() {
|
|
aux.LastModified = r.LastModified.UTC().Format(time.RFC3339)
|
|
}
|
|
|
|
return e.EncodeElement(aux, start)
|
|
}
|
|
|
|
type CompleteMultipartUploadRequestBody struct {
|
|
Parts []types.CompletedPart `xml:"Part"`
|
|
}
|
|
|
|
type CompleteMultipartUploadResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CompleteMultipartUploadResult" json:"-"`
|
|
Location *string
|
|
Bucket *string
|
|
Key *string
|
|
ETag *string
|
|
ChecksumCRC32 *string
|
|
ChecksumCRC32C *string
|
|
ChecksumSHA1 *string
|
|
ChecksumSHA256 *string
|
|
ChecksumCRC64NVME *string
|
|
ChecksumType *types.ChecksumType
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
type OwnershipControls struct {
|
|
Rules []types.OwnershipControlsRule `xml:"Rule"`
|
|
}
|
|
|
|
type InitiateMultipartUploadResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ InitiateMultipartUploadResult" json:"-"`
|
|
Bucket string
|
|
Key string
|
|
UploadId string
|
|
}
|
|
|
|
type ListVersionsResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListVersionsResult" json:"-"`
|
|
CommonPrefixes []types.CommonPrefix
|
|
DeleteMarkers []types.DeleteMarkerEntry `xml:"DeleteMarker"`
|
|
Delimiter *string
|
|
EncodingType types.EncodingType
|
|
IsTruncated *bool
|
|
KeyMarker *string
|
|
MaxKeys *int32
|
|
Name *string
|
|
NextKeyMarker *string
|
|
NextVersionIdMarker *string
|
|
Prefix *string
|
|
VersionIdMarker *string
|
|
Versions []ObjectVersion `xml:"Version"`
|
|
}
|
|
|
|
type ObjectVersion struct {
|
|
ChecksumAlgorithm []types.ChecksumAlgorithm
|
|
ChecksumType types.ChecksumType
|
|
ETag *string
|
|
IsLatest *bool
|
|
Key *string
|
|
LastModified *time.Time
|
|
Owner *types.Owner
|
|
RestoreStatus *types.RestoreStatus
|
|
Size *int64
|
|
StorageClass types.ObjectVersionStorageClass
|
|
VersionId *string
|
|
}
|
|
|
|
func (o ObjectVersion) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
type Alias ObjectVersion
|
|
aux := &struct {
|
|
LastModified string `xml:"LastModified"`
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(&o),
|
|
}
|
|
|
|
if o.LastModified != nil {
|
|
aux.LastModified = o.LastModified.UTC().Format(time.RFC3339)
|
|
}
|
|
|
|
return e.EncodeElement(aux, start)
|
|
}
|
|
|
|
type GetBucketVersioningOutput struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersioningConfiguration" json:"-"`
|
|
MFADelete *types.MFADeleteStatus
|
|
Status *types.BucketVersioningStatus
|
|
}
|
|
|
|
type PutObjectRetentionInput struct {
|
|
XMLName xml.Name `xml:"Retention"`
|
|
Mode types.ObjectLockRetentionMode
|
|
RetainUntilDate AmzDate
|
|
}
|
|
|
|
type PutObjectInput struct {
|
|
ContentLength *int64
|
|
ObjectLockRetainUntilDate *time.Time
|
|
|
|
Bucket *string
|
|
Key *string
|
|
ContentType *string
|
|
ContentEncoding *string
|
|
ContentDisposition *string
|
|
ContentLanguage *string
|
|
CacheControl *string
|
|
Expires *string
|
|
Tagging *string
|
|
ChecksumCRC32 *string
|
|
ChecksumCRC32C *string
|
|
ChecksumSHA1 *string
|
|
ChecksumSHA256 *string
|
|
ChecksumCRC64NVME *string
|
|
ContentMD5 *string
|
|
ExpectedBucketOwner *string
|
|
GrantFullControl *string
|
|
GrantRead *string
|
|
GrantReadACP *string
|
|
GrantWriteACP *string
|
|
IfMatch *string
|
|
IfNoneMatch *string
|
|
SSECustomerAlgorithm *string
|
|
SSECustomerKey *string
|
|
SSECustomerKeyMD5 *string
|
|
SSEKMSEncryptionContext *string
|
|
SSEKMSKeyId *string
|
|
WebsiteRedirectLocation *string
|
|
|
|
ObjectLockMode types.ObjectLockMode
|
|
ObjectLockLegalHoldStatus types.ObjectLockLegalHoldStatus
|
|
ChecksumAlgorithm types.ChecksumAlgorithm
|
|
|
|
Metadata map[string]string
|
|
Body io.Reader
|
|
}
|
|
|
|
type CreateMultipartUploadInput struct {
|
|
Bucket *string
|
|
Key *string
|
|
ExpectedBucketOwner *string
|
|
CacheControl *string
|
|
ContentDisposition *string
|
|
ContentEncoding *string
|
|
ContentLanguage *string
|
|
ContentType *string
|
|
Expires *string
|
|
SSECustomerAlgorithm *string
|
|
SSECustomerKey *string
|
|
SSECustomerKeyMD5 *string
|
|
SSEKMSEncryptionContext *string
|
|
SSEKMSKeyId *string
|
|
GrantFullControl *string
|
|
GrantRead *string
|
|
GrantReadACP *string
|
|
GrantWriteACP *string
|
|
Tagging *string
|
|
WebsiteRedirectLocation *string
|
|
BucketKeyEnabled *bool
|
|
ObjectLockRetainUntilDate *time.Time
|
|
Metadata map[string]string
|
|
|
|
ACL types.ObjectCannedACL
|
|
ChecksumAlgorithm types.ChecksumAlgorithm
|
|
ChecksumType types.ChecksumType
|
|
ObjectLockLegalHoldStatus types.ObjectLockLegalHoldStatus
|
|
ObjectLockMode types.ObjectLockMode
|
|
RequestPayer types.RequestPayer
|
|
ServerSideEncryption types.ServerSideEncryption
|
|
StorageClass types.StorageClass
|
|
}
|
|
|
|
type CopyObjectInput struct {
|
|
Metadata map[string]string
|
|
Bucket *string
|
|
CopySource *string
|
|
Key *string
|
|
CacheControl *string
|
|
ContentDisposition *string
|
|
ContentEncoding *string
|
|
ContentLanguage *string
|
|
ContentType *string
|
|
CopySourceIfMatch *string
|
|
CopySourceIfNoneMatch *string
|
|
CopySourceSSECustomerAlgorithm *string
|
|
CopySourceSSECustomerKey *string
|
|
CopySourceSSECustomerKeyMD5 *string
|
|
ExpectedBucketOwner *string
|
|
ExpectedSourceBucketOwner *string
|
|
Expires *string
|
|
GrantFullControl *string
|
|
GrantRead *string
|
|
GrantReadACP *string
|
|
GrantWriteACP *string
|
|
SSECustomerAlgorithm *string
|
|
SSECustomerKey *string
|
|
SSECustomerKeyMD5 *string
|
|
SSEKMSEncryptionContext *string
|
|
SSEKMSKeyId *string
|
|
Tagging *string
|
|
WebsiteRedirectLocation *string
|
|
|
|
CopySourceIfModifiedSince *time.Time
|
|
CopySourceIfUnmodifiedSince *time.Time
|
|
ObjectLockRetainUntilDate *time.Time
|
|
|
|
BucketKeyEnabled *bool
|
|
|
|
ACL types.ObjectCannedACL
|
|
ChecksumAlgorithm types.ChecksumAlgorithm
|
|
MetadataDirective types.MetadataDirective
|
|
ObjectLockLegalHoldStatus types.ObjectLockLegalHoldStatus
|
|
ObjectLockMode types.ObjectLockMode
|
|
RequestPayer types.RequestPayer
|
|
ServerSideEncryption types.ServerSideEncryption
|
|
StorageClass types.StorageClass
|
|
TaggingDirective types.TaggingDirective
|
|
}
|
|
|
|
type GetObjectLegalHoldResult struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LegalHold"`
|
|
Status types.ObjectLockLegalHoldStatus
|
|
}
|
|
|
|
type AmzDate struct {
|
|
time.Time
|
|
}
|
|
|
|
// Parses the date from xml string and validates for predefined date formats
|
|
func (d *AmzDate) UnmarshalXML(e *xml.Decoder, startElement xml.StartElement) error {
|
|
var dateStr string
|
|
err := e.DecodeElement(&dateStr, &startElement)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
retDate, err := d.ISO8601Parse(dateStr)
|
|
if err != nil {
|
|
return s3err.GetAPIError(s3err.ErrInvalidRequest)
|
|
}
|
|
|
|
*d = AmzDate{retDate}
|
|
return nil
|
|
}
|
|
|
|
// Encodes expiration date if it is non-zero
|
|
// Encodes empty string if it's zero
|
|
func (d AmzDate) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error {
|
|
if d.IsZero() {
|
|
return nil
|
|
}
|
|
return e.EncodeElement(d.UTC().Format(iso8601TimeFormat), startElement)
|
|
}
|
|
|
|
// Parses ISO8601 date string to time.Time by
|
|
// validating different time layouts
|
|
func (AmzDate) ISO8601Parse(date string) (t time.Time, err error) {
|
|
for _, layout := range []string{
|
|
iso8601TimeFormat,
|
|
iso8601TimeFormatExtended,
|
|
iso8601TimeFormatWithTZ,
|
|
time.RFC3339,
|
|
} {
|
|
t, err = time.Parse(layout, date)
|
|
if err == nil {
|
|
return t, nil
|
|
}
|
|
}
|
|
|
|
return t, err
|
|
}
|
|
|
|
// Admin api response types
|
|
type ListBucketsResult struct {
|
|
Buckets []Bucket
|
|
}
|
|
|
|
type Checksum struct {
|
|
Algorithm types.ChecksumAlgorithm
|
|
Type types.ChecksumType
|
|
|
|
CRC32 *string
|
|
CRC32C *string
|
|
SHA1 *string
|
|
SHA256 *string
|
|
CRC64NVME *string
|
|
}
|
|
|
|
// LocationConstraint represents the GetBucketLocation response
|
|
type LocationConstraint struct {
|
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LocationConstraint"`
|
|
Value string `xml:",chardata"`
|
|
}
|
|
|
|
type CreateBucketConfiguration struct {
|
|
LocationConstraint string
|
|
TagSet []types.Tag `xml:"Tags>Tag"`
|
|
}
|