DEV Community

Asif
Asif

Posted on

Dynamically Change the Content-Disposition of an S3 Object URL

The Content-Disposition response header of an S3 object can be changed dynamically by modifying the header value in the HTTP response that is returned when the object's URL is accessed.

One way to do this is to use an AWS Lambda function to intercept the request for the object's URL and modify the Content-Disposition response header before returning the response to the browser. This allows you to change the Content-Disposition value dynamically based on the request or other conditions.

Here's an example of a Lambda function that changes the Content-Disposition value based on the value of a query parameter in the request URL:

exports.handler = async (event) => {
  // Get the object key and bucket from the event
  const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
  const bucket = event.Records[0].s3.bucket.name;

  // Get the request query parameters
  const params = event.Records[0].cf.request.querystring;

  // Set the Content-Disposition value based on the "download" query parameter
  let contentDisposition;
  if (params.includes('download=1')) {
    contentDisposition = 'attachment';
  } else {
    contentDisposition = 'inline';
  }

  // Get the object from S3
  const s3 = new AWS.S3();
  const s3Object = await s3.getObject({
    Bucket: bucket,
    Key: key
  }).promise();

  // Create the response
  const response = {
    status: '200',
    statusDescription: 'OK',
    headers: {
      'Content-Type': [{
        key: 'Content-Type',
        value: s3Object.ContentType
      }],
      'Content-Disposition': [{
        key: 'Content-Disposition',
        value: contentDisposition
      }]
    },
    body: s3Object.Body
  };

  // Return the response
  return response;
};

Enter fullscreen mode Exit fullscreen mode

To use this Lambda function, you would need to set up an Amazon CloudFront distribution that points to your S3 bucket and associates the Lambda function with the distribution as an origin request trigger. Then, you can access the object's URL through the CloudFront distribution and use the download query parameter to control whether the object is rendered in the browser window or downloaded.

For example, the following URL would cause the object to be downloaded:

https://my-cloudfront-distribution.com/path/to/object.ext?download=1
Enter fullscreen mode Exit fullscreen mode

And the following URL would cause the object to be rendered in the browser window:

https://my-cloudfront-distribution.com/path/to/object.ext
Enter fullscreen mode Exit fullscreen mode

With this setup, you can easily switch between rendering the object in the browser window and forcing a download without having to manually change the Content-Disposition value.

Top comments (1)

Collapse
 
gbhorwood profile image
grant horwood

this is an excellent tip!