# cURL command line utility

![curl logo](https://439978545-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDiEVTiIb6z0zL45wfNrM%2Fuploads%2Fgit-blob-87712369a9db2d2686a2fc66b733df16edec1a6d%2Fcurl-logo.svg?alt=media)

## Determine HTTP status (200, 404, etc.) with `--write-out '%{http_code}'`

{% code title="health-probe.sh" %}

```bash
#!/bin/bash

function httpStatus { echo "$( curl --silent --output /dev/null --write-out '%{http_code}' $1 )" ; }

echo "Azure: $( httpStatus "https://portal.azure.com/" )"
```

{% endcode %}

results in `Azure: 200`.

## Send some XML via POST to a URL

### Read body to upload from STDIN (via `--data @-`)

{% code title="POST-XML.sh" %}

```bash
#!/bin/bash

cat payload.xml | curl \
  --silent --include \
  --request POST \
  --url "https://localhost/cgi-bin/postsomestuff" \
  --header "Content-Type: application/xml" \
  --data @-
```

{% endcode %}

### Read body to upload from file

{% code title="POST-XML.sh" %}

```bash
#!/bin/bash

curl \
  --silent --include \
  --request POST \
  --url "https://localhost/cgi-bin/postsomestuff" \
  --header "Content-Type: application/xml" \
  --data @payload.xml
```

{% endcode %}

## Tracing your cURL calls with Fiddler

When I want to completely see the traffic originating from my cURL instance, I use [Fiddler ](https://www.telerik.com/fiddler)(a Windows-based HTTP(s)-proxy GUI). Fiddler can be configured to decrypt TLS (https\://) traffic, but that means that the server certificate for cURL will be untrusted. The following args instruct cURL to use a local (untrusted) HTTPs-proxy:

{% code title="curl-use-fiddler.sh" %}

```bash
#!/bin/bash

curl \
   --get \
   --url "https://management.azure.com/" \
   --proxy http://127.0.0.1:8888/ --insecure
```

{% endcode %}

![Tracing a cURL interaction in Fiddler](https://439978545-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDiEVTiIb6z0zL45wfNrM%2Fuploads%2Fgit-blob-0a6ea551288cdc2288c032c685659e84da977ca7%2Fcurl-use-fiddler.png?alt=media)

## Extract both custom HTTP header values and the body from a request

The following script uses cURL to fetch a web page, and then extracts both an HTTP from the response headers, as well as the body.

{% hint style="warning" %}
This script uses `awk,` which creates temporary files to store header and body part.
{% endhint %}

```bash
#!/bin/bash

function extractHeaders {
  local curlResponse="$1"

  local tempF="$( mktemp )"
  local tH="${tempF}headers"
  local tB="/dev/null"

  echo "${response}" | awk -v bl=1 "$( printf 'bl{bl=0; h=($0 ~ /HTTP\/1/)} /^\r?$/{bl=1} {print $0>(h?"%s":"%s")}' $tH $tB )"

  headerContents="$( cat "${tH}" ; rm "${tH}" )"

  echo "${headerContents}"
}

function extractBody {
  local curlResponse="$1"

  local tempF="$( mktemp )"
  local tH="/dev/null"
  local tB="${tempF}body"

  echo "${response}" | awk -v bl=1 "$( printf 'bl{bl=0; h=($0 ~ /HTTP\/1/)} /^\r?$/{bl=1} {print $0>(h?"%s":"%s")}' $tH $tB )"

  bodyContents="$( cat "${tB}" ; rm "${tB}" )"

  echo "${bodyContents}"
}

someURL="https://www.google.com/"

response="$( curl \
  --silent --include \
  --request GET --url "${someURL}" )"

body="$( extractBody "${response}" )"

headers="$( extractHeaders "${response}" )"
someHeader="Content-Type"
someHeaderValue="$( echo "${headers}" | grep "^${someHeader}:" | sed -E 's/^(\S+?): (.+)/\2/' )"

echo "The ${someHeader} was ${someHeaderValue}"
echo "The body was ${body}"
```

## Links

* [curl.haxx.se](https://curl.haxx.se/)
  * [Windows download](https://curl.haxx.se/windows/)
* [The book 'Everything curl'](https://bagder.gitbook.io/everything-curl/)
