diff --git a/s3/s3.go b/s3/s3.go index dbeec6ef..05b1796a 100644 --- a/s3/s3.go +++ b/s3/s3.go @@ -331,9 +331,11 @@ func (b *Bucket) PutReaderHeader(path string, r io.Reader, length int64, customH } /* -Copy - copy objects inside bucket +copyObject - copy objects. +oldPath should begin with /. +newPath should not include the bucket name. */ -func (b *Bucket) Copy(oldPath, newPath string, perm ACL) error { +func (b *Bucket) copyObject(oldPath, newPath string, perm ACL) error { if !strings.HasPrefix(oldPath, "/") { oldPath = "/" + oldPath } @@ -343,7 +345,7 @@ func (b *Bucket) Copy(oldPath, newPath string, perm ACL) error { bucket: b.Name, path: newPath, headers: map[string][]string{ - "x-amz-copy-source": {amazonEscape("/" + b.Name + oldPath)}, + "x-amz-copy-source": {amazonEscape(oldPath)}, "x-amz-acl": {string(perm)}, }, } @@ -366,6 +368,26 @@ func (b *Bucket) Copy(oldPath, newPath string, perm ACL) error { panic("unreachable") } +/* +Copy - copy objects inside bucket +*/ +func (b *Bucket) Copy(oldPath, newPath string, perm ACL) error { + if !strings.HasPrefix(oldPath, "/") { + oldPath = "/" + oldPath + } + return b.copyObject("/" + b.Name + oldPath, newPath, perm) +} + +/* +CopyToAnotherBucket - copy objects from this bucket to another +*/ +func (b *Bucket) CopyToAnotherBucket(oldPath string, newBucket *Bucket, newPath string, perm ACL) error { + if !strings.HasPrefix(oldPath, "/") { + oldPath = "/" + oldPath + } + return newBucket.copyObject("/" + b.Name + oldPath, newPath, perm) +} + // Del removes an object from the S3 bucket. // // See http://goo.gl/APeTt for details. diff --git a/s3/s3_test.go b/s3/s3_test.go index 376c9470..beed0c28 100644 --- a/s3/s3_test.go +++ b/s3/s3_test.go @@ -290,6 +290,26 @@ func (s *S) TestCopy(c *C) { c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"}) } +func (s *S) TestCopyToAnotherBucket(c *C) { + testServer.Response(200, nil, "") + + b := s.s3.Bucket("bucket") + nb := s.s3.Bucket("new-bucket") + err := b.CopyToAnotherBucket( + "old/file", + nb, + "new/file", + s3.Private, + ) + c.Assert(err, IsNil) + + req := testServer.WaitRequest() + c.Assert(req.Method, Equals, "PUT") + c.Assert(req.URL.Path, Equals, "/new-bucket/new/file") + c.Assert(req.Header["X-Amz-Copy-Source"], DeepEquals, []string{"/bucket/old/file"}) + c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"}) +} + func (s *S) TestPlusInURL(c *C) { testServer.Response(200, nil, "")