s3: Use rest.URLEscape rather than url.QueryEscape.

The X-Amz-Copy-Source takes a path. url.QueryEscape
escapes spaces with a plus sign while rest.URLEscape
(which mimics the url.PathEscape available from go 1.8)
uses '%20'

This works around an issue when copying objects with
spaces in their key on DigitalOcean Spaces.
This commit is contained in:
Andrew Starr-Bochicchio 2017-12-22 16:27:19 -05:00 committed by Nick Craig-Wood
parent 4eac50eb83
commit 64ea94c1a4

View File

@ -17,7 +17,6 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"net/url"
"path" "path"
"regexp" "regexp"
"strings" "strings"
@ -36,6 +35,7 @@ import (
"github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager" "github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/ncw/rclone/fs" "github.com/ncw/rclone/fs"
"github.com/ncw/rclone/rest"
"github.com/ncw/swift" "github.com/ncw/swift"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -786,7 +786,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 := url.QueryEscape(srcFs.bucket + "/" + srcFs.root + srcObj.remote) source := rest.URLEscape(srcFs.bucket + "/" + srcFs.root + srcObj.remote)
req := s3.CopyObjectInput{ req := s3.CopyObjectInput{
Bucket: &f.bucket, Bucket: &f.bucket,
Key: &key, Key: &key,
@ -935,7 +935,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(url.QueryEscape(sourceKey)), CopySource: aws.String(rest.URLEscape(sourceKey)),
Metadata: o.meta, Metadata: o.meta,
MetadataDirective: &directive, MetadataDirective: &directive,
} }