Following all the steps above didn't work on my case, because having the binary support for content-type = */*
will convert all responses to binary.
My case:
Multiple lambda functions returning json (text), just a single lambda returning a binary file. All have lambda proxy enabled.
The lambdas are in an API Gateway
The API Gateway is behind CloudFront
Hint:
I have notice an important information in the API Gateway -> Settings
Quoting:
API Gateway will look at the Content-Type and Accept HTTP headers to decide how to handle the body.
This means that the Content-Type response header must match Accept request header
Solution:
Set Binary Media Types in API gateway to your mime type: image/jpg
In your HTTP request set Accept: image/jpg
In your HTTP response set Content-Type: image/jpg
{
"isBase64Encoded": True,
"statusCode": 200,
"headers": { "content-type": "image/jpg"},
"body": base64.b64encode(content_bytes).decode("utf-8")
}
- Next we must tell CloudFront to accept the 'Accept' header from the request. So, in CloudFront distribution, click on your API Gateway instance (ID is clickable) and once redirected to CloudFront instance go to Behaviour tab, select the path-pattern of your API (example: /api/*) and click on Edit button.
On the new screen, you have to add Accept header to Whitelist.
Note 1: If you have multiple file types, you must add them all to Binary Media Types in the API gateway settings
Note 2: For those coming from serverless and want to set the binary types when deploying your lambdas, then check this post: setting binary media types for API gateway
plugins:
- serverless-apigw-binary
custom:
apigwBinary:
types:
- 'image/jpeg'
The serverless.yml file for cloudfront should contain:
resources:
WebAppCloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
...
CacheBehaviors:
...
-
#API calls
...
ForwardedValues:
...
Headers:
- Authorization
- Accept
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…