Search code examples
amazon-web-servicescorsaws-api-gatewaypreflight

AWS API gateway error while making OPTIONS request


I am using CFT for creating env for my API. I have added OPTIONS for CORS. I have noticed when i do the test from AWS console for OPTIONS i am getting 200 response. However when i do the same from CURL or PostMan i am getting 500 internal server error. After reviewing SO questions related to it. I have modified the Integration reponse to CONVERT_TO_TEXT. but that also did not solve the issue.

I have noticed a wired behavior in the log. Following is the log snippet for request from AWS console :

Sat Apr 13 15:06:26 UTC 2019 : Method request headers: { Access-Control-Request-Method= POST, Content-Type= application/json}
Sat Apr 13 15:06:26 UTC 2019 : Method request body before transformations: 
Sat Apr 13 15:06:26 UTC 2019 : Method response body after transformations: 
Sat Apr 13 15:06:26 UTC 2019 : Method response headers: {X-Requested-With=*, Access-Control-Allow-Headers=Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-requested-with, Access-Control-Allow-Origin=*, Access-Control-Allow-Methods=POST,OPTIONS, Content-Type=application/json}
Sat Apr 13 15:06:26 UTC 2019 : Successfully completed execution
Sat Apr 13 15:06:26 UTC 2019 : Method completed with status: 200

But the same request when i give from CRUL or PM i am seeing the following log:

Method request path: {}
Method request query string: {}
Method request headers:  Method request headers: {Accept=*/*, CloudFront-Viewer-Country=IN, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, CloudFront-Is-Mobile-Viewer=false, User-Agent=curl/7.55.1, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=MYHOST, X-Forwarded-Port=443,   (CloudFront), Access-Control-Request-Method=POST, CloudFront-Is-Desktop-Viewer=true, Content-Type=application/json}
Method request body before transformations: [Binary Data]
Execution failed due to configuration error: Unable to transform request
Method completed with status: 500

We can see it is trying to transform the [Binary Data] but i am not sending anything.

Curl i used : curl -X OPTIONS -H "Access-Control-Request-Headers: Content-Type" -H "Access-Control-Request-Method: POST" -H "Access-Control-Allow-Origin: '*'" -v MYHOST

Why i am seeing this difference in log ? what went wrong in my configurtion? Can you help me.

UPDATE: I am using the below CFT

Type: AWS::ApiGateway::Method
Properties:
  AuthorizationType: NONE
  HttpMethod: OPTIONS
  Integration:
    Type: MOCK
    IntegrationResponses:
    - StatusCode: 200
      ResponseParameters:
        method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
        method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
        method.response.header.Access-Control-Allow-Origin: "'*'"
    RequestTemplates:
      application/json:
        Fn::Join:
        - ''
        - - "{"
          - ' {"statusCode":200} '
          - "}"
  MethodResponses:
  - StatusCode: 200
    ResponseParameters:
      method.response.header.Access-Control-Allow-Headers: true
      method.response.header.Access-Control-Allow-Methods: true
      method.response.header.Access-Control-Allow-Origin: true

Solution

  • there seams to be a less documented requirement to add contentHandling: CONVERT_TO_TEXT param to both: integration request and integration response settings.

    In swagger CORS config would look something like that:

    responses: {
      200: {
        description: "Returning CORS headers",
        headers: {
          "Access-Control-Allow-Headers":{ type: "string" },
          "Access-Control-Allow-Methods": { type: "string" },
          "Access-Control-Allow-Origin": { type: "string" },
        }
      }
    },
    "x-amazon-apigateway-integration": {
      type: "mock",
      contentHandling: "CONVERT_TO_TEXT", // Resolves problems with cloudfront binary content issues
      requestTemplates: {
        "application/json": "{ \"statusCode\": 200 }"
      },
      responses: {
        "default": {
          statusCode: "200",
          contentHandling: "CONVERT_TO_TEXT", // Resolves problems with cloudfront binary content issues
          responseParameters: {
            "method.response.header.Access-Control-Allow-Headers": "'*'",
            "method.response.header.Access-Control-Allow-Methods" : "'*'",
            "method.response.header.Access-Control-Allow-Origin" : "'*'"
          },
          responseTemplates: {
            "application/json": "{}"
          }
        }
      }
    }