frostfs-s3-gw/api/handler/response.go

220 lines
7.4 KiB
Go

package handler
import (
"encoding/xml"
"fmt"
)
// ListBucketsResponse -- format for list buckets response.
type ListBucketsResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResult" json:"-"`
Owner Owner
// Container for one or more buckets.
Buckets struct {
Buckets []Bucket `xml:"Bucket"`
} // Buckets are nested
}
// ListObjectsV1Response -- format for ListObjectsV1 response.
type ListObjectsV1Response struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResult" json:"-"`
CommonPrefixes []CommonPrefix `xml:"CommonPrefixes"`
Contents []Object `xml:"Contents"`
Delimiter string `xml:"Delimiter,omitempty"`
EncodingType string `xml:"EncodingType,omitempty"`
IsTruncated bool `xml:"IsTruncated"`
Marker string `xml:"Marker"`
MaxKeys int `xml:"MaxKeys"`
Name string `xml:"Name"`
NextMarker string `xml:"NextMarker,omitempty"`
Prefix string `xml:"Prefix"`
}
// ListObjectsV2Response -- format for ListObjectsV2 response.
type ListObjectsV2Response struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResult" json:"-"`
CommonPrefixes []CommonPrefix `xml:"CommonPrefixes"`
Contents []Object `xml:"Contents"`
ContinuationToken string `xml:"ContinuationToken,omitempty"`
Delimiter string `xml:"Delimiter,omitempty"`
EncodingType string `xml:"EncodingType,omitempty"`
IsTruncated bool `xml:"IsTruncated"`
KeyCount int `xml:"KeyCount"`
MaxKeys int `xml:"MaxKeys"`
Name string `xml:"Name"`
NextContinuationToken string `xml:"NextContinuationToken,omitempty"`
Prefix string `xml:"Prefix"`
StartAfter string `xml:"StartAfter,omitempty"`
}
// Bucket container for bucket metadata.
type Bucket struct {
Name string
CreationDate string // time string of format "2006-01-02T15:04:05.000Z"
}
// AccessControlPolicy contains ACL.
type AccessControlPolicy struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlPolicy" json:"-"`
Owner Owner
AccessControlList []*Grant `xml:"AccessControlList>Grant"`
}
// Grant is container for Grantee data.
type Grant struct {
Grantee *Grantee
Permission AWSACL
}
// Grantee is info about access rights of some actor.
type Grantee struct {
XMLName xml.Name `xml:"Grantee"`
XMLNS string `xml:"xmlns:xsi,attr"`
ID string `xml:"ID,omitempty"`
DisplayName string `xml:"DisplayName,omitempty"`
EmailAddress string `xml:"EmailAddress,omitempty"`
URI string `xml:"URI,omitempty"`
Type GranteeType `xml:"xsi:type,attr"`
}
// NewGrantee creates new grantee using workaround
// https://github.com/golang/go/issues/9519#issuecomment-252196382
func NewGrantee(t GranteeType) *Grantee {
return &Grantee{
XMLNS: "http://www.w3.org/2001/XMLSchema-instance",
Type: t,
}
}
// Owner -- bucket owner/principal.
type Owner struct {
ID string
DisplayName string
}
// CommonPrefix container for prefix response in ListObjects's response.
type CommonPrefix struct {
Prefix string
}
// Object container for object metadata.
type Object struct {
Key string
LastModified string // time string of format "2006-01-02T15:04:05.000Z"
ETag string `xml:"ETag,omitempty"`
Size uint64
// Owner of the object.
Owner *Owner `xml:"Owner,omitempty"`
// Class of storage used to store the object.
StorageClass string `xml:"StorageClass,omitempty"`
}
// ObjectVersionResponse container for object version in the response of ListBucketObjectVersionsHandler.
type ObjectVersionResponse struct {
ETag string `xml:"ETag"`
IsLatest bool `xml:"IsLatest"`
Key string `xml:"Key"`
LastModified string `xml:"LastModified"`
Owner Owner `xml:"Owner"`
Size uint64 `xml:"Size"`
StorageClass string `xml:"StorageClass,omitempty"` // is empty!!
VersionID string `xml:"VersionId"`
}
// DeleteMarkerEntry container for deleted object's version in the response of ListBucketObjectVersionsHandler.
type DeleteMarkerEntry struct {
IsLatest bool `xml:"IsLatest"`
Key string `xml:"Key"`
LastModified string `xml:"LastModified"`
Owner Owner `xml:"Owner"`
VersionID string `xml:"VersionId"`
}
// StringMap is a map[string]string.
type StringMap map[string]string
// LocationResponse -- format for location response.
type LocationResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LocationConstraint" json:"-"`
Location string `xml:",chardata"`
}
// CopyObjectResponse container returns ETag and LastModified of the successfully copied object.
type CopyObjectResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopyObjectResult" json:"-"`
LastModified string // time string of format "2006-01-02T15:04:05.000Z"
ETag string // md5sum of the copied object.
}
// ListObjectsVersionsResponse is a response of ListBucketObjectVersionsHandler.
type ListObjectsVersionsResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListVersionsResult" json:"-"`
EncodingType string `xml:"EncodingType,omitempty"`
Name string `xml:"Name"`
IsTruncated bool `xml:"IsTruncated"`
KeyMarker string `xml:"KeyMarker"`
NextKeyMarker string `xml:"NextKeyMarker,omitempty"`
NextVersionIDMarker string `xml:"NextVersionIdMarker,omitempty"`
VersionIDMarker string `xml:"VersionIdMarker"`
DeleteMarker []DeleteMarkerEntry `xml:"DeleteMarker"`
Version []ObjectVersionResponse `xml:"Version"`
CommonPrefixes []CommonPrefix `xml:"CommonPrefixes"`
}
// VersioningConfiguration contains VersioningConfiguration XML representation.
type VersioningConfiguration struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersioningConfiguration"`
Status string `xml:"Status,omitempty"`
MfaDelete string `xml:"MfaDelete,omitempty"`
}
// Tagging contains tag set.
type Tagging struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Tagging"`
TagSet []Tag `xml:"TagSet>Tag"`
}
// PostResponse contains result of posting object.
type PostResponse struct {
Bucket string `xml:"Bucket"`
Key string `xml:"Key"`
ETag string `xml:"Etag"`
}
// Tag is an AWS key-value tag.
type Tag struct {
Key string
Value string
}
// MarshalXML -- StringMap marshals into XML.
func (s StringMap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
tokens := []xml.Token{start}
for key, value := range s {
t := xml.StartElement{}
t.Name = xml.Name{
Space: "",
Local: key,
}
tokens = append(tokens, t, xml.CharData(value), xml.EndElement{Name: t.Name})
}
tokens = append(tokens, xml.EndElement{
Name: start.Name,
})
for _, t := range tokens {
if err := e.EncodeToken(t); err != nil {
return fmt.Errorf("encode token: %w", err)
}
}
// flush to ensure tokens are written
return e.Flush()
}