# cURL command line utility

![curl logo](/files/izumniWANkww5o23wYV2)

## 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](/files/GXGBVsSagKnzuVA7nS9I)

## 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/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cookbook.geuer-pollmann.de/command-line-utilities/curl.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
