Reputation: 524
Using the out the box Serverless template for C# .Net Core 2.0, I've created an S3 bucket that contains an image - I want to display this in a browser.
Running the webapi locally I can view the image fine and the content-length header isn't even included. When accessing via https://apidemo.boro2g.co.uk/media/mirrored-faces.jpg the content-length is getting changed to be bigger than it should. The original image is roughly 300kb but out of the API gateway its roughly 400kb.
I want to use the proxy to apply some custom security over the images so don't want them to be public, for testing you can see the original at https://s3-eu-west-1.amazonaws.com/boro2g-photogallery/mirrored-faces.jpg
I've tried adding the binary media types as well within the API but these don't seem to have any effect.
The code to 'get' the image is pretty simple:
[HttpGet("{key}")]
public async Task Get(string key)
{
try
{
var getResponse = await S3Client.GetObjectAsync(new GetObjectRequest
{
BucketName = BucketName,
Key = key
});
Response.ContentType = getResponse.Headers.ContentType;
getResponse.ResponseStream.CopyTo(Response.Body);
}
catch (AmazonS3Exception e)
{
Response.StatusCode = (int)e.StatusCode;
var writer = new StreamWriter(Response.Body);
writer.Write(e.Message);
}
}
Why would the API be updating the content-length incorrectly?
FYI static txt files load without problem: https://apidemo.boro2g.co.uk/media/test.txt
Upvotes: 2
Views: 1844
Reputation: 12218
Why is AWS Gateway setting the wrong content length for an image streamed from S3?
Your API Gateway is not rendering the binary data properly, its assuming the data is string in a different encoding such as base64, following did fix the issue.
API Settings > Binary Media Types
*/*
API Method Response, Add HTTP Status 200, and set desired Content-Type header
I also had to apply following patch for the response body to be converted to binary.
aws apigateway update-integration-response \
--profile AWS_PROFILE_NAME \
--rest-api-id API_ID \
--resource-id RESOURCE_ID \
--region AWS_REGION \
--http-method GET \
--status-code 200 \
--patch-operations '[{"op" : "replace", "path" : "/contentHandling", "value" : "CONVERT_TO_BINARY"}]'
Upvotes: 0
Reputation: 229
Upvotes: 1
Reputation: 524
In the end the solution I found to work was:
The second step here may not be necessary but I found the / didn’t kick in until I made the change.
Upvotes: 4