How can you debug a CORS request with cURL?

CurlCors

Curl Problem Overview


How can you debug CORS requests using cURL? So far I couldn't find any way to "simulate" the preflight request .

Curl Solutions


Solution 1 - Curl

Here's how you can debug CORS requests using curl.

Sending a regular CORS request using cUrl:

curl -H "Origin: http://example.com" --verbose \
  https://www.googleapis.com/discovery/v1/apis?fields=

The -H "Origin: http://example.com" flag is the third party domain making the request. Substitute in whatever your domain is.

The --verbose flag prints out the entire response so you can see the request and response headers.

The url I'm using above is a sample request to a Google API that supports CORS, but you can substitute in whatever url you are testing.

The response should include the Access-Control-Allow-Origin header.

Sending a preflight request using cUrl:

curl -H "Origin: http://example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: X-Requested-With" \
  -X OPTIONS --verbose \
  https://www.googleapis.com/discovery/v1/apis?fields=

This looks similar to the regular CORS request with a few additions:

The -H flags send additional preflight request headers to the server

The -X OPTIONS flag indicates that this is an HTTP OPTIONS request.

If the preflight request is successful, the response should include the Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers response headers. If the preflight request was not successful, these headers shouldn't appear, or the HTTP response won't be 200.

You can also specify additional headers, such as User-Agent, by using the -H flag.

Solution 2 - Curl

Updated answer that covers most cases

curl -H "Access-Control-Request-Method: GET" -H "Origin: http://localhost" --head http://www.example.com/
  1. Replace http://www.example.com/ with URL you want to test.
  2. If response includes Access-Control-Allow-* then your resource supports CORS.

Rationale for alternative answer

I google this question every now and then and the accepted answer is never what I need. First it prints response body which is a lot of text. Adding --head outputs only headers. Second when testing S3 URLs we need to provide additional header -H "Access-Control-Request-Method: GET".

Hope this will save time.

Solution 3 - Curl

Seems like just this works:

curl -I http://example.com

Look for Access-Control-Allow-Origin: * in the returned headers

Solution 4 - Curl

The bash script "corstest" below works for me. It is based on Jun's comment above.

usage

corstest [-v] url

examples

./corstest https://api.coindesk.com/v1/bpi/currentprice.json
https://api.coindesk.com/v1/bpi/currentprice.json Access-Control-Allow-Origin: *

the positive result is displayed in green

./corstest https://github.com/IonicaBizau/jsonrequest
https://github.com/IonicaBizau/jsonrequest does not support CORS
you might want to visit https://enable-cors.org/ to find out how to enable CORS

the negative result is displayed in red and blue

the -v option will show the full curl headers

corstest

#!/bin/bash
# WF 2018-09-20
# https://stackoverflow.com/a/47609921/1497139

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'  
red='\033[0;31m'  
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message 
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}


#
# show the usage
#
usage() {
  echo "usage: [-v] $0 url"
  echo "  -v |--verbose: show curl result" 
  exit 1 
}

if [ $# -lt 1 ]
then
  usage
fi

# commandline option
while [  "$1" != ""  ]
do
  url=$1
  shift

  # optionally show usage
  case $url in      
    -v|--verbose)
       verbose=true;
       ;;          
  esac
done  


if [ "$verbose" = "true" ]
then
  curl -s -X GET $url -H 'Cache-Control: no-cache' --head 
fi
origin=$(curl -s -X GET $url -H 'Cache-Control: no-cache' --head | grep -i access-control)


if [ $? -eq 0 ]
then
  color_msg $green "$url $origin"
else
  color_msg $red "$url does not support CORS"
  color_msg $blue "you might want to visit https://enable-cors.org/ to find out how to enable CORS"
fi

Solution 5 - Curl

The preflight request is done using the OPTIONS HTTP method.

Assuming you want to test CORS on a POST request from http://mysite.example.com to https://myapi.example.com/foo, the command should be:

curl -XOPTIONS \
  -H "Access-Control-Request-Method: POST" \
  -H "Origin: http://mysite.example.com" \
  https://myapi.example.com/foo

The response is either OK or an error message like Disallowed CORS origin. You can still include the headers using -i if you’d like.

This is a lot simpler than some other responses that make either GET or HEAD requests and ask you to interprete the headers.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionthemihaiView Question on Stackoverflow
Solution 1 - CurlmonsurView Answer on Stackoverflow
Solution 2 - CurlVilius PaulauskasView Answer on Stackoverflow
Solution 3 - CurlMalcolmOceanView Answer on Stackoverflow
Solution 4 - CurlWolfgang FahlView Answer on Stackoverflow
Solution 5 - CurlbfontaineView Answer on Stackoverflow