Copying an object
You use the HTTP PUT method with the x-amz-copy-source
header to copy an object from one location to another. The source and target locations can be two different buckets within the same tenant, or they can be the same bucket. You can specify a name for the target object that is different from the name of the source object.
To copy an object, you need read permission for the bucket containing the source object or for the source object itself, and write permission for the target bucket.
By default, a copy operation copies the current version of the source object specified in the request. If versioning is enabled for the source bucket, you can use the versionId query parameter with the source object specification to copy a specific version of the object.
- If the version identified by the versionId parameter is a delete marker, HCP returns a 503 (Service Unavailable) status code.
- If the current version of the source object is a delete marker and you do not specify a version ID, HCP returns a 404 (Not Found) status code.
HCP does not copy version IDs with objects. The object created by a copy operation has its own version ID.
HCP also does not copy ACLs with objects. However, in the copy request, you can specify an ACL for the target object. To do this, you need to use ACL headers. You cannot use an ACL request body when copying an object. If the ACL you specify in a request to copy an object is invalid, HCP returns a 400 (Bad Request) or 501 (Not Implemented) status code and does not copy the object.
By default, HCP copies any custom metadata for the source object to the target object. However, in the copy request, you can specify replacement custom metadata to be used for the target object. To apply this custom metadata to the target object, you need to include the x-amz-metadata-directive
header with a value of REPLACE
in the copy request.
If you are an authenticated user, when you copy an object, you become the owner of the target object. If you are accessing the bucket anonymously, the target object has no owner.
In response to a request to copy an object, HCP returns an XML response body containing the ETag and last modification date of the target object.
Request line
Depending on whether the bucket name is included in the hostname in the S3 compatible request, a request to copy an object has either of these formats:
- With the bucket name included in the hostname:
PUT /target-object-name HTTP/1.1
- With the bucket name following the hostname:
PUT /target-bucket-name/target-object-name HTTP/1.1
Required headers
The next list describes the headers you can use in a request to copy an object.
Authorization
Specifies user credentials or requests anonymous access.
Content-Type
Specifies the Internet media type of the data being copied. Valid values are Internet media types (for example,
text/plain
,application/xml
, orimage/jpeg
).Date
Specifies the date and time when the request is being made according to the requester. Normally, this is the current date and time.
The date and time must always be specified using Greenwich Mean Time (GMT).
To specify the date and time, use this format:
DDD, dd MMM yyyy HH:mm:ss (+0000|GMT)
In this format:
DDD
The three-letter abbreviation for the day of the week, with an uppercase first letter (for example, Mon).
dd
The two-digit day of the month.
MMM
The three-letter abbreviation for the month, with an uppercase first letter (for example, Feb).
yyyy
The four-digit year.
HH
The hour on a 24-hour clock.
mm
The number of minutes.
ss
The number of seconds.
For example:
Thu, 23 Mar 2017 14:27:05 +0000
All S3 compatible requests must include either a
Date
header or anx-amz-date
header. If a request includes both headers, HCP uses the date and time in thex-amz-date
header.Host
Specifies the hostname for the request. The host name identifies either a tenant or a bucket.
For a tenant, use this format:
tenant-name.hcp-domain-name
For a bucket, use this format:
bucket-name.tenant-name.hcp-domain-name
x-amz-copy-source
Specifies the source bucket and object or object version, in this format:
/bucket-name/source-object-name[?versionId=source-object-version-id]
The initial forward slash (/) is required.
Valid values for source-object-version-id are the IDs of versions of the source object specified in the request.
The versionId query parameter is not case sensitive.
If you include the versionId query parameter in the
x-amz-copy-source
header with an invalid value while versioning is enabled, HCP returns a 404 (Not Found) status code and does not copy the object.If you include the versionId query parameter in the
x-amz-copy-source
header while versioning is disabled, the parameter is ignored, and the current version of the specified object is used as the source for the copy operation.x-amz-date
Specifies the date and time at which the request is being made according to the requester. Normally, this is the current date and time.
For the valid values for this header, see the description of the
Date
header above.
Optional headers
x-amz-acl
Adds a canned ACL to the bucket.
This header is used only to add a canned ACL to a bucket. If you’re using individual
x-amz-grant-
headers to add the ACL, thex-amz-acl
header is invalid.x-amz-copy-source-if-match
Specifies one or more values for comparison with the ETag of the specified source object or object version. If the ETag matches one of the specified values, HCP continues processing the request. If the ETag does not match any of the specified values, HCP returns a 412 (Precondition Failed) status code and does not copy the object.
To specify the values for this header, use this format:
"value"[, "value"]...
In this format, each value can be any string of one or more characters and must be enclosed in double quotation marks (").
Alternatively, you can specify a single asterisk (*) as the value for the
x-amz-copy-source-if-match
header. All ETags match an asterisk in anx-amz-copy-source-if-match
header.x-amz-copy-source-if-modified-since
Specifies a date and time, in Greenwich Mean Time (GMT), for comparison with the date and time the specified source object or object version was last modified. If the modification date and time is later than the specified date and time, HCP continues processing the request. If the modification date and time is equal to or earlier than the specified date and time, HCP returns a 412 (Precondition Failed) status code and does not copy the object.
To specify the date and time for this header, use one of these formats:
- DDD, dd MMM yyyy HH:mm:ss (+0000|GMT)
For example: Tue, 07 Feb 2017 14:27:05 +0000
- DDDD, dd-MMM-yyyy HH:mm:ss (+0000|GMT)
For example: Tuesday, 07-Feb-17 14:27:05 +0000
- DDD MMM d HH:mm:ss yyyy
For example: Tue Feb 7 14:27:05 2017
If the value specified by the x-amz-copy-source-if-modified-since header doesn’t conform to one of the formats shown above, the header is ignored.
- DDD, dd MMM yyyy HH:mm:ss (+0000|GMT)
x-amz-copy-source-if-none-match
Specifies one or more values for comparison with the ETag of the specified source object or object version. If the ETag doesn’t match any of the specified values, HCP continues processing the request. If the ETag matches any of the specified values, HCP returns a 412 (Precondition Failed) status code and does not copy the object.
To specify the values for this header, use this format:
"value"[, "value"]...
In this format, each value can be any string of one or more characters and must be enclosed in double quotation marks (").
Alternatively, you can specify a single asterisk (*) as the value for the
x-amz-copy-source-if-match
header. No ETags match an asterisk in anx-amz-copy-source-if-match
header.x-amz-copy-source-if-unmodified-since
Specifies a date and time, in Greenwich Mean Time (GMT), for comparison with the date and time the specified source object or object version was last modified. If the modification date and time is equal to or earlier than the specified date and time, HCP continues processing the request. If the modification date and time is later than the specified date and time, HCP returns a 412 (Precondition Failed) status code and does not copy the object.
For valid values for this header, see the description of the
x-amz-copy-source-if-modified-since
header above.x-amz-grant-full-control
Grants full control over the bucket to one or more specified grantees.
If you’re using a canned ACL to add an ACL to a bucket, the
x-amz-grant-full-control
header is invalid.x-amz-grant-read
Grants the browse and read data access permissions for the bucket to one or more specified grantees.
If you’re using a canned ACL to add an ACL to a bucket, the
x-amz-grant-read
header is invalid.x-amz-grant-read-acp
Grants the read ACL data access permission for the bucket to one or more specified grantees.
If you’re using a canned ACL to add an ACL to a bucket, the
x-amz-grant-read-acp
header is invalid.x-amz-grant-write
Grants the write and delete data access permissions for the bucket to one or more specified grantees.
If you’re using a canned ACL to add an ACL to a bucket, the
x-amz-grant-write
header is invalid.x-amz-grant-write-acp
Grants the write ACL data access permission for the bucket to one or more specified grantees.
If you’re using a canned ACL to add an ACL to a bucket, the
x-amz-grant-write-acp
header is invalid.x-amz-meta-
Adds custom metadata to the target object.
x-amz-metadata-directive
Tells HCP whether to use the custom metadata, if any, for the source object or object version as the custom metadata for the target object or to use the custom metadata, if any, specified in the copy request. Valid values are:
COPY
Use the custom metadata for the source object or object version.
REPLACE
Use the custom metadata specified in the copy request.
These values are case sensitive.
The default is COPY.
x-amz-server-side-encryption
Requests that the response headers include
x-amz-server-side-encryption
, which indicates whether objects stored in HCP are encrypted. The value of thex-amz-server-side-encryption
request header can be any character string.x-hcp-pretty-print
Optionally, requests that the XML response body be formatted for readability. Valid values are:
true
Format the XML response body for readability.
false
Do not apply any special formatting to the XML response body.
The default is false.
The values
true
andfalse
are not case sensitive.x-hcp-labelretentionhold
Specifies whether to place one or more labeled holds on the object and the associated labeled hold IDs. The values passed with this header are in a JSON format string containing one or more id and hold-value pairs.
id
Unique label name. The maximum label size is 64 characters.
hold
Either
true
orfalse
.
Examples
- Place two labeled holds on the object.
x-hcp-labelretentionhold [{"id":"LabelHold-1","hold":true}, {"id":"LabelHold-2","hold":true}]
- Remove a labeled hold from the object.
x-hcp-labelretentionhold [{"id":"LabelHold-2","hold":false}]
x-hcp-retention
Specifies the retention value for the object being stored. This value can be a fixed date, an offset, a retention class, or a special value.
x-hcp-retentionhold
Specifies whether the object is on hold. This value can be either
true
orfalse
.
Response headers
The list below describes the headers returned in response to a successful request to copy an object.
Content-Type
Specifies the Internet media type of the response body. For a request to copy an object, the value of this header is always
application/xml;charset=UTF-8
.Date
The date and time when HCP responded to the request, in Greenwich Mean Time (GMT). The date and time are returned in this format:
DDD dd MMM yyyy HH:mm:ss GMT
For example:
Fri, 18 Sep 2020 14:27:05 GMT
ETag
Specifies the ETag for the object.
ETags are useful for making object-level operations conditional based on the object content. Operations that can be made conditional are checking the existence of an object, copying an object, and retrieving an object.
Transfer-Encoding
Indicates that HCP could not determine the size of the response body before formulating the response. For a request to list the buckets you own, the value of this header is always
chunked
.x-amz-copy-source-version-id
Specifies the version ID of the source object. This header is returned only while versioning is enabled for the source bucket.
x-amz-server-side-encryption
Specifies whether objects stored in HCP are encrypted. Possible values are:
- If objects are encrypted,
AES256
- If objects are not encrypted,
None
This header is returned only if the request headers include
x-amz-server-side-encryption
.- If objects are encrypted,
x-amz-version-id
Specifies the version ID of the object. This header is returned only while versioning is enabled for the bucket.
Response body
HCP returns information about the target object that results from a successful copy request in an XML response body.
The next list describes the XML elements in the response body returned in response to a request to copy an object. The elements are listed in alphabetical order.
CopyObjectResult
Root element.
ETag
Child of the
CopyObjectResult
element.The
ETag
element specifies the ETag for the target object.LastModified
Child of the
CopyObjectResult
element.The
LastModified
element specifies the date and time when the target object was last modified, in Greenwich Mean Time (GMT). The date and time are expressed in this format:yyyy-MM-ddTHH:mm:ss.SSSZ
For example:
2020-02-18T19:46:03.856Z
Modifying an object means modifying its metadata. You cannot modify the content of an object.
Return codes
The table below describes HTTP status codes that can be returned in response to a request to copy an object.
Code | Meaning | Description |
200 | OK | HCP successfully copied the object. |
400 | Bad Request | Possible reasons include that an ACL grant header specifies an invalid grantee. |
403 | Forbidden |
Possible reasons include:
|
404 | Not Found |
One of these:
|
409 | Conflict |
One of these:
|
412 | Precondition Failed |
One of these:
|
413 | Request Entity Too Large | The source object you are trying to copy is too big for the amount of space left in the target bucket. |
500 | Internal Server Error |
An internal error occurred. If this error persists, contact your tenant administrator. |
501 | Not Implemented | The request includes the x-amz-acl header with an invalid value. |
503 | Service Unavailable |
Possible reasons include:
If this error persists, contact your tenant administrator. |
Example: Conditionally copying an object from one bucket to another
Here is a sample PUT request that conditionally copies the current version of an object named campaigns/GoGetEm.xls from the sales-mktg bucket to the finance bucket, where the target object that results from the copy operation is named mktg/campaign_GoGetEm_expenses.xls. The request is being made while versioning is enabled for both the source and target buckets.
For the purpose of this example, assume that mktg/campaign_GoGetEm_expenses.xls already exists in the target bucket with an ETag of 7ad452af1e2f61b33a865c4362be5921. The request directs HCP to perform the copy operation only if the ETag of the source object doesn't match the ETag of the most recent version of the target object.
Request with s3curl command line
./s3curl.pl --id=lgreen --copysrc=/sales-mktg/campaigns/GoGetEm.xls -- -k "https://finance.europe.hcp.example.com/mktg/campaign_GoGetEm_expenses.xls" -H "x-amz-copy-source-if-none-match:7ad452af1e2f61b33a865c4362be5921" -H "x-hcp-pretty-print: true"
Request headers
PUT /mktg/campaign_GoGetEm_expenses.xls HTTP/1.1 Host: finance.europe.hcp.example.com Date: Fri, 07 February 2020 17:19:26 +0000 Authorization: AWS bGdyZWVu:oBVRqkcjktavqo6z1m+chHhRmmI= x-amz-copy-source: /sales-mktg/campaigns/GoGetEm.xls x-amz-copy-source-if-none-match:7ad452af1e2f61b33a865c4362be5921 x-hcp-pretty-print: true
Response headers
HTTP/1.1 200 OK Date: Fri, 07 February 2020 17:19:26 GMT x-amz-version-id: 87288825190337 ETag: "6ed7faad1e0661c03ad65a4317d4a94c" x-amz-copy-source-version-id: 87388217426433 Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
Response body
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <CopyObjectResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LastModified>2017-02-23T17:19:26.402Z</LastModified> <ETag>"6ed7faad1e0661c03ad65a4317d4a94c"</ETag> </CopyObjectResult>
Example: Recovering an old version of an object
Here is a sample PUT request that copies an old version of an object to the same object, thereby creating a new current version from the old version. The object in question is named AcctgBestPractices.doc and is in the finance bucket. The version ID of the version being copied is 87288808614529. The request is being made while versioning is enabled for the bucket.
Request with s3curl command line
./s3curl.pl --id=lgreen --copysrc=/finance/ AcctgBestPractices.doc?versionId=87288808614529 -- -k "https://finance.europe.hcp.example.com/AcctgBestPractices.doc" -H "x-hcp-pretty-print: true"
Request headers
PUT /AcctgBestPractices.doc HTTP/1.1 Host: finance.europe.hcp.example.com Date: Fri, 07 February 2020 17:19:26 +0000 Authorization: AWS bGdyZWVu:AZ/GOgJJXFh7K1pr59bIlwRUrc0= x-amz-copy-source: /finance/AcctgBestPractices.doc?versionId=87288808614529 x-hcp-pretty-print: true
Response headers
HTTP/1.1 200 OK Date: Fri, 07 February 2020 17:19:26 GMT x-amz-version-id: 87288815588289 ETag: "764f38262c6e581f678e1ac9b0211ae8" x-amz-copy-source-version-id: 87288808614529 Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
Response body
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <CopyObjectResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LastModified>2017-02-23T17:19:26.000Z</LastModified> <ETag>"764f38262c6e581f678e1ac9b0211ae8"</ETag> </CopyObjectResult>
Example: Replacing custom metadata for an existing object
Here is a sample PUT request that replaces the existing custom metadata for the object named hum_res/budget_proposals/BudgProp-2020 in the finance bucket with new custom metadata. The request is being made while versioning is disabled for the bucket, so the custom metadata is replaced on the current version of the object. No new version is created.
Request with s3curl command line
./s3curl.pl --id=lgreen --copysrc=/finance/hum_res/budget_proposals/BudgProp-2020 -- -k "https://finance.europe.hcp.example.com/hum_res/budget_proposals/ BudgProp-2020" -H "x-amz-meta-author: Robin Silver" -H "x-amz-meta-department: Human Resources" -H "x-amz-metadata-directive: REPLACE" -H "x-hcp-pretty-print: true"
Request headers
PUT /hum_res/budget_proposals/BudgProp-2020 HTTP/1.1 Host: finance.europe.hcp.example.com Date: Fri, 07 February 2020 17:19:26 +0000 Authorization: AWS bGdyZWVu:WAamEr9PkL76M/kWkFu5K2rY9Bs= x-amz-copy-source: /finance/hum_res/budget_proposals/BudgProp-2020 x-amz-meta-author: Robin Silver x-amz-meta-department: Human Resources x-amz-metadata-directive: REPLACE x-hcp-pretty-print: true
Response headers
HTTP/1.1 200 OK Date: Fri, 07 February 2020 17:19:26 GMT Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
Response body
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <CopyObjectResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LastModified>2017-02-23T17:19:26.062Z</LastModified> <ETag>"76216527ff2f6219f7c29251a619c8db"</ETag> </CopyObjectResult>
Example: Setting retention for an existing object
Here is a sample PUT request that updates the retention setting for the object named hum_res/budget_proposals/BudgProp-2020 in the finance bucket. In this example, the retention value of the object is set to five days past the time when the object was stored. The request is made while versioning is disabled for the bucket, so the retention value is replaced on the current version of the object. No new version is created.
Request with s3curl command line
./s3curl.pl --id=lgreen --copysrc=/finance/hum_res/budget_proposals/BudgProp-2020 -- -k "https://finance.europe.hcp.example.com/hum_res/budget_proposals/ BudgProp-2020" -H "x-hcp-retention: A+5d" -H "x-amz-metadata-directive: REPLACE" -H "x-hcp-pretty-print: true"
Request headers
PUT /hum_res/budget_proposals/BudgProp-2020 HTTP/1.1 Host: finance.europe.hcp.example.com Date: Fri, 07 February 2020 17:19:26 +0000 Authorization: AWS bGdyZWVu:WAamEr9PkL76M/kWkFu5K2rY9Bs= x-amz-copy-source: /finance/hum_res/budget_proposals/BudgProp-2020 x-hcp-retention: A+5d x-amz-metadata-directive: REPLACE x-hcp-pretty-print: true
Response headers
HTTP/1.1 200 OK Date: Fri, 07 February 2020 17:19:26 GMT Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
Response body
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <CopyObjectResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LastModified>2017-02-23T17:19:26.062Z</LastModified> <ETag>"76216527ff2f6219f7c29251a619c8db"</ETag> </CopyObjectResult>
Example: Changing the retention hold value of an object
Here is a sample PUT request that updates the retention hold setting for the object named hum_res/budget_proposals/BudgProp-2020 in the finance bucket. In this example, the retention hold value of the object is modified from false
to true
. The request is being made while versioning is disabled for the bucket, so the retention hold value is replaced on the current version of the object. No new version is created.
Request with s3curl command line
./s3curl.pl --id=lgreen --copysrc=/finance/hum_res/budget_proposals/BudgProp-2020 -- -k "https://finance.europe.hcp.example.com/hum_res/budget_proposals/ BudgProp-2020" -H "x-hcp-retentionhold: true" -H "x-amz-metadata-directive: REPLACE" -H "x-hcp-pretty-print: true"
Request headers
PUT /hum_res/budget_proposals/BudgProp-2020 HTTP/1.1 Host: finance.europe.hcp.example.com Date: Fri, 07 February 2020 17:19:26 +0000 Authorization: AWS bGdyZWVu:WAamEr9PkL76M/kWkFu5K2rY9Bs= x-amz-copy-source: /finance/hum_res/budget_proposals/BudgProp-2020 x-hcp-retentionhold: true x-amz-metadata-directive: REPLACE x-hcp-pretty-print: true
Response headers
HTTP/1.1 200 OK Date: Fri, 07 February 2020 17:19:26 GMT Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
Response body
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <CopyObjectResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LastModified>2017-02-23T17:19:26.062Z</LastModified> <ETag>"76216527ff2f6219f7c29251a619c8db"</ETag> </CopyObjectResult>
Example: Placing a labeled hold on an object
Here is a sample PUT request that places a labeled hold on an exiting object namedhum_res/budget_proposals/BudgProp-2020 in the finance bucket. The labeled hold is placed on the current version of the object.
Request with s3curl command line
./s3curl.pl --id=lgreen --copysrc=/finance/hum_res/budget_proposals/BudgProp-2020 -- -v -k "https://finance.europe.hcp.example.com/hum_res/budget_proposals/ BudgProp-2020" -H "x-hcp-retentionhold: true" -H 'x-hcp-labelretentionhold: [{"id":"UniqueLabelHold-1","hold":true}]' -H "x-amz-metadata-directive: REPLACE" -H "x-hcp-pretty-print: true"
Request headers
PUT /hum_res/budget_proposals/BudgProp-2020 HTTP/1.1 Host: finance.europe.hcp.example.com Date: Fri, 26 June 2020 17:19:26 +0000 Authorization: AWS bGdyZWVu:WAamEr9PkL76M/kWkFu5K2rY9Bs= x-amz-copy-source: /finance/hum_res/budget_proposals/BudgProp-2020 X-HCP-RetentionHold: true X-HCP-LabelRetentionHold: true x-amz-metadata-directive: REPLACE x-hcp-pretty-print: true
Response headers
HTTP/1.1 200 OK Date: Fri, 26 June 2020 17:19:26 GMT Content-Type: application/xml;charset=UTF-8 Transfer-Encoding: chunked
Response body
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <CopyObjectResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LastModified>2020-06-12T17:19:26.062Z</LastModified> <ETag>"76216527ff2f6219f7c29251a619c8db"</ETag> </CopyObjectResult>