Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Expires header for an existing S3 object using AWS Java SDK

I'm updating existing objects in an Amazon S3 bucket to set some metadata. I'd like to set the HTTP Expires header for each object to better handle HTTP/1.0 clients.

We're using the AWS Java SDK, which allows for metadata changes to an object without re-uploading the object content. We do this using CopyObjectRequest to copy an object to itself. The ObjectMetadata class allows us to set the Cache-Control, Content-Type and several other headers. But not the Expires header.

I know that S3 stores and serves the Expires header for objects PUT using the REST API. Is there a way to do this from the Java SDK?

Updated to indicate that we are using CopyObjectRequest

like image 780
bkirkbri Avatar asked Mar 21 '12 01:03

bkirkbri


2 Answers

To change the metadata of an existing Amazon S3 object, you need to copy the object to itself and provide the desired new metadata on the fly, see copyObject():

By default, all object metadata for the source object are copied to the new destination object, unless new object metadata in the specified CopyObjectRequest is provided.

This can be achieved like so approximately (fragment from the top of my head, so beware):

AmazonS3 s3 = new AmazonS3Client();

String bucketName = "bucketName ";
String key = "key.txt";
ObjectMetadata newObjectMetadata = new ObjectMetadata();
// ... whatever you desire, e.g.:
newObjectMetadata.setHeader("Expires", "Thu, 21 Mar 2042 08:16:32 GMT");

CopyObjectRequest copyObjectRequest = new CopyObjectRequest()
                 .WithSourceBucketName(bucketName)
                 .WithSourceKey(key)
                 .WithDestinationBucket(bucketName)
                 .WithDestinationKey(key)
                 .withNewObjectMetadata(newObjectMetadata);

s3.copyObject(copyObjectRequest);

Please be aware of the following easy to miss, but important copyObject() constraint:

The Amazon S3 Acccess Control List (ACL) is not copied to the new object. The new object will have the default Amazon S3 ACL, CannedAccessControlList.Private, unless one is explicitly provided in the specified CopyObjectRequest.

This is not accounted for in my code fragment yet!

Good luck!

like image 154
Steffen Opel Avatar answered Oct 23 '22 23:10

Steffen Opel


We were looking for a similar solution and eventually settled for max-age cache-control directive. And we eventually realized that hte cache-control overrides the Expires even if expires is more restrictive. And anyways cache-control met our requirement as well.

like image 25
Anoop Halgeri Avatar answered Oct 23 '22 23:10

Anoop Halgeri