'AWS GET request with body rejected by CloudFront
I'm build an API using AWS SAM (Lambda & API Gateway) whose contract is defined by a 3rd party.
The 3rd party calls my API with a GET request that contains JSON in the body. However, when a request is sent to the API with a body it gets rejected by CloudFront.
This is the request:
curl -X GET -H "Content-Type: application/json" --data '{"hello":"world"}' https://my-api.execute-api.us-east-2.amazonaws.com/Prod/my-api
This is the response:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD>
<BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Bad request.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: 1p0St_-e3noQL-2uMxeB_2I6lkMr1mg5afvxJRmVpCdnG67Vgnhj9w==
</PRE>
<ADDRESS></ADDRESS>
</BODY>
</HTML>
Checking the logs, the request never hits API Gateway or the Lambda function. However, if I remove the body from the request, then it hits the Lambda function and I get the appropriate error message from the API (telling the caller that the expected body is missing.)
curl -X GET -H "Content-Type: application/json" https://my-api.execute-api.us-east-2.amazonaws.com/Prod/my-api
I'm using basic configuration of API Gateway via a SAM template. This is the relevant section:
MyApiFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: bin/main.zip
Handler: main
Runtime: go1.x
Tracing: Active
Role: !Sub ${MyApiLambdaExecutorRole.Arn}
Events:
CatchAll:
Type: Api
Properties:
Path: /my-api
Method: GET
Solution 1:[1]
GET requests cannot contain a request body on CloudFront. Try using POST instead.
If you want to send limited data in a GET request, you can use query parameters.
You can see in the AWS Docs that this isn't possible here:
If a viewer GET request includes a body, CloudFront returns an HTTP status code 403 (Forbidden) to the viewer.
You could perhaps use an EC2 instance or other service that doesn't use API Gateway to handle the request.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
