How to solve the OPTIONS 500 error in AWS API Gateway? - amazon-web-services

I have created a React Application to upload a file to the S3 bucket. To do this, I have created a PUT API from the AWS API Gateway and the API is working well in the POSTMAN. The problem is, when I call the API from my React Application locally (http://localhost:3000), I'm getting a 500 error from the OPTIONS request (Preflight).
I have set the Binary Media Types to "image/jpeg" and When I remove the Binary Media Types, the API returns the 200 response, but then, an empty image is uploaded without its content.
How can I solve this?
This is my Request Integrations of both the PUT method and the OPTIONS method
PUT
OPTIONS
Binary Media Types

Related

API Gateway request blocked by CORS

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."

AWS CloudFront + Lambda#Edge "The JSON output is not parsable"

I have a Lambda function (a packaged next.js app) which I'm trying to access via CloudFront. The web app works unless I try to hit the homepage.
When I hit /search or /video/{videoId} the page loads just fine.
When I try to hit the homepage, I get the following error page:
502 ERROR
The request could not be satisfied.
The Lambda function returned invalid JSON: The JSON output is not parsable. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront)
Request ID: {id}
Why would just the homepage be invalid JSON? Where can I see this JSON to determine what is wrong? I created a mock Cloudfront request test in the Lambda function and it just returns successfully.
The problem was due to the 1 MB size limit of CloudFront Lambda#Edge responses. I didn't realize that Next.js's serverside rendering was creating a large <script id="__NEXT_DATA__"> tag on my homepage with all the fetched info from my API duplicated multiple times over. This resulted in my app's homepage being >2 MB.
I refactored my app to only send one network request, and made sure that data is only put into the __NEXT_DATA__ tag once. The app now works.

AWS API Gateway 403 Forbidden response OPTIONS

I am trying to call API of AWS through JEE and I got this error in the Chrome Console
[![enter image description here][1]][1]
But when I call same API from postman or when I use it in localhost it works.
Whats wrong ?
In your API Gateway OPTIONS method, go into Method Response and add a response header with the name 'Access-Control-Allow-Origin'.
Now go into Integration Response, expand the default 200 response and in Header Mappings put the URL of your DNS. If you don't want to restrict by URL, just put a *.
You may need to add this configuration to other methods as well.

AWS API Gateway Integration Request setup automation

I am trying to use the AWS API Gateway+Swagger to route the request to my express backend. I can't figure out how to automate the setup of the integration request as the Swagger file has no details on it.
I'm also having difficulty with the endpoint url parameter when setting my method requests to GET/VPC Link on the integration type
For example:
My api gateway path is /info/car/{model}/aggregate
Now the endpoint url is http://carapi.com/info/car/{model}/aggregate
I have lots of gateway paths all of which are the same paths that my carapi.com site uses, so I don't want to keep retyping the path over and over. When entering in the endpoint url, I was able to simplify not having to type carapi.com by using stage variables turning my endpoint url to
http://${stageVariables.carApi}/info/car/{model}/aggregate
However after reading https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#stagevariables-template-reference
I see that there is also a $context available, but it gives me an error(when I try to call the api in postman, says 'internal server error' for the message) when I try to implement the context (which through that link shows that I can implement the path).
http://${stageVariables.carApi}/${context.resourcePath}
So my question is: how do I automate the setup of Integration requests so I don't have to manually setup each and every one(as I have hundreds of paths)? Is there also anyway to not have to set the paths manually for the endpoints?
I don't know of any solution which is ready to use.
In my project, we wrote a custom solution that downloads the application Swagger json, parses it, adds the required integration and generates another json file. Then we import that into API Gateway. This has been converted as a Jenkins job and runs as a post job of microservice deployment.
Another way is, instead of generating the json, directly call API Gateway APIs and add the integration.

AWS API Gateway ERR_CONTENT_DECODING_FAILED in browser

In my use case, API Gateway serves as an HTTP proxy, using default settings following official tutorial.
It's tested working in test console or via curl. But if I access the link in browser or make an AJAX call, I'll get ERR_CONTENT_DECODING_FAILED.
It seems that API Gateway corrupt the content. Related issue.
Is there a way to forbid API Gateway changing my content? I set Content Handling to passthrough, but clearly it's changing my content.
Add a static integration request header Accept-Encoding with value 'identity', so that AWS won't tamper your request.