Hello,
I'm new to using AWS Lambda to stream HTTP responses. I am using typescript, node.js, and Lambda function URL and am building a Lambda application using SAM.
For a small image(less than 6MB), I was able to use "BUFFERED" invokeMode to return the image in the HTTP response. However, for an image bigger than 6MB, I wasn't able to do that as the maximum payload size is 6 MB for that invokeMode.
So, I am trying to stream an image in HTTP response using "STREAM_RESPONSE" invokeMode. I got to a point where the lambda function URL prompts download from the browser, and when I save the response, I can see the streamed image from s3. However, my goal is to stream the image from s3 and display it in the browser when I reach the lambda function URL. What should I do to achieve it? I think my issue is coming from the incorrect content type as the response content type is "application/octet-stream" even though I set my content type to "image/jpeg". Is there a way to prevent manually-set content-type in HTTP response from being overridden to application/octet-stream?
This is the output I see from POSTMAN when I send request to lambda function URL

Here's the code I used:
// lambda function
export const handler: Handler = awslambda.streamifyResponse(async (event, responseStream, context): Promise<any> => {
let response: any;
try {
const s3Uri = `actual-s3-uri`;
// Log the complete S3 URI
logger.info({ s3Uri });
// Parse the S3 URI to extract bucket and key
const { bucket, key } = parseS3Uri(s3Uri);
logger.info({bucket, key});
const command = new GetObjectCommand({
Bucket: bucket,
Key: key,
});
const { Body: imageStream, ContentType: contentType, ContentLength } = await s3.send(command);
if (!imageStream) {
throw new Error('no body');
}
let srcStream;
// Convert it to a Node.js readable stream
if (imageStream instanceof Readable) {
logger.info('imageStream is a readable stream');
srcStream = imageStream;
} else if (imageStream instanceof Blob) {
logger.info('imageStream is a blob');
const arrayBuffer = await imageStream.arrayBuffer();
const blobStream = new Readable({
read() {
this.push(Buffer.from(arrayBuffer));
this.push(null);
}
});
srcStream = blobStream;
} else {
throw new Error('imageStream is neither a readable stream nor a blob');
}
logger.info({ contentType, ContentLength});
// Return the processed image stream directly as the Lambda response
response = {
"statusCode": 200,
"headers": {
"Content-Type": "image/jpeg"
},
"isBase64Encoded": false,
"body": await pipeline(srcStream, responseStream),
};
logger.info({statusCode: response.statusCode, headers: response.headers});
return response;
} catch (err: any) {
logger.error({ err }, response);
rollbar.error(err, response, { custom: {} });
response = {
statusCode: 500,
body: JSON.stringify({ message: 'Unexpected error in lambda function' }),
};
throw err;
} finally {
await promiseRollbarWait(rollbar);
}
});