diff options
Diffstat (limited to 'weed/s3api')
| -rw-r--r-- | weed/s3api/AmazonS3.xsd | 692 | ||||
| -rw-r--r-- | weed/s3api/README.txt | 7 | ||||
| -rw-r--r-- | weed/s3api/s3api_bucket_handlers.go | 177 | ||||
| -rw-r--r-- | weed/s3api/s3api_errors.go | 88 | ||||
| -rw-r--r-- | weed/s3api/s3api_handlers.go | 100 | ||||
| -rw-r--r-- | weed/s3api/s3api_object_handlers.go | 163 | ||||
| -rw-r--r-- | weed/s3api/s3api_server.go | 113 | ||||
| -rw-r--r-- | weed/s3api/s3api_xsd_generated.go | 1002 |
8 files changed, 2342 insertions, 0 deletions
diff --git a/weed/s3api/AmazonS3.xsd b/weed/s3api/AmazonS3.xsd new file mode 100644 index 000000000..8016a6a83 --- /dev/null +++ b/weed/s3api/AmazonS3.xsd @@ -0,0 +1,692 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsd:schema + xmlns:tns="http://s3.amazonaws.com/doc/2006-03-01/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified" + targetNamespace="http://s3.amazonaws.com/doc/2006-03-01/"> + + <xsd:element name="CreateBucket"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="MetadataEntry"> + <xsd:sequence> + <xsd:element name="Name" type="xsd:string"/> + <xsd:element name="Value" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="CreateBucketResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="CreateBucketReturn" type="tns:CreateBucketResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="Status"> + <xsd:sequence> + <xsd:element name="Code" type="xsd:int"/> + <xsd:element name="Description" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="Result"> + <xsd:sequence> + <xsd:element name="Status" type="tns:Status"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="CreateBucketResult"> + <xsd:sequence> + <xsd:element name="BucketName" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="DeleteBucket"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="DeleteBucketResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="DeleteBucketResponse" type="tns:Status"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="BucketLoggingStatus"> + <xsd:sequence> + <xsd:element name="LoggingEnabled" type="tns:LoggingSettings" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="LoggingSettings"> + <xsd:sequence> + <xsd:element name="TargetBucket" type="xsd:string"/> + <xsd:element name="TargetPrefix" type="xsd:string"/> + <xsd:element name="TargetGrants" type="tns:AccessControlList" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="GetBucketLoggingStatus"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetBucketLoggingStatusResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetBucketLoggingStatusResponse" type="tns:BucketLoggingStatus"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetBucketLoggingStatus"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + <xsd:element name="BucketLoggingStatus" type="tns:BucketLoggingStatus"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetBucketLoggingStatusResponse"> + <xsd:complexType> + <xsd:sequence/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObjectAccessControlPolicy"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObjectAccessControlPolicyResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetObjectAccessControlPolicyResponse" type="tns:AccessControlPolicy"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetBucketAccessControlPolicy"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetBucketAccessControlPolicyResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetBucketAccessControlPolicyResponse" type="tns:AccessControlPolicy"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType abstract="true" name="Grantee"/> + + <xsd:complexType name="User" abstract="true"> + <xsd:complexContent> + <xsd:extension base="tns:Grantee"/> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="AmazonCustomerByEmail"> + <xsd:complexContent> + <xsd:extension base="tns:User"> + <xsd:sequence> + <xsd:element name="EmailAddress" type="xsd:string"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="CanonicalUser"> + <xsd:complexContent> + <xsd:extension base="tns:User"> + <xsd:sequence> + <xsd:element name="ID" type="xsd:string"/> + <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="Group"> + <xsd:complexContent> + <xsd:extension base="tns:Grantee"> + <xsd:sequence> + <xsd:element name="URI" type="xsd:string"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:simpleType name="Permission"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="READ"/> + <xsd:enumeration value="WRITE"/> + <xsd:enumeration value="READ_ACP"/> + <xsd:enumeration value="WRITE_ACP"/> + <xsd:enumeration value="FULL_CONTROL"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="StorageClass"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="STANDARD"/> + <xsd:enumeration value="REDUCED_REDUNDANCY"/> + <xsd:enumeration value="GLACIER"/> + <xsd:enumeration value="UNKNOWN"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="Grant"> + <xsd:sequence> + <xsd:element name="Grantee" type="tns:Grantee"/> + <xsd:element name="Permission" type="tns:Permission"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="AccessControlList"> + <xsd:sequence> + <xsd:element name="Grant" type="tns:Grant" minOccurs="0" maxOccurs="100"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="CreateBucketConfiguration"> + <xsd:sequence> + <xsd:element name="LocationConstraint" type="tns:LocationConstraint"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="LocationConstraint"> + <xsd:simpleContent> + <xsd:extension base="xsd:string"/> + </xsd:simpleContent> + </xsd:complexType> + + <xsd:complexType name="AccessControlPolicy"> + <xsd:sequence> + <xsd:element name="Owner" type="tns:CanonicalUser"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="SetObjectAccessControlPolicy"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetObjectAccessControlPolicyResponse"> + <xsd:complexType> + <xsd:sequence/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetBucketAccessControlPolicy"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetBucketAccessControlPolicyResponse"> + <xsd:complexType> + <xsd:sequence/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObject"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="GetMetadata" type="xsd:boolean"/> + <xsd:element name="GetData" type="xsd:boolean"/> + <xsd:element name="InlineData" type="xsd:boolean"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObjectResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetObjectResponse" type="tns:GetObjectResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="GetObjectResult"> + <xsd:complexContent> + <xsd:extension base="tns:Result"> + <xsd:sequence> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="Data" type="xsd:base64Binary" nillable="true"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="ETag" type="xsd:string"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:element name="GetObjectExtended"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="GetMetadata" type="xsd:boolean"/> + <xsd:element name="GetData" type="xsd:boolean"/> + <xsd:element name="InlineData" type="xsd:boolean"/> + <xsd:element name="ByteRangeStart" type="xsd:long" minOccurs="0"/> + <xsd:element name="ByteRangeEnd" type="xsd:long" minOccurs="0"/> + <xsd:element name="IfModifiedSince" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="IfUnmodifiedSince" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="IfMatch" type="xsd:string" minOccurs="0" maxOccurs="100"/> + <xsd:element name="IfNoneMatch" type="xsd:string" minOccurs="0" maxOccurs="100"/> + <xsd:element name="ReturnCompleteObjectOnConditionFailure" type="xsd:boolean" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObjectExtendedResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetObjectResponse" type="tns:GetObjectResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="PutObject"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="100"/> + <xsd:element name="ContentLength" type="xsd:long"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="StorageClass" type="tns:StorageClass" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="PutObjectResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="PutObjectResponse" type="tns:PutObjectResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="PutObjectResult"> + <xsd:sequence> + <xsd:element name="ETag" type="xsd:string"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="PutObjectInline"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element minOccurs="0" maxOccurs="100" name="Metadata" type="tns:MetadataEntry"/> + <xsd:element name="Data" type="xsd:base64Binary"/> + <xsd:element name="ContentLength" type="xsd:long"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="StorageClass" type="tns:StorageClass" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="PutObjectInlineResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="PutObjectInlineResponse" type="tns:PutObjectResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="DeleteObject"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="DeleteObjectResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="DeleteObjectResponse" type="tns:Status"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="ListBucket"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Prefix" type="xsd:string" minOccurs="0"/> + <xsd:element name="Marker" type="xsd:string" minOccurs="0"/> + <xsd:element name="MaxKeys" type="xsd:int" minOccurs="0"/> + <xsd:element name="Delimiter" type="xsd:string" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="ListBucketResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="ListBucketResponse" type="tns:ListBucketResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="ListVersionsResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="ListVersionsResponse" type="tns:ListVersionsResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="ListEntry"> + <xsd:sequence> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="ETag" type="xsd:string"/> + <xsd:element name="Size" type="xsd:long"/> + <xsd:element name="Owner" type="tns:CanonicalUser" minOccurs="0"/> + <xsd:element name="StorageClass" type="tns:StorageClass"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="VersionEntry"> + <xsd:sequence> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="VersionId" type="xsd:string"/> + <xsd:element name="IsLatest" type="xsd:boolean"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="ETag" type="xsd:string"/> + <xsd:element name="Size" type="xsd:long"/> + <xsd:element name="Owner" type="tns:CanonicalUser" minOccurs="0"/> + <xsd:element name="StorageClass" type="tns:StorageClass"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="DeleteMarkerEntry"> + <xsd:sequence> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="VersionId" type="xsd:string"/> + <xsd:element name="IsLatest" type="xsd:boolean"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="Owner" type="tns:CanonicalUser" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="PrefixEntry"> + <xsd:sequence> + <xsd:element name="Prefix" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ListBucketResult"> + <xsd:sequence> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="Name" type="xsd:string"/> + <xsd:element name="Prefix" type="xsd:string"/> + <xsd:element name="Marker" type="xsd:string"/> + <xsd:element name="NextMarker" type="xsd:string" minOccurs="0"/> + <xsd:element name="MaxKeys" type="xsd:int"/> + <xsd:element name="Delimiter" type="xsd:string" minOccurs="0"/> + <xsd:element name="IsTruncated" type="xsd:boolean"/> + <xsd:element name="Contents" type="tns:ListEntry" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="CommonPrefixes" type="tns:PrefixEntry" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ListVersionsResult"> + <xsd:sequence> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="Name" type="xsd:string"/> + <xsd:element name="Prefix" type="xsd:string"/> + <xsd:element name="KeyMarker" type="xsd:string"/> + <xsd:element name="VersionIdMarker" type="xsd:string"/> + <xsd:element name="NextKeyMarker" type="xsd:string" minOccurs="0"/> + <xsd:element name="NextVersionIdMarker" type="xsd:string" minOccurs="0"/> + <xsd:element name="MaxKeys" type="xsd:int"/> + <xsd:element name="Delimiter" type="xsd:string" minOccurs="0"/> + <xsd:element name="IsTruncated" type="xsd:boolean"/> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="Version" type="tns:VersionEntry"/> + <xsd:element name="DeleteMarker" type="tns:DeleteMarkerEntry"/> + </xsd:choice> + <xsd:element name="CommonPrefixes" type="tns:PrefixEntry" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="ListAllMyBuckets"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="ListAllMyBucketsResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="ListAllMyBucketsResponse" type="tns:ListAllMyBucketsResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="ListAllMyBucketsEntry"> + <xsd:sequence> + <xsd:element name="Name" type="xsd:string"/> + <xsd:element name="CreationDate" type="xsd:dateTime"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ListAllMyBucketsResult"> + <xsd:sequence> + <xsd:element name="Owner" type="tns:CanonicalUser"/> + <xsd:element name="Buckets" type="tns:ListAllMyBucketsList"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ListAllMyBucketsList"> + <xsd:sequence> + <xsd:element name="Bucket" type="tns:ListAllMyBucketsEntry" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="PostResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Location" type="xsd:anyURI"/> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="ETag" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:simpleType name="MetadataDirective"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="COPY"/> + <xsd:enumeration value="REPLACE"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:element name="CopyObject"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="SourceBucket" type="xsd:string"/> + <xsd:element name="SourceKey" type="xsd:string"/> + <xsd:element name="DestinationBucket" type="xsd:string"/> + <xsd:element name="DestinationKey" type="xsd:string"/> + <xsd:element name="MetadataDirective" type="tns:MetadataDirective" minOccurs="0"/> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="100"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="CopySourceIfModifiedSince" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="CopySourceIfUnmodifiedSince" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="CopySourceIfMatch" type="xsd:string" minOccurs="0" maxOccurs="100"/> + <xsd:element name="CopySourceIfNoneMatch" type="xsd:string" minOccurs="0" maxOccurs="100"/> + <xsd:element name="StorageClass" type="tns:StorageClass" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="CopyObjectResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="CopyObjectResult" type="tns:CopyObjectResult" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="CopyObjectResult"> + <xsd:sequence> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="ETag" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="RequestPaymentConfiguration"> + <xsd:sequence> + <xsd:element name="Payer" type="tns:Payer" minOccurs="1" maxOccurs="1"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:simpleType name="Payer"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="BucketOwner"/> + <xsd:enumeration value="Requester"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="VersioningConfiguration"> + <xsd:sequence> + <xsd:element name="Status" type="tns:VersioningStatus" minOccurs="0"/> + <xsd:element name="MfaDelete" type="tns:MfaDeleteStatus" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:simpleType name="MfaDeleteStatus"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="Enabled"/> + <xsd:enumeration value="Disabled"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="VersioningStatus"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="Enabled"/> + <xsd:enumeration value="Suspended"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="NotificationConfiguration"> + <xsd:sequence> + <xsd:element name="TopicConfiguration" minOccurs="0" maxOccurs="unbounded" type="tns:TopicConfiguration"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="TopicConfiguration"> + <xsd:sequence> + <xsd:element name="Topic" minOccurs="1" maxOccurs="1" type="xsd:string"/> + <xsd:element name="Event" minOccurs="1" maxOccurs="unbounded" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + +</xsd:schema>
\ No newline at end of file diff --git a/weed/s3api/README.txt b/weed/s3api/README.txt new file mode 100644 index 000000000..10a18ff4d --- /dev/null +++ b/weed/s3api/README.txt @@ -0,0 +1,7 @@ +see https://blog.aqwari.net/xml-schema-go/ + +1. go get aqwari.net/xml/cmd/xsdgen +2. xsdgen -o s3api_xsd_generated.go -pkg s3api AmazonS3.xsd + + + diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go new file mode 100644 index 000000000..af05d0a93 --- /dev/null +++ b/weed/s3api/s3api_bucket_handlers.go @@ -0,0 +1,177 @@ +package s3api + +import ( + "context" + "fmt" + "github.com/chrislusf/seaweedfs/weed/glog" + "github.com/chrislusf/seaweedfs/weed/pb/filer_pb" + "github.com/gorilla/mux" + "net/http" + "os" + "time" +) + +var ( + OS_UID = uint32(os.Getuid()) + OS_GID = uint32(os.Getgid()) +) + +func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Request) { + + var response ListAllMyBucketsResponse + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + request := &filer_pb.ListEntriesRequest{ + Directory: s3a.option.BucketsPath, + } + + glog.V(4).Infof("read directory: %v", request) + resp, err := client.ListEntries(context.Background(), request) + if err != nil { + return fmt.Errorf("list buckets: %v", err) + } + + var buckets []ListAllMyBucketsEntry + for _, entry := range resp.Entries { + if entry.IsDirectory { + buckets = append(buckets, ListAllMyBucketsEntry{ + Name: entry.Name, + CreationDate: time.Unix(entry.Attributes.Crtime, 0), + }) + } + } + + response = ListAllMyBucketsResponse{ + ListAllMyBucketsResponse: ListAllMyBucketsResult{ + Owner: CanonicalUser{ + ID: "", + DisplayName: "", + }, + Buckets: ListAllMyBucketsList{ + Bucket: buckets, + }, + }, + } + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeSuccessResponseXML(w, encodeResponse(response)) +} + +func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + bucket := vars["bucket"] + + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + request := &filer_pb.CreateEntryRequest{ + Directory: s3a.option.BucketsPath, + Entry: &filer_pb.Entry{ + Name: bucket, + IsDirectory: true, + Attributes: &filer_pb.FuseAttributes{ + Mtime: time.Now().Unix(), + Crtime: time.Now().Unix(), + FileMode: uint32(0777 | os.ModeDir), + Uid: OS_UID, + Gid: OS_GID, + }, + }, + } + + glog.V(1).Infof("create bucket: %v", request) + if _, err := client.CreateEntry(context.Background(), request); err != nil { + return fmt.Errorf("mkdir %s/%s: %v", s3a.option.BucketsPath, bucket, err) + } + + // lazily create collection + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeSuccessResponseEmpty(w) +} + +func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + bucket := vars["bucket"] + + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + ctx := context.Background() + + // delete collection + deleteCollectionRequest := &filer_pb.DeleteCollectionRequest{ + Collection: bucket, + } + + glog.V(1).Infof("delete collection: %v", deleteCollectionRequest) + if _, err := client.DeleteCollection(ctx, deleteCollectionRequest); err != nil { + return fmt.Errorf("delete collection %s: %v", bucket, err) + } + + // delete bucket metadata + request := &filer_pb.DeleteEntryRequest{ + Directory: s3a.option.BucketsPath, + Name: bucket, + IsDirectory: true, + IsDeleteData: false, + IsRecursive: true, + } + + glog.V(1).Infof("delete bucket: %v", request) + if _, err := client.DeleteEntry(ctx, request); err != nil { + return fmt.Errorf("delete bucket %s/%s: %v", s3a.option.BucketsPath, bucket, err) + } + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeResponse(w, http.StatusNoContent, nil, mimeNone) +} + +func (s3a *S3ApiServer) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + bucket := vars["bucket"] + + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + request := &filer_pb.LookupDirectoryEntryRequest{ + Directory: s3a.option.BucketsPath, + Name: bucket, + } + + glog.V(1).Infof("lookup bucket: %v", request) + if _, err := client.LookupDirectoryEntry(context.Background(), request); err != nil { + return fmt.Errorf("lookup bucket %s/%s: %v", s3a.option.BucketsPath, bucket, err) + } + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrNoSuchBucket, r.URL) + return + } + + writeSuccessResponseEmpty(w) +} diff --git a/weed/s3api/s3api_errors.go b/weed/s3api/s3api_errors.go new file mode 100644 index 000000000..771b1dd82 --- /dev/null +++ b/weed/s3api/s3api_errors.go @@ -0,0 +1,88 @@ +package s3api + +import ( + "encoding/xml" + "net/http" +) + +// APIError structure +type APIError struct { + Code string + Description string + HTTPStatusCode int +} + +// RESTErrorResponse - error response format +type RESTErrorResponse struct { + XMLName xml.Name `xml:"Error" json:"-"` + Code string `xml:"Code" json:"Code"` + Message string `xml:"Message" json:"Message"` + Resource string `xml:"Resource" json:"Resource"` + RequestID string `xml:"RequestId" json:"RequestId"` +} + +// ErrorCode type of error status. +type ErrorCode int + +// Error codes, see full list at http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html +const ( + ErrNone ErrorCode = iota + ErrMethodNotAllowed + ErrBucketNotEmpty + ErrBucketAlreadyExists + ErrBucketAlreadyOwnedByYou + ErrNoSuchBucket + ErrInvalidBucketName + ErrInvalidDigest + ErrInternalError +) + +// error code to APIError structure, these fields carry respective +// descriptions for all the error responses. +var errorCodeResponse = map[ErrorCode]APIError{ + ErrMethodNotAllowed: { + Code: "MethodNotAllowed", + Description: "The specified method is not allowed against this resource.", + HTTPStatusCode: http.StatusMethodNotAllowed, + }, + ErrBucketNotEmpty: { + Code: "BucketNotEmpty", + Description: "The bucket you tried to delete is not empty", + HTTPStatusCode: http.StatusConflict, + }, + ErrBucketAlreadyExists: { + Code: "BucketAlreadyExists", + Description: "The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.", + HTTPStatusCode: http.StatusConflict, + }, + ErrBucketAlreadyOwnedByYou: { + Code: "BucketAlreadyOwnedByYou", + Description: "Your previous request to create the named bucket succeeded and you already own it.", + HTTPStatusCode: http.StatusConflict, + }, + ErrInvalidBucketName: { + Code: "InvalidBucketName", + Description: "The specified bucket is not valid.", + HTTPStatusCode: http.StatusBadRequest, + }, + ErrInvalidDigest: { + Code: "InvalidDigest", + Description: "The Content-Md5 you specified is not valid.", + HTTPStatusCode: http.StatusBadRequest, + }, + ErrNoSuchBucket: { + Code: "NoSuchBucket", + Description: "The specified bucket does not exist", + HTTPStatusCode: http.StatusNotFound, + }, + ErrInternalError: { + Code: "InternalError", + Description: "We encountered an internal error, please try again.", + HTTPStatusCode: http.StatusInternalServerError, + }, +} + +// getAPIError provides API Error for input API error code. +func getAPIError(code ErrorCode) APIError { + return errorCodeResponse[code] +} diff --git a/weed/s3api/s3api_handlers.go b/weed/s3api/s3api_handlers.go new file mode 100644 index 000000000..ab1fc7038 --- /dev/null +++ b/weed/s3api/s3api_handlers.go @@ -0,0 +1,100 @@ +package s3api + +import ( + "bytes" + "encoding/base64" + "encoding/xml" + "fmt" + "github.com/chrislusf/seaweedfs/weed/pb/filer_pb" + "github.com/chrislusf/seaweedfs/weed/util" + "net/http" + "net/url" + "time" +) + +type mimeType string + +const ( + mimeNone mimeType = "" + mimeJSON mimeType = "application/json" + mimeXML mimeType = "application/xml" +) + +func setCommonHeaders(w http.ResponseWriter) { + w.Header().Set("x-amz-request-id", fmt.Sprintf("%d", time.Now().UnixNano())) + w.Header().Set("Accept-Ranges", "bytes") +} + +// Encodes the response headers into XML format. +func encodeResponse(response interface{}) []byte { + var bytesBuffer bytes.Buffer + bytesBuffer.WriteString(xml.Header) + e := xml.NewEncoder(&bytesBuffer) + e.Encode(response) + return bytesBuffer.Bytes() +} + +func (s3a *S3ApiServer) withFilerClient(fn func(filer_pb.SeaweedFilerClient) error) error { + + grpcConnection, err := util.GrpcDial(s3a.option.FilerGrpcAddress) + if err != nil { + return fmt.Errorf("fail to dial %s: %v", s3a.option.FilerGrpcAddress, err) + } + defer grpcConnection.Close() + + client := filer_pb.NewSeaweedFilerClient(grpcConnection) + + return fn(client) +} + +// If none of the http routes match respond with MethodNotAllowed +func notFoundHandler(w http.ResponseWriter, r *http.Request) { + writeErrorResponse(w, ErrMethodNotAllowed, r.URL) +} + +func writeErrorResponse(w http.ResponseWriter, errorCode ErrorCode, reqURL *url.URL) { + apiError := getAPIError(errorCode) + errorResponse := getRESTErrorResponse(apiError, reqURL.Path) + encodedErrorResponse := encodeResponse(errorResponse) + writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeXML) +} + +func getRESTErrorResponse(err APIError, resource string) RESTErrorResponse { + return RESTErrorResponse{ + Code: err.Code, + Message: err.Description, + Resource: resource, + RequestID: fmt.Sprintf("%d", time.Now().UnixNano()), + } +} + +func writeResponse(w http.ResponseWriter, statusCode int, response []byte, mType mimeType) { + setCommonHeaders(w) + if mType != mimeNone { + w.Header().Set("Content-Type", string(mType)) + } + w.WriteHeader(statusCode) + if response != nil { + w.Write(response) + w.(http.Flusher).Flush() + } +} + +func writeSuccessResponseXML(w http.ResponseWriter, response []byte) { + writeResponse(w, http.StatusOK, response, mimeXML) +} + +func writeSuccessResponseEmpty(w http.ResponseWriter) { + writeResponse(w, http.StatusOK, nil, mimeNone) +} + +func validateContentMd5(h http.Header) ([]byte, error) { + md5B64, ok := h["Content-Md5"] + if ok { + if md5B64[0] == "" { + return nil, fmt.Errorf("Content-Md5 header set to empty value") + } + return base64.StdEncoding.DecodeString(md5B64[0]) + } + return []byte{}, nil +} diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go new file mode 100644 index 000000000..6c1895cbc --- /dev/null +++ b/weed/s3api/s3api_object_handlers.go @@ -0,0 +1,163 @@ +package s3api + +import ( + "encoding/json" + "fmt" + "github.com/chrislusf/seaweedfs/weed/glog" + "github.com/gorilla/mux" + "io/ioutil" + "net/http" + "io" +) + +var ( + client *http.Client +) + +func init() { + client = &http.Client{Transport: &http.Transport{ + MaxIdleConnsPerHost: 1024, + }} +} + +type UploadResult struct { + Name string `json:"name,omitempty"` + Size uint32 `json:"size,omitempty"` + Error string `json:"error,omitempty"` +} + +func (s3a *S3ApiServer) PutObjectHandler(w http.ResponseWriter, r *http.Request) { + + // http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html + + vars := mux.Vars(r) + bucket := vars["bucket"] + object := vars["object"] + + _, err := validateContentMd5(r.Header) + if err != nil { + writeErrorResponse(w, ErrInvalidDigest, r.URL) + return + } + + uploadUrl := fmt.Sprintf("http://%s%s/%s/%s?collection=%s", + s3a.option.Filer, s3a.option.BucketsPath, bucket, object, bucket) + proxyReq, err := http.NewRequest("PUT", uploadUrl, r.Body) + + if err != nil { + glog.Errorf("NewRequest %s: %v", uploadUrl, err) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + proxyReq.Header.Set("Host", s3a.option.Filer) + proxyReq.Header.Set("X-Forwarded-For", r.RemoteAddr) + + for header, values := range r.Header { + for _, value := range values { + proxyReq.Header.Add(header, value) + } + } + + resp, postErr := client.Do(proxyReq) + + if postErr != nil { + glog.Errorf("post to filer: %v", postErr) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + defer resp.Body.Close() + + resp_body, ra_err := ioutil.ReadAll(resp.Body) + if ra_err != nil { + glog.Errorf("upload to filer response read: %v", ra_err) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + var ret UploadResult + unmarshal_err := json.Unmarshal(resp_body, &ret) + if unmarshal_err != nil { + glog.Errorf("failing to read upload to %s : %v", uploadUrl, string(resp_body)) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + if ret.Error != "" { + glog.Errorf("upload to filer error: %v", ret.Error) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeSuccessResponseEmpty(w) +} + +func (s3a *S3ApiServer) GetObjectHandler(w http.ResponseWriter, r *http.Request) { + + destUrl := fmt.Sprintf("http://%s%s%s", + s3a.option.Filer, s3a.option.BucketsPath, r.RequestURI) + + s3a.proxyToFiler(w, r, destUrl, passThroghResponse) + +} + +func (s3a *S3ApiServer) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { + + destUrl := fmt.Sprintf("http://%s%s%s", + s3a.option.Filer, s3a.option.BucketsPath, r.RequestURI) + + s3a.proxyToFiler(w, r, destUrl, passThroghResponse) + +} + +func (s3a *S3ApiServer) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) { + + destUrl := fmt.Sprintf("http://%s%s%s", + s3a.option.Filer, s3a.option.BucketsPath, r.RequestURI) + + s3a.proxyToFiler(w, r, destUrl, func(proxyResonse *http.Response, w http.ResponseWriter) { + for k, v := range proxyResonse.Header { + w.Header()[k] = v + } + w.WriteHeader(http.StatusNoContent) + }) + +} + +func (s3a *S3ApiServer) proxyToFiler(w http.ResponseWriter, r *http.Request, destUrl string, responseFn func(proxyResonse *http.Response, w http.ResponseWriter)) { + + glog.V(2).Infof("s3 proxying %s to %s", r.Method, destUrl) + + proxyReq, err := http.NewRequest(r.Method, destUrl, r.Body) + + if err != nil { + glog.Errorf("NewRequest %s: %v", destUrl, err) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + proxyReq.Header.Set("Host", s3a.option.Filer) + proxyReq.Header.Set("X-Forwarded-For", r.RemoteAddr) + + for header, values := range r.Header { + for _, value := range values { + proxyReq.Header.Add(header, value) + } + } + + resp, postErr := client.Do(proxyReq) + + if postErr != nil { + glog.Errorf("post to filer: %v", postErr) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + defer resp.Body.Close() + + responseFn(resp, w) +} +func passThroghResponse(proxyResonse *http.Response, w http.ResponseWriter) { + for k, v := range proxyResonse.Header { + w.Header()[k] = v + } + w.WriteHeader(proxyResonse.StatusCode) + io.Copy(w, proxyResonse.Body) +} diff --git a/weed/s3api/s3api_server.go b/weed/s3api/s3api_server.go new file mode 100644 index 000000000..a4bb6b32d --- /dev/null +++ b/weed/s3api/s3api_server.go @@ -0,0 +1,113 @@ +package s3api + +import ( + _ "github.com/chrislusf/seaweedfs/weed/filer2/cassandra" + _ "github.com/chrislusf/seaweedfs/weed/filer2/leveldb" + _ "github.com/chrislusf/seaweedfs/weed/filer2/memdb" + _ "github.com/chrislusf/seaweedfs/weed/filer2/mysql" + _ "github.com/chrislusf/seaweedfs/weed/filer2/postgres" + _ "github.com/chrislusf/seaweedfs/weed/filer2/redis" + "github.com/gorilla/mux" + "net/http" +) + +type S3ApiServerOption struct { + Filer string + FilerGrpcAddress string + DomainName string + BucketsPath string +} + +type S3ApiServer struct { + option *S3ApiServerOption +} + +func NewS3ApiServer(router *mux.Router, option *S3ApiServerOption) (s3ApiServer *S3ApiServer, err error) { + s3ApiServer = &S3ApiServer{ + option: option, + } + + s3ApiServer.registerRouter(router) + + return s3ApiServer, nil +} + +func (s3a *S3ApiServer) registerRouter(router *mux.Router) { + // API Router + apiRouter := router.PathPrefix("/").Subrouter() + var routers []*mux.Router + if s3a.option.DomainName != "" { + routers = append(routers, apiRouter.Host("{bucket:.+}." + s3a.option.DomainName).Subrouter()) + } + routers = append(routers, apiRouter.PathPrefix("/{bucket}").Subrouter()) + + for _, bucket := range routers { + + // PutObject + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectHandler) + // GetObject + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.GetObjectHandler) + // HeadObject + bucket.Methods("HEAD").Path("/{object:.+}").HandlerFunc(s3a.HeadObjectHandler) + // DeleteObject + bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(s3a.DeleteObjectHandler) + + // PutBucket + bucket.Methods("PUT").HandlerFunc(s3a.PutBucketHandler) + // DeleteBucket + bucket.Methods("DELETE").HandlerFunc(s3a.DeleteBucketHandler) + // HeadBucket + bucket.Methods("HEAD").HandlerFunc(s3a.HeadBucketHandler) + + /* + // CopyObject + bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(s3a.CopyObjectHandler) + + // CopyObjectPart + bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(s3a.CopyObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") + // PutObjectPart + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") + // ListObjectPxarts + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.ListObjectPartsHandler).Queries("uploadId", "{uploadId:.*}") + // CompleteMultipartUpload + bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(s3a.CompleteMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") + // NewMultipartUpload + bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(s3a.NewMultipartUploadHandler).Queries("uploads", "") + // AbortMultipartUpload + bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(s3a.AbortMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") + + // ListMultipartUploads + bucket.Methods("GET").HandlerFunc(s3a.ListMultipartUploadsHandler).Queries("uploads", "") + // ListObjectsV2 + bucket.Methods("GET").HandlerFunc(s3a.ListObjectsV2Handler).Queries("list-type", "2") + // ListObjectsV1 (Legacy) + bucket.Methods("GET").HandlerFunc(s3a.ListObjectsV1Handler) + // DeleteMultipleObjects + bucket.Methods("POST").HandlerFunc(s3a.DeleteMultipleObjectsHandler).Queries("delete", "") + + // not implemented + // GetBucketLocation + bucket.Methods("GET").HandlerFunc(s3a.GetBucketLocationHandler).Queries("location", "") + // GetBucketPolicy + bucket.Methods("GET").HandlerFunc(s3a.GetBucketPolicyHandler).Queries("policy", "") + // GetObjectACL + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.GetObjectACLHandler).Queries("acl", "") + // GetBucketACL + bucket.Methods("GET").HandlerFunc(s3a.GetBucketACLHandler).Queries("acl", "") + // PutBucketPolicy + bucket.Methods("PUT").HandlerFunc(s3a.PutBucketPolicyHandler).Queries("policy", "") + // DeleteBucketPolicy + bucket.Methods("DELETE").HandlerFunc(s3a.DeleteBucketPolicyHandler).Queries("policy", "") + // PostPolicy + bucket.Methods("POST").HeadersRegexp("Content-Type", "multipart/form-data*").HandlerFunc(s3a.PostPolicyBucketHandler) + */ + + } + + // ListBuckets + apiRouter.Methods("GET").Path("/").HandlerFunc(s3a.ListBucketsHandler) + + // NotFound + apiRouter.NotFoundHandler = http.HandlerFunc(notFoundHandler) + +} diff --git a/weed/s3api/s3api_xsd_generated.go b/weed/s3api/s3api_xsd_generated.go new file mode 100644 index 000000000..915b74ec4 --- /dev/null +++ b/weed/s3api/s3api_xsd_generated.go @@ -0,0 +1,1002 @@ +package s3api + +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 { + 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"` + Status Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Status"` +} + +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"` + DeleteMarker DeleteMarkerEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteMarker"` + 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 []byte((time.Time)(t).Format("2006-01-02T15:04:05.999999999")), nil +} +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 +} |
