DisgruntledGoat
DisgruntledGoat

Reputation: 72510

How to update metadata using Amazon S3 SDK

I am using the PHP version of Amazon's AWS SDK. I have a bunch of files with an Expires header; I want to delete that header and add a Cache-control header instead. The update_object function lets me add headers but not remove them.

The answers on this question suggest you can update a file's metadata when you copy it, but I have tried it and it doesn't work. Here is what I used:

$response = $s3->copy_object(
    array(
        'bucket' => $bucket,
        'filename' => $file,
    ),
    array(
        'bucket' => $bucket,
        'filename' => $file2,
    ),
    array(
        'acl' => AmazonS3::ACL_PUBLIC,
        'headers' => array(
            'Content-Type' => 'image/jpeg',
            'Cache-Control' => 'public,max-age=30240000',
        ),
        'meta' => array(
            'x-fake-header' => 'something awesome is happening',
        ),
    )
);

However, the copied object has the exact same headers as the original object (Expires and Content-Type only). I've tried all manner of combinations of the above (with and without Content-Type, Cache-control, meta, etc) and get the same result.

How do I reset the metadata?

Upvotes: 9

Views: 16115

Answers (3)

Alex Rosiu
Alex Rosiu

Reputation: 31

Based on Jeffin P S's answer (which works great), I'm proposing a version that creates the new metadata object by cloning the original one. This way, the AWS-specific (non-user) metadata do not get converted into user metadata. Not sure if that would be a real issue, but seems more legit this way.

ObjectMetadata metadataCopy = amazonS3Client.getObjectMetadata(bucketName, fileKey).clone();
metadataCopy.addUserMetadata("yourKey", "updateValue");
metadataCopy.addUserMetadata("otherKey", "newValue");

CopyObjectRequest request = new CopyObjectRequest(bucketName, fileKey, bucketName, fileKey)
      .withSourceBucketName(bucketName)
      .withSourceKey(fileKey)
      .withNewObjectMetadata(metadataCopy);

amazonS3Client.copyObject(request);

Upvotes: 3

Jefin Stephan
Jefin Stephan

Reputation: 108

In Java, You can copy object to the same location. Here metadata will not copy while copying an Object. You have to get metadata of original and set to copy request. This method is more recommended to insert or update metadata of an Amazon S3 object

ObjectMetadata metadata = amazonS3Client.getObjectMetadata(bucketName, fileKey);
ObjectMetadata metadataCopy = new ObjectMetadata();
metadataCopy.addUserMetadata("yourKey", "updateValue");
metadataCopy.addUserMetadata("otherKey", "newValue");
metadataCopy.addUserMetadata("existingKey", metadata.getUserMetaDataOf("existingValue"));

CopyObjectRequest request = new CopyObjectRequest(bucketName, fileKey, bucketName, fileKey)
      .withSourceBucketName(bucketName)
      .withSourceKey(fileKey)
      .withNewObjectMetadata(metadataCopy);

amazonS3Client.copyObject(request);

Upvotes: 2

DisgruntledGoat
DisgruntledGoat

Reputation: 72510

I've just found that copying to object to itself actually does change the headers properly. I was copying it to a second file for testing purposes to avoid overwriting the original.

But for some strange reason copying to a different file doesn't change the headers, but copying to the same file does.

Upvotes: 8

Related Questions