fix: move RFC 3339 time formatting to s3response

It is better if we let the s3response module handle the xml
formatting spec specifics, and let the backends not worry
about how to format the time fields. This should help to
prevent any future backend modifications or additions from
accidental incorrect time formatting.
This commit is contained in:
Ben McClelland
2024-08-26 21:08:24 -07:00
parent e065c86e62
commit ee202b76f3
7 changed files with 71 additions and 26 deletions
+4 -4
View File
@@ -559,7 +559,7 @@ Pager:
objects = append(objects, s3response.Object{
ETag: (*string)(v.Properties.ETag),
Key: v.Name,
LastModified: backend.GetStringPtr(v.Properties.LastModified.UTC().Format(backend.RFC3339TimeFormat)),
LastModified: v.Properties.LastModified,
Size: v.Properties.ContentLength,
StorageClass: types.ObjectStorageClass(*v.Properties.AccessTier),
})
@@ -620,7 +620,7 @@ Pager:
objects = append(objects, s3response.Object{
ETag: (*string)(v.Properties.ETag),
Key: v.Name,
LastModified: backend.GetStringPtr(v.Properties.LastModified.UTC().Format(backend.RFC3339TimeFormat)),
LastModified: v.Properties.LastModified,
Size: v.Properties.ContentLength,
StorageClass: types.ObjectStorageClass(*v.Properties.AccessTier),
})
@@ -868,7 +868,7 @@ func (az *Azure) ListParts(ctx context.Context, input *s3.ListPartsInput) (s3res
Size: *el.Size,
ETag: *el.Name,
PartNumber: partNumber,
LastModified: time.Now().Format(backend.RFC3339TimeFormat),
LastModified: time.Now(),
})
if len(parts) >= int(maxParts) {
nextPartNumberMarker = partNumber
@@ -923,7 +923,7 @@ func (az *Azure) ListMultipartUploads(ctx context.Context, input *s3.ListMultipa
}
uploads = append(uploads, s3response.Upload{
Key: *el.Name,
Initiated: el.Properties.CreationTime.Format(backend.RFC3339TimeFormat),
Initiated: *el.Properties.CreationTime,
})
}
}
-5
View File
@@ -30,11 +30,6 @@ import (
"github.com/versity/versitygw/s3response"
)
var (
// RFC3339TimeFormat RFC3339 time format
RFC3339TimeFormat = "2006-01-02T15:04:05.999Z"
)
func IsValidBucketName(name string) bool { return true }
type ByBucketName []s3response.ListAllMyBucketsEntry
+6 -6
View File
@@ -943,7 +943,7 @@ func (p *Posix) ListMultipartUploads(_ context.Context, mpu *s3.ListMultipartUpl
uploads = append(uploads, s3response.Upload{
Key: objectName,
UploadID: uploadID,
Initiated: fi.ModTime().Format(backend.RFC3339TimeFormat),
Initiated: fi.ModTime(),
})
}
}
@@ -1088,7 +1088,7 @@ func (p *Posix) ListParts(_ context.Context, input *s3.ListPartsInput) (s3respon
parts = append(parts, s3response.Part{
PartNumber: pn,
ETag: etag,
LastModified: fi.ModTime().Format(backend.RFC3339TimeFormat),
LastModified: fi.ModTime(),
Size: fi.Size(),
})
}
@@ -2155,12 +2155,12 @@ func (p *Posix) fileToObj(bucket string) backend.GetObjFunc {
}
size := int64(0)
mDate := fi.ModTime().UTC().Format(backend.RFC3339TimeFormat)
mtime := fi.ModTime()
return s3response.Object{
ETag: &etag,
Key: &path,
LastModified: &mDate,
LastModified: &mtime,
Size: &size,
}, nil
}
@@ -2187,12 +2187,12 @@ func (p *Posix) fileToObj(bucket string) backend.GetObjFunc {
}
size := fi.Size()
mDate := fi.ModTime().UTC().Format(backend.RFC3339TimeFormat)
mtime := fi.ModTime()
return s3response.Object{
ETag: &etag,
Key: &path,
LastModified: &mDate,
LastModified: &mtime,
Size: &size,
}, nil
}
+3 -4
View File
@@ -204,7 +204,7 @@ func (s *S3Proxy) ListMultipartUploads(ctx context.Context, input *s3.ListMultip
DisplayName: *u.Owner.DisplayName,
},
StorageClass: string(u.StorageClass),
Initiated: u.Initiated.Format(backend.RFC3339TimeFormat),
Initiated: *u.Initiated,
})
}
@@ -241,7 +241,7 @@ func (s *S3Proxy) ListParts(ctx context.Context, input *s3.ListPartsInput) (s3re
for _, p := range output.Parts {
parts = append(parts, s3response.Part{
PartNumber: int(*p.PartNumber),
LastModified: p.LastModified.Format(backend.RFC3339TimeFormat),
LastModified: *p.LastModified,
ETag: *p.ETag,
Size: *p.Size,
})
@@ -776,11 +776,10 @@ func convertObjects(objs []types.Object) []s3response.Object {
result := make([]s3response.Object, len(objs))
for _, obj := range objs {
lastModified := obj.LastModified.UTC().Format(backend.RFC3339TimeFormat)
result = append(result, s3response.Object{
ETag: obj.ETag,
Key: obj.Key,
LastModified: &lastModified,
LastModified: obj.LastModified,
Owner: obj.Owner,
Size: obj.Size,
RestoreStatus: obj.RestoreStatus,
+4 -2
View File
@@ -858,11 +858,12 @@ func (s *ScoutFS) fileToObj(bucket string) backend.GetObjFunc {
}
key := path + "/"
mtime := fi.ModTime()
return s3response.Object{
ETag: &etag,
Key: &key,
LastModified: backend.GetStringPtr(fi.ModTime().UTC().Format(backend.RFC3339TimeFormat)),
LastModified: &mtime,
StorageClass: types.ObjectStorageClassStandard,
}, nil
}
@@ -905,11 +906,12 @@ func (s *ScoutFS) fileToObj(bucket string) backend.GetObjFunc {
}
size := fi.Size()
mtime := fi.ModTime()
return s3response.Object{
ETag: &etag,
Key: &path,
LastModified: backend.GetStringPtr(fi.ModTime().UTC().Format(backend.RFC3339TimeFormat)),
LastModified: &mtime,
Size: &size,
StorageClass: sc,
}, nil
+4 -2
View File
@@ -44,11 +44,12 @@ func getObj(path string, d fs.DirEntry) (s3response.Object, error) {
if err != nil {
return s3response.Object{}, fmt.Errorf("get fileinfo: %w", err)
}
mtime := fi.ModTime()
return s3response.Object{
ETag: &etag,
Key: &path,
LastModified: backend.GetStringPtr(fi.ModTime().UTC().Format(backend.RFC3339TimeFormat)),
LastModified: &mtime,
}, nil
}
@@ -60,11 +61,12 @@ func getObj(path string, d fs.DirEntry) (s3response.Object, error) {
}
size := fi.Size()
mtime := fi.ModTime()
return s3response.Object{
ETag: &etag,
Key: &path,
LastModified: backend.GetStringPtr(fi.ModTime().UTC().Format(backend.RFC3339TimeFormat)),
LastModified: &mtime,
Size: &size,
}, nil
}
+50 -3
View File
@@ -21,14 +21,30 @@ import (
"github.com/aws/aws-sdk-go-v2/service/s3/types"
)
const RFC3339TimeFormat = "2006-01-02T15:04:05.999Z"
// Part describes part metadata.
type Part struct {
PartNumber int
LastModified string
LastModified time.Time
ETag string
Size int64
}
func (p Part) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
type Alias Part
aux := &struct {
LastModified string `xml:"LastModified"`
*Alias
}{
Alias: (*Alias)(&p),
}
aux.LastModified = p.LastModified.Format(RFC3339TimeFormat)
return e.EncodeElement(aux, start)
}
// ListPartsResponse - s3 api list parts response.
type ListPartsResult struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListPartsResult" json:"-"`
@@ -124,13 +140,30 @@ type ListObjectsV2Result struct {
type Object struct {
ETag *string
Key *string
LastModified *string
LastModified *time.Time
Owner *types.Owner
RestoreStatus *types.RestoreStatus
Size *int64
StorageClass types.ObjectStorageClass
}
func (o Object) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
type Alias Object
aux := &struct {
LastModified *string `xml:"LastModified,omitempty"`
*Alias
}{
Alias: (*Alias)(&o),
}
if o.LastModified != nil {
formattedTime := o.LastModified.Format(RFC3339TimeFormat)
aux.LastModified = &formattedTime
}
return e.EncodeElement(aux, start)
}
// Upload describes in progress multipart upload
type Upload struct {
Key string
@@ -138,7 +171,21 @@ type Upload struct {
Initiator Initiator
Owner Owner
StorageClass string
Initiated string
Initiated time.Time
}
func (u Upload) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
type Alias Upload
aux := &struct {
Initiated string `xml:"Initiated"`
*Alias
}{
Alias: (*Alias)(&u),
}
aux.Initiated = u.Initiated.Format(RFC3339TimeFormat)
return e.EncodeElement(aux, start)
}
// CommonPrefix ListObjectsResponse common prefixes (directory abstraction)