5

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
backtrack
  • 7,996
  • 5
  • 52
  • 99
  • Try removing the '-H "Content-Type: application/json"'. Your browser doesn't send a Content-Type header in the OPTIONS request. (It only sends that in the POST request.) You also need to send the Access-Control-Request-Headers request header. – sideshowbarker Apr 13 '19 at 16:40
  • Hi @sideshowbarker - I tried that but still same error – backtrack Apr 13 '19 at 17:28
  • https://stackoverflow.com/q/44067102/441757 looks relevant. It seems like you might get better help if you post your `x-amazon-apigateway-integration` value, and if you post the template you’re using for OPTIONS requests. Also, to be clear: Do you not get the same failure when you test POST requests with curl or Postman? See also https://forums.aws.amazon.com/thread.jspa?threadID=256140 – sideshowbarker Apr 13 '19 at 23:17
  • @sideshowbarker - Please refer the update section in my post. – backtrack Apr 14 '19 at 06:35
  • @backtrack did you manage to resolve this? if so, can you please provide an answer to you question detailing how you resolved this issue. thanks. – M. Ali Iftikhar May 29 '20 at 07:53

3 Answers3

3

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": "{}"
      }
    }
  }
}
  • 1
    Thanks a million! I had very similar issue and your answer pointed me into the right direction! I removed the Binary Media Type `*/*` and the MOCK does not fail on parsing preflights anymore! – bgw Apr 08 '21 at 08:45
1

For me the issue was coming from this line:

"x-amazon-apigateway-binary-media-types" : [ "multipart/form-data", "application/zip", "*/*" ]

Just remove the "*/*"

"x-amazon-apigateway-binary-media-types" : [ "multipart/form-data", "application/zip" ]

It's only after finding this that I saw the comment from @bgw

Anyway, hope this can help someone else not searching for hours!

Mathix420
  • 872
  • 11
  • 21
0

If in your API gateway settings you have added 'application/json' to the binary media types (like in case you want to gzip responses) or if this request is anyway for a binary media type then the default OPTIONS that gets added by the 'enable CORS' feature will need to be adjusted.

Like it was said above, you'll need to set the contentHandling to "CONVERT_TO_TEXT" at least for the integration. For me it worked without having to add it to the integration response. You can do it via AWS CLI as follows:

aws apigateway update-integration --rest-api-id YOUR_REST_ID --resource-id YOUR_RESOURCE_ID --http-method OPTIONS --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'

Oh and don't forget to redeploy the API afterwards.

Dre
  • 1,985
  • 16
  • 13