-
-
Notifications
You must be signed in to change notification settings - Fork 366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle binary responses (encode body) #457
Conversation
That's interesting thanks for sharing! If I understand correctly base64 encoding will only work with the mime types specified explicitly in plugins:
- serverless-apigw-binary
custom:
apigwBinary:
types: #list of mime-types
- 'image/jpeg'
- 'text/html' Here we should only base64 encode That leads me to this: should Bref automatically encode in base64 the same mimetypes that exist in The question would then be: how do we get the list of mime types… |
Also Bref needs to work without being tied to Serverless (e.g. people can use SAM or CloudFormation)… |
It seems that there is no need for a plugin anymore, it is supported natively in (sorry for posting 3 times in a row ;)) |
OK we had a quick chat with @Guillaume-Rossignol and here is a summary: Enabling API Gateway support for binary responses seems simple (https://serverless.com/framework/docs/providers/aws/events/apigateway/#binary-media-types): provider:
apiGateway:
binaryMediaTypes:
- '*/*' I can add that to the documentation after merging this PR. By recommending to use On top of that, this PR does the job: Bref will automatically base64-encode the responses that are NOT text-based. The whitelist is currently: Finally one last question to make this work: are we sure that setting |
Ignore the last commit :) |
Ooo ... very nice spotting there - thank you for for that!
I agree -- my thoughts as well ... also if the serverless.yml is in a non-standard location, etc.
Sounds good -- done. Will keep an eye out for any other additions to the list.
Yes ... looks like it didn't come out properly in my initial description on this PR. |
Perfect! I can take care of the documentation. I'll try also to see if it's possible to cover that with tests. You can try to have a look, but I'm afraid those tests are not the easiest to get started with. |
Ace, thank you! |
Answering this myself: yes it seems to work perfectly! |
OK I've written some documentation. I'm looking for advices. Do you think the section I've highlighted is necessary? I am wondering because if you want to return a binary file in PHP, you have to set the content-type anyway. Here the documentation makes it seem like there is an extra step involved, but there isn't. What do you think? |
@Guillaume-Rossignol did a few tests and it turns out this part of the docs is useful: some web browsers can handle some files without the content types. I will be leaving it. |
I think it's good practice to keep it in there. From past experience without it, the browser caches the response type ... so one request to the url which returns HTML, will continue to be interpreted as HTML unless it's told otherwise (eg. with the content-type to say the next response is actually an image, or something else). It also maximises proper handling of binary files by the browser, without having to leave the browser to figure out what type of file is actually getting downloaded. |
Despite trying for a few hours I didn't manage to write an automated test for that. I tested things manually for now. Thank you @victormacko for pushing this! |
I've added this in to allow PDF and Excel documents to be outputted by a lambda function (via the API Gateway), as a http response. (They can already be generated internally and saved/emailed ... just not output as the http response).
Previously a lambda error would occur (from memory this was shown as a JSON error "Internal server error" (or something similar) - it's detailed more in #288.
In summary this was because Bref could not encode binary data as JSON for the response to the lambda invocation endpoint.
I've implemented this by looking at the content-type included in the response, and base64 encoding any non-text response - content types of text/* ... (internally it just checks that the content-type header starts with 'text'.
I had a bit of a shortage of time so wasn't able to get the unit-tests running (I don't have the php-fpm executable installed), but hopefully this shouldn't cause any issues.
No changes to the PHP applications are required (after updating the bref package to include this change), apart from configuring API Gateway to allow Binary responses for the certain content-types which are needed ... '/' can also be used to allow everything. At the time of testing I used / as API Gateway was being difficult with having specific content-types entered ... I have a feeling the 'Accept' header (with the content-type you're requesting) needs to be included if you don't use a wildcard content-type).
The serverless (framework) plugin provides an easy way of setting this;
https://github.com/maciejtreder/serverless-apigw-binary
The approach of using the 'text/*' content-type was borrowed from the laravel-bref-bridge (was mentioned in #288;
https://github.com/stechstudio/laravel-bref-bridge/blob/9b4762f09cd6a8384fb6273506d04ee903d0bbec/src/Services/Bootstrap.php#L266-L278