user11523816
user11523816

Reputation:

How do I update/define system metadata for an AWS S3 object while creating a presigned url using Node.js SDK

I'm currently generating a pre-signed url to upload an object to my AWS s3 bucket const signedUrl = await s3.getSignedUrl('putObject', params);

Here is my params object:

 const params = {
     Bucket: 'mybucket',
     Key: `mybucketpost-${Math.ceil(Math.random() * 10 ** 10)}.png`,
     ContentType: 'image/png',
     Metadata: {
     ContentType: 'image/png',
     },
     Expires: 36000
   }

I'm able to successfully generate a presigned URL and upload an object to my bucket, but when I'm trying to access the object using the s3.getSignedUrl method, the object gets downloaded instead of the png image opening up in my browser tab. Now with all the research I've done, I understand why that's happening. That's because the system-defined object metadata Content-Type for my object is still binary/octet-stream. Even though I've attempted to change the Content-Type for the object I'm generating the presigned url for to image/png, it gets added as a user-generated metadata for the object x-amz-meta-contenttype: image/png.

So in my AWS console, the meta-data for my uploaded object are:

System defined  Cache-Control   no-cache
System defined  Content-Type    binary/octet-stream
User defined    x-amz-meta-contenttype  image/png

and unfortunately, this does not solve the issue of loading up the image in the browser tab. I've tried changing the System defined meta-data Content-Type for an object directly through the AWS console to image/png and as expected, the object (png) opens up in my browser tab using the object URL, but I've not been able to find a way to change System Defined meta-data Content-Type using the AWS SDK for Node.js while generating the presigned URL using the putObject property. Need your help with the same. Thanks!

Upvotes: 4

Views: 3571

Answers (3)

Md. Zayed Hassan
Md. Zayed Hassan

Reputation: 306

To override System Defined Metadata, use MetadataDirective: 'REPLACE'

ContentType: 'image/png',
MetadataDirective: 'REPLACE'
Metadata: {
   'custom-key': 'custom-value'
}

Upvotes: 0

Steve Abramson
Steve Abramson

Reputation: 1

For getSignedURL(...) setting the ResponseContentType worked for me as below:

signedUrl = await s3.getSignedUrl('putObject', params);


 const params = {
     Bucket: 'mybucket',
     Key: `mybucketpost-${Math.ceil(Math.random() * 10 ** 10)}.png`,
     ResponseContentType: 'application/binary-stream',
     Expires: 36000
   }

In my case I want create 2 URLS, one which will upon click download an mp4 file to disk(ResponseContentType: 'application/binary-stream') and the second will pop open a browser tab and play the video(ResponseContentType: 'video/mp4').

This works independent of what the system Content-Type value is in S3. Although if the value in S3 is set to video/mp4 you can actually leave out the ResponseContentType parameter and the default will be your S3 system content-type setting.

Upvotes: 0

curtispy
curtispy

Reputation: 224

I ran into the same problem when I try to set the Content-Disposition metadata whiling uploading to S3. In my case, by deleteing the Metadata object inside params works for me.

The following is a AWS JavaScript SDK example that defines an params object. It suggests that in order to change an System Defined metadata, you don't need to specify it in Metadata object but rather define it directly inside params object. And anything you define inside Metadata object will become user defined.

var params = {
  Bucket: 'STRING_VALUE', /* required */
  Key: 'STRING_VALUE', /* required */
  ACL: private | public-read | public-read-write | authenticated-read | aws-exec-read | bucket-owner-read | bucket-owner-full-control,
  BucketKeyEnabled: true || false,
  CacheControl: 'STRING_VALUE',
  ContentDisposition: 'STRING_VALUE',
  ContentEncoding: 'STRING_VALUE',
  ContentLanguage: 'STRING_VALUE',
  ContentType: 'STRING_VALUE',
  ExpectedBucketOwner: 'STRING_VALUE',
  Expires: new Date || 'Wed Dec 31 1969 16:00:00 GMT-0800 (PST)' || 123456789,
  GrantFullControl: 'STRING_VALUE',
  GrantRead: 'STRING_VALUE',
  GrantReadACP: 'STRING_VALUE',
  GrantWriteACP: 'STRING_VALUE',
  Metadata: {
    '<MetadataKey>': 'STRING_VALUE',
    /* '<MetadataKey>': ... */
  },
  ...
}

Upvotes: 4

Related Questions