I created a API Gateway which is Integrated to use S3 bucket. I see that when I tried to retrieve the object I am getting a 200 response. However I am getting some ackward text(probably a base64 or binary text rather than the image. Can you please let me know the fix.
So the answer is set the following headers:-
Related
I am using AWS API Gateway put method to post an image to S3 bucket. In API Gateway settings when I add / in Binary Media Types I get the following error message
Access to fetch at ‘some_invokation_request/my_s3_bucket/image.png’ from origin ‘http://localhost:3001’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.
When I remove / from Binary media types in settings I can post an image and when I check the posted image in S3 it's messed up.
I'll post the original image and S3 image
Apparently this is an open issue right now and you can find further details here
I believe you have two different errors present. One is CORS related and the other is the upload of an image getting messed up. I don't think they are necessarily related. I've hit the same issue with the image upload showing the tiny white square but faced no CORS issue.
For me, the problem turned out to be trying to combine the use of Convert to Binary (if needed) and a mapping template on the Integration Request. According to the documentation (and my experience as well), if a mapping template is defined, APIGW doesn't run the Convert to Binary passthrough functionality. What gets passed to the S3 bucket for saving is a base64 encoded string instead of actual binary, thus the messed up image.
Excerpt from the linked documentation:
"On the contentHandling property of the Integration resource, set CONVERT_TO_BINARY. Set WHEN_NO_MATCH as the passthroughBehavior property value without defining a mapping template. This enables API Gateway to invoke the passthrough template."
I have an AWS lambda function that is called by AWS api gateway. The function takes URLs from multiple mp3 files hosted on AWS S3 and concatenates them into a single mp3 file. When I call the api from a browser all is good (the browser opens a media player and the combined audio mp3 is played).
The URL request looks like this:
https://0xxxxxxxx.execute-api.eu-west-1.amazonaws.com/alpha/files?file=https://xxx.s3-eu-west-1.amazonaws.com/file1.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file2.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file3.mp3
the HTTP response is of type audio/mpeg, about 10 seconds long, and is base64 encoded.
I've tried to wrap this into SSML in my skill and it fails. From the Alexa skills kit voice and tone simulator, I get the error message "error retrieving text to speech; the input was incompatible"
In the simulator, this is what I wrote:
<speak>
<audio src='https://0xxxxxxxx.execute-api.eu-west-1.amazonaws.com/alpha/files?file=https://xxx.s3-eu-west-1.amazonaws.com/file1.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file2.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file3.mp3'/>
</speak>
and I used this to confirm that S3 access works in the simulator:
<speak>
<audio src='https://s3.amazonaws.com/ask-soundlibrary/human/amzn_sfx_crowd_applause_05.mp3'/>
</speak>
Any ideas what is wrong? Is the issue with the http response from my lambda skill, or does something need to be enabled in api gateway? From my api gateway logs, it seems that the skill never tries to access the gateway.
Should I be using a different approach to fetch the mp3 for playback? Note, i want to use SSML as my audio is an effect and therefore shouldn't use the audioplayer (This is an Amazon requirement).
I might help you with this. The same problem happened to me. And after researching I resolved it. The problem here is "&" in you link which you provide in SSML. The solution you provided worked because there is no "&" now in your link. Too many parameters is not the problem.
I will suggest you to replace "&" with "&"
In python -
url = 'https://0xxxxxxxx.execute-api.eu-west-1.amazonaws.com/alpha/files?file=https://xxx.s3-eu-west-1.amazonaws.com/file1.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file2.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file3.mp3'
url = url.replace("&","&")
<speak>
"<audio src='" + url + "'/>"
</speak>
I hope this helps you. Please let me know if doesn't work.
Ok, I've worked it out myself.
It seems that SSML audio src doesn't like too many parameters in the URL call. I now just pass 1 parameter in the URL and use my lambda function to strip out the multiple filenames frome that single parameter.
https://0xxxxxxxx.execute-api.eu-west-1.amazonaws.com/alpha/files?file=/file1.mp3file=file2.mp3file=file3.mp3
I deployed Serverless Image Handler to S3 bucket with using this guide. And it was successfull.
Also i tried Demo UI and it's working. But i can not get images in S3 bucket with Thumbor image requests. Like this;
https://<distName>.cloudfront.net/fit-in/500x500/image.png
For my current images when i add "fit-in/500x500" to url it gives "AccessDenied" error.
For urls produced by Serverless Image Handler Demo UI it says;
{
"status":400,
"code":"RequestTypeError",
"message":"The type of request you are making could not be processed. Please ensure that your original image is of a supported file type (jpg, png, tiff, webp) and that your image request is provided in the correct syntax. Refer to the documentation for additional guidance on forming image requests."
}
How can i make current buckets working with Serverless Image Handler by url?
Problem Statement:- Not able to stream PDF, using AWS gateway/Lambda setup.
I've following Setup:-
Gateway API -> Lambda Function(java) -> S3
Api should stream a PDF back to the client via Lambda from S3 server.
I am unable to do so.
Things tried
1) On Lambda side
Use RequestStreamHandler, write PDF on OutputStream
outputStream.write();
Tried Setting Base64 encoding using following
AWS Base64 Utility
java.util Base64 Utility
apache Base64 utility
Send Byte[] without encoding
Use non-proxy handler, write PDF as string to one of the output variable.
Tried Setting Base64 encoding using following
AWS Base64 Utility
java.util Base64 Utility
apache Base64 utility
Send Byte[] without encoding
2) On Gateway Side
Set Proxy integration
Remove Proxy integration
Tried Set Content Handling using
Passthrough
Convert to Binary
Convert to String
Set headers
Content-Type = 'application/pdf'
Content-Disposition = 'attachment; filename="nameofpdffile.pdf"'
I've tried all the permutations/combinations of these 2. However, I am not able to get it to work and documentation around this area seems poor.
When I set Base64 encoding in Lambda and on gateway side specify content handling as convert to binary, i get error, fail to conert using Base64 decode.
For other combinations, I get binary data as output when I test it using gateway Test funciton, however my client(Postman, Chrome, Safari) fail to convert it to PDF
Note:- I've a workaround in place, where I create a signedURL to S3 object, and send it as redirect. However, I am trying to make it work by streaming a binary file using Lambda.
Thanks for reading such a long post. Any pointers, links in the right direction are highly appreciated.
- Frustated AWS user :-)
I had a similar problem with trying to offer up gzipped content: Client -> API-Gateway -> S3.
I couldn't figure out why the content I pulled couldn't get recognized by the client (either browser or code) until I inspected the header(the binary header, not http).
It appears that API Gateway by default assumes a string based encoding (utf-8) so what I was seeing is data that API Gateway was transforming on the fly and adding utf-8 headers in various places.
Late last year API Gateway started to support binary payloads. I started reading this article which may help in your case. It did not in mine, but your use case is slightly different and closer to the article so it might.
https://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/
As for what I ended up doing... I realized I was just using the API Gateway as a passthrough (to take advantage of the Cognito based authentication I had already setup) so I bypassed API Gateway all together and used the aws js sdk to connect directly to s3 (and set IAM policies on the bucket separately)
As in the title, I can't seem to get it to work, i'm following the high level guide detailed here but any images uploaded seem to be blank.
What i've set up:
/images/{object} - PUT
> Integration Request
AWS Region: ap-southeast-2
AWS Service: S3
AWS Subdomain [bucket name here]
HTTP method: PUT
Path override: /{object}
Execution Role [I have one set up]
> URL Path Paramaters
object -> method.request.path.object
I'm trying to use Postman to send a PUT request with Content-Type: image/png and the body is a binary upload of a png file.
I've also tried using curl:
curl -X PUT -H "Authorization: Bearer [token]" -H "Content-Type: image/gif" --upload-file ~/Pictures/bart.gif https://[api-url]/dev/images/cool.gif
It creates the file on the server and the size seems to be double what ever was uploaded, when viewed I just get "image has an error".
When I try with .txt files (content-type: text/plain) it seems to work though.
Any ideas?
After reading alot and chatting to AWS technical support, the problem seems to be that you can't do binary uploads through API Gateway as anything that passes through automatically goes through a UTF-8 encode.
There are a few workarounds for this I can think of, my solution will be to base64 the files before upload and trigger a lambda when they hit the bucket to decode them
This is a old post, but I got a solution.
AWS now support binary upload through APIGateway READ.
In general, go to your API settings, and add a Binary Media type.
After that, you can handle the file in base64