SaltwaterC edited this page Oct 14, 2012 · 2 revisions


S3 helper for changing the path / renaming of an existing S3 object.


s3.moveObject(source, destination, acl, [headers], callback)
  • 'source' - the source S3 Path. This must be an absolute path, containing the bucket name in the path itself. This path uses the path based addressing of the S3 API. For more information about bucket naming and different styles of object addressing, see the Bucket Name document.
  • 'destination' - the destination S3 Path.
  • 'acl' - the S3 Canned ACL.
  • 'headers' - optional argument. An object containing the HTTP headers you may want to pass to the PUT request, such as the x-amz-* metadata headers.
  • 'callback' - the callback that is executed when the processing finishes. It has a couple of arguments: error and result.
  • If there's an error, the callback receives the error argument as Error instance.
  • If the error argument is null, then the response argument contains the response.headers object as returned by the node.js core HTTPS client.

This helper does not re-upload the object. It uses the PUT Object - Copy method via the x-amz-copy-source HTTP header and the x-amz-metadata-directive HTTP header for copying the source metadata. Since there's no native object moving functionality in S3, this method basically is a wrapper for s3.copyObject() that contains an embedded call to s3.del() for the source path.

You need both read and write privileges for the source object in order to move it successfully aka delete the source object after the copy operation. Some limitations may apply due to s3.del(), as the DELETE operation is not confirmed by the S3 API. Per RFC 2616: "The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully.". Therefore, you may need to do garbage collection yourself.

The method may fail in a couple of key points:

  • the s3.copyObject() method fails or
  • the s3.del() method fails. In this case, the failure may be due to network conditions, but S3 may receive a successful DELETE request. Act accordingly. I won't take the (risky) decision to clean up the destination object as you may wind up, in edge cases, without both objects, the source, and the destination.

Obviously, the source bucket may be the same as the target bucket. This method deprecates the usage of s3.renameObject(). Even though it has a more complicated syntax for the source path, it brings the advantage of being bucket independent.

I won't keep them both in order to keep the API short and sweet. Bloating the API isn't always a happy decision. See how PHP got with 5000 functions under the same namespace.


s3.moveObject(s3.getBucket() + '/' + source, destination, false, {}, function (err, res) {

This piece of code may be used in order to replicate the behavior of s3.renameObject().