英文:
How to Download a ZIP file using AWS Lambda and API Gateway
问题
I want to download files using AWS Lambda triggered by an API Gateway endpoint, for this, my lambda function code compiles several files from S3 and creates a zip file (within the lambda /tmp/
directory) containing the specified files.
I'm having some trouble when downloading the file. I understand I have to return within the lambda response the file I want to download as an IO Stream, encoded in base 64. But when I test the API endpoint using Postman and save the response body as a .zip
file and try to open it, it says:
> Unable to expand "response.zip". It is in an unsupported format.
I was taking this documentation as an example, but what's different here is that the example downloads images instead of zip files.
my lambda handler method:
require 'logger'
require './lib/reports'
require 'base64'
$logger = Logger.new($stdout, level: Logger::Severity::INFO)
def handler(event:, context:)
$logger.info("Starting execution of lambda. AWS_REQUEST_ID: #{context.aws_request_id}")
prefix = 'reports'
path = event['path']
reports = Reports::ReportsZipper.new(prefix, path)
reports.download_and_compress_files
zip_file_path = reports.zip_file_path
zip_file = File.new(zip_file_path).read()
lambda_response = {
'headers': { 'Content-Type': 'application/zip' },
'statusCode': 200,
'body': Base64.encode64(zip_file).force_encoding('UTF-8'),
'isBase64Encoded': true
}
return lambda_response
rescue Exception => e
$logger.error("Error processing. Event: #{event}, Error: #{e.message}")
{ isBase64Encoded: false, statusCode: 400 }
end
Is there something I'm missing?
英文:
I want to download files using AWS Lambda triggered by an API Gateway endpoint, for this, my lambda function code compiles several files from S3 and creates a zip file (within the lambda /tmp/
directory) containing the specified files.
I'm having some trouble when downloading the file. I understand I have to return within the lambda response the file I want to download as a IO Stream, encoded in base 64. But when I test the API endpoint using postman and saving the response body as a .zip
file and I try to open it it says:
> Unable to expand "response.zip". It is in an unsupported format.
.
I was taking this documentation as an example, but what's different here is that the example downloads images instead of zip files.
my lambda handler method:
require 'logger'
require './lib/reports'
require 'base64'
$logger = Logger.new($stdout, level: Logger::Severity::INFO)
def handler(event:, context:)
$logger.info("Starting execution of lambda. AWS_REQUEST_ID: #{context.aws_request_id}")
prefix = 'reports'
path = event['path']
reports = Reports::ReportsZipper.new(prefix, path)
reports.download_and_compress_files
zip_file_path = reports.zip_file_path
zip_file = File.new(zip_file_path).read()
lambda_response = {
'headers': { 'Content-Type': 'application/zip' },
'statusCode': 200,
'body': Base64.encode64(zip_file).force_encoding('UTF-8'),
'isBase64Encoded': true
}
return lambda_response
rescue Exception => e
$logger.error("Error processing. Event: #{event}, Error: #{e.message}")
{ isBase64Encoded: false, statusCode: 400 }
end
Is there something I'm missing?
答案1
得分: 2
不要有别的内容。以下是翻译好的部分:
"Instead of using API Gateway to download a ZIP, look at putting the ZIP file into an Amazon S3 bucket, presign the ZIP file and get the presign URL.
Once that is ready - use a Service like Amazon SNS to send out a notification message with the presigned URL. Then users can download the ZIP from the Presigned URL in the notification message (see below).
This approach and implementation details are described in this AWS DEV article:
Create a photo asset management application that lets users manage photos using labels
UPDATE
Here is the app you build if you follow the instructions in the previous AWS link. For example, assume I want to get all images that are tagged Bird.
I select the tag in the app and click Download.
The app dynamically creates a ZIP of all images with this tag (there are 3 images with this tag as shown in the app). After a few mins - i get an email with the presigned URL.
When I click that - I get my ZIP with the images.
Note - if i click the link after the presigned ULR expires, I can no longer get the S3 object.
For more information about presign - read:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html"
英文:
Instead of using API Gateway to download a ZIP, look at putting the ZIP file into an Amazon S3 bucket, presign the ZIP file and get the presign URL.
Once that is ready - use a Service like Amazon SNS to send out a notification message with the presigned URL. Then users can download the ZIP from the Presigned URL in the notification message (see below).
This approach and implementation details are described in this AWS DEV article:
Create a photo asset management application that lets users manage photos using labels
UPDATE
Here is the app you build if you follow the instructions in the previous AWS link. For example, assume I want to get all images that are tagged Bird.
I select the tag in the app and click Download.
The app dynamically creates a ZIP of all images with this tag (there are 3 images with this tag as shown in the app). After a few mins - i get an email with the presigned URL.
When I click that - I get my ZIP with the images.
Note - if i click the link after the presigned ULR expires, I can no longer get the S3 object.
For more information about presign - read:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论