Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using lambda to serve bucket image resources through API Gateway results in a broken image

I am using AWS Api Gateway, Lambda, and S3.

My goal is to hit the gateway and serve and display an image from my S3 bucket in the browser. Currently I am able to successfully fetch the image from the appropriate bucket using the AWS SDK in my lambda no problem. I then send it over the wire as and the response is 200 and I can see all the appropriate headers. However the image is broken.

Here is the code in my lambda:

const AWS = require('aws-sdk');

const s3 = new AWS.S3();

exports.handler = async (event) => {
  const bucketParams = {
    Bucket: 'my-bucket',
    Key: 'build/cat.jpg',
  };
    
    const bucket = await s3.getObject(bucketParams).promise();
    
    const response = {
        statusCode: 200,
        body: Buffer.from(bucket.Body).toString(),
        headers: {
            'Accept-Ranges': 'bytes',
            'Content-Length': bucket.ContentLength,
            'Content-Type': bucket.ContentType,
            'Last-Modified': bucket.LastModified,
            'ETag': bucket.Etag,
        }
    };
    
    return response;
};

The response is a 200, everything works but my image appears to be broken in the browser. Here is a uri of the example https://3bn2t9npbd.execute-api.us-east-1.amazonaws.com/dev/cat.jpg

As a side note I serve more than just images through this code the example above though is just a single image.

like image 352
allencoded Avatar asked Oct 29 '25 02:10

allencoded


1 Answers

I was able to figure out the solution to my problem. Thanks to jarmod for pointing me in the right direction. I first had to enable Binary Media Types for all content in my AWS Gateway Settings pictured below.

enter image description here

After that I changed the lambda code to response to be:

const bucket = await s3.getObject(bucketParams).promise();
    
const response = {
  statusCode: 200,
  body: Buffer.from(bucket.Body).toString("base64"),
  headers: {
    'Accept-Ranges': 'bytes',
    'Content-Length': bucket.ContentLength,
    'Content-Type': bucket.ContentType,
    'Last-Modified': bucket.LastModified,
  },
  isBase64Encoded: true,
};
    
return response;
like image 88
allencoded Avatar answered Oct 30 '25 17:10

allencoded



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!