From 38f829842abdb522b88504e859bce2078111a9a1 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 23 Jan 2018 10:50:50 +0000 Subject: [PATCH] s3: fix server side copy and set modtime on files with + in - fixes #2001 This was broken in 64ea94c1a4e9d7a104b393a17d2e883593e20809 when putting a work-around for Digital Ocean. PathEscape has now been adjusted so it works with both providers. --- backend/s3/s3.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/s3/s3.go b/backend/s3/s3.go index 201e6a2b1..0aa409172 100644 --- a/backend/s3/s3.go +++ b/backend/s3/s3.go @@ -773,6 +773,12 @@ func (f *Fs) Precision() time.Duration { return time.Nanosecond } +// pathEscape escapes s as for a URL path. It uses rest.URLPathEscape +// but also escapes '+' for S3 and Digital Ocean spaces compatibility +func pathEscape(s string) string { + return strings.Replace(rest.URLPathEscape(s), "+", "%2B", -1) +} + // Copy src to this remote using server side copy operations. // // This is stored with the remote path given @@ -794,7 +800,7 @@ func (f *Fs) Copy(src fs.Object, remote string) (fs.Object, error) { } srcFs := srcObj.fs key := f.root + remote - source := rest.URLPathEscape(srcFs.bucket + "/" + srcFs.root + srcObj.remote) + source := pathEscape(srcFs.bucket + "/" + srcFs.root + srcObj.remote) req := s3.CopyObjectInput{ Bucket: &f.bucket, Key: &key, @@ -955,7 +961,7 @@ func (o *Object) SetModTime(modTime time.Time) error { ACL: &o.fs.acl, Key: &key, ContentType: &mimeType, - CopySource: aws.String(rest.URLPathEscape(sourceKey)), + CopySource: aws.String(pathEscape(sourceKey)), Metadata: o.meta, MetadataDirective: &directive, }