s3: fix server side copy and set modtime on files with + in - fixes #2001

This was broken in 64ea94c1a4 when
putting a work-around for Digital Ocean.  PathEscape has now been
adjusted so it works with both providers.
This commit is contained in:
Nick Craig-Wood 2018-01-23 10:50:50 +00:00
parent f9806848fe
commit 38f829842a

View file

@ -773,6 +773,12 @@ func (f *Fs) Precision() time.Duration {
return time.Nanosecond 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. // Copy src to this remote using server side copy operations.
// //
// This is stored with the remote path given // 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 srcFs := srcObj.fs
key := f.root + remote key := f.root + remote
source := rest.URLPathEscape(srcFs.bucket + "/" + srcFs.root + srcObj.remote) source := pathEscape(srcFs.bucket + "/" + srcFs.root + srcObj.remote)
req := s3.CopyObjectInput{ req := s3.CopyObjectInput{
Bucket: &f.bucket, Bucket: &f.bucket,
Key: &key, Key: &key,
@ -955,7 +961,7 @@ func (o *Object) SetModTime(modTime time.Time) error {
ACL: &o.fs.acl, ACL: &o.fs.acl,
Key: &key, Key: &key,
ContentType: &mimeType, ContentType: &mimeType,
CopySource: aws.String(rest.URLPathEscape(sourceKey)), CopySource: aws.String(pathEscape(sourceKey)),
Metadata: o.meta, Metadata: o.meta,
MetadataDirective: &directive, MetadataDirective: &directive,
} }