mirror of
https://github.com/rclone/rclone.git
synced 2024-11-26 10:25:03 +01:00
s3: change metadata storage to normal map with lowercase keys
This commit is contained in:
parent
776a083892
commit
a692bd2cd4
@ -2072,14 +2072,14 @@ type Object struct {
|
|||||||
//
|
//
|
||||||
// List will read everything but meta & mimeType - to fill
|
// List will read everything but meta & mimeType - to fill
|
||||||
// that in you need to call readMetaData
|
// that in you need to call readMetaData
|
||||||
fs *Fs // what this object is part of
|
fs *Fs // what this object is part of
|
||||||
remote string // The remote path
|
remote string // The remote path
|
||||||
md5 string // md5sum of the object
|
md5 string // md5sum of the object
|
||||||
bytes int64 // size of the object
|
bytes int64 // size of the object
|
||||||
lastModified time.Time // Last modified
|
lastModified time.Time // Last modified
|
||||||
meta map[string]*string // The object metadata if known - may be nil
|
meta map[string]string // The object metadata if known - may be nil - with lower case keys
|
||||||
mimeType string // MimeType of object - may be ""
|
mimeType string // MimeType of object - may be ""
|
||||||
storageClass string // e.g. GLACIER
|
storageClass string // e.g. GLACIER
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
@ -3753,6 +3753,27 @@ func (o *Object) readMetaData(ctx context.Context) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert S3 metadata with pointers into a map[string]string
|
||||||
|
// while lowercasing the keys
|
||||||
|
func s3MetadataToMap(s3Meta map[string]*string) map[string]string {
|
||||||
|
meta := make(map[string]string, len(s3Meta))
|
||||||
|
for k, v := range s3Meta {
|
||||||
|
if v != nil {
|
||||||
|
meta[strings.ToLower(k)] = *v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return meta
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert our metadata back into S3 metadata
|
||||||
|
func mapToS3Metadata(meta map[string]string) map[string]*string {
|
||||||
|
s3Meta := make(map[string]*string, len(meta))
|
||||||
|
for k, v := range meta {
|
||||||
|
s3Meta[k] = aws.String(v)
|
||||||
|
}
|
||||||
|
return s3Meta
|
||||||
|
}
|
||||||
|
|
||||||
func (o *Object) setMetaData(etag *string, contentLength *int64, lastModified *time.Time, meta map[string]*string, mimeType *string, storageClass *string) {
|
func (o *Object) setMetaData(etag *string, contentLength *int64, lastModified *time.Time, meta map[string]*string, mimeType *string, storageClass *string) {
|
||||||
// Ignore missing Content-Length assuming it is 0
|
// Ignore missing Content-Length assuming it is 0
|
||||||
// Some versions of ceph do this due their apache proxies
|
// Some versions of ceph do this due their apache proxies
|
||||||
@ -3760,17 +3781,14 @@ func (o *Object) setMetaData(etag *string, contentLength *int64, lastModified *t
|
|||||||
o.bytes = *contentLength
|
o.bytes = *contentLength
|
||||||
}
|
}
|
||||||
o.setMD5FromEtag(aws.StringValue(etag))
|
o.setMD5FromEtag(aws.StringValue(etag))
|
||||||
o.meta = meta
|
o.meta = s3MetadataToMap(meta)
|
||||||
if o.meta == nil {
|
|
||||||
o.meta = map[string]*string{}
|
|
||||||
}
|
|
||||||
// Read MD5 from metadata if present
|
// Read MD5 from metadata if present
|
||||||
if md5sumBase64, ok := o.meta[metaMD5Hash]; ok {
|
if md5sumBase64, ok := o.meta[metaMD5Hash]; ok {
|
||||||
md5sumBytes, err := base64.StdEncoding.DecodeString(*md5sumBase64)
|
md5sumBytes, err := base64.StdEncoding.DecodeString(md5sumBase64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Debugf(o, "Failed to read md5sum from metadata %q: %v", *md5sumBase64, err)
|
fs.Debugf(o, "Failed to read md5sum from metadata %q: %v", md5sumBase64, err)
|
||||||
} else if len(md5sumBytes) != 16 {
|
} else if len(md5sumBytes) != 16 {
|
||||||
fs.Debugf(o, "Failed to read md5sum from metadata %q: wrong length", *md5sumBase64)
|
fs.Debugf(o, "Failed to read md5sum from metadata %q: wrong length", md5sumBase64)
|
||||||
} else {
|
} else {
|
||||||
o.md5 = hex.EncodeToString(md5sumBytes)
|
o.md5 = hex.EncodeToString(md5sumBytes)
|
||||||
}
|
}
|
||||||
@ -3800,11 +3818,11 @@ func (o *Object) ModTime(ctx context.Context) time.Time {
|
|||||||
}
|
}
|
||||||
// read mtime out of metadata if available
|
// read mtime out of metadata if available
|
||||||
d, ok := o.meta[metaMtime]
|
d, ok := o.meta[metaMtime]
|
||||||
if !ok || d == nil {
|
if !ok {
|
||||||
// fs.Debugf(o, "No metadata")
|
// fs.Debugf(o, "No metadata")
|
||||||
return o.lastModified
|
return o.lastModified
|
||||||
}
|
}
|
||||||
modTime, err := swift.FloatStringToTime(*d)
|
modTime, err := swift.FloatStringToTime(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Logf(o, "Failed to read mtime from object: %v", err)
|
fs.Logf(o, "Failed to read mtime from object: %v", err)
|
||||||
return o.lastModified
|
return o.lastModified
|
||||||
@ -3818,7 +3836,7 @@ func (o *Object) SetModTime(ctx context.Context, modTime time.Time) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
o.meta[metaMtime] = aws.String(swift.TimeToFloatString(modTime))
|
o.meta[metaMtime] = swift.TimeToFloatString(modTime)
|
||||||
|
|
||||||
// Can't update metadata here, so return this error to force a recopy
|
// Can't update metadata here, so return this error to force a recopy
|
||||||
if o.storageClass == "GLACIER" || o.storageClass == "DEEP_ARCHIVE" {
|
if o.storageClass == "GLACIER" || o.storageClass == "DEEP_ARCHIVE" {
|
||||||
@ -3829,7 +3847,7 @@ func (o *Object) SetModTime(ctx context.Context, modTime time.Time) error {
|
|||||||
bucket, bucketPath := o.split()
|
bucket, bucketPath := o.split()
|
||||||
req := s3.CopyObjectInput{
|
req := s3.CopyObjectInput{
|
||||||
ContentType: aws.String(fs.MimeType(ctx, o)), // Guess the content type
|
ContentType: aws.String(fs.MimeType(ctx, o)), // Guess the content type
|
||||||
Metadata: o.meta,
|
Metadata: mapToS3Metadata(o.meta),
|
||||||
MetadataDirective: aws.String(s3.MetadataDirectiveReplace), // replace metadata with that passed in
|
MetadataDirective: aws.String(s3.MetadataDirectiveReplace), // replace metadata with that passed in
|
||||||
}
|
}
|
||||||
if o.fs.opt.RequesterPays {
|
if o.fs.opt.RequesterPays {
|
||||||
@ -4423,7 +4441,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
|
|||||||
o.md5 = md5sumHex
|
o.md5 = md5sumHex
|
||||||
o.bytes = size
|
o.bytes = size
|
||||||
o.lastModified = time.Now()
|
o.lastModified = time.Now()
|
||||||
o.meta = req.Metadata
|
o.meta = s3MetadataToMap(req.Metadata)
|
||||||
o.mimeType = aws.StringValue(req.ContentType)
|
o.mimeType = aws.StringValue(req.ContentType)
|
||||||
o.storageClass = aws.StringValue(req.StorageClass)
|
o.storageClass = aws.StringValue(req.StorageClass)
|
||||||
// If we have done a single part PUT request then we can read these
|
// If we have done a single part PUT request then we can read these
|
||||||
|
Loading…
Reference in New Issue
Block a user