1. Library
  2. Computer Networks
  3. Tools and Commands
  4. Http Testing

Updated 8 hours ago

Curl has hundreds of options. You don't need to know hundreds of options.

What you need is a mental model: every curl option answers one of five questions about the HTTP conversation you're having. What am I saying? Who am I? How should I connect? What should I do with the response? And the meta-question that makes debugging possible: Show me what's actually happening.

Once you see curl options this way, they stop being flags to memorize and become tools you reach for naturally.

Controlling Output

By default, curl dumps everything to your terminal. These options give you control over where responses go and what information you see.

Save to a File

# Choose your own filename
curl -o page.html https://example.com

# Use the filename from the URL
curl -O https://example.com/report.pdf

-o lets you name the file. -O trusts the server's filename.

Silence and Errors

# Complete silence
curl -s https://example.com

# Silent unless something goes wrong
curl -sS https://example.com

-s suppresses everything—progress bars, errors, all of it. The combination -sS is curl's way of saying "shut up unless something goes wrong." This is what you want in scripts.

Ask Curl About the Request

The -w flag lets you interrogate curl itself about what just happened:

# Just the status code
curl -w "%{http_code}\n" -o /dev/null -s https://example.com

# How long did each phase take?
curl -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nFirst byte: %{time_starttransfer}s\nTotal: %{time_total}s\n" -o /dev/null -s https://example.com

Useful variables:

  • %{http_code} — The response status
  • %{time_total} — Total time in seconds
  • %{time_namelookup} — How long DNS took
  • %{time_connect} — How long TCP handshake took
  • %{time_appconnect} — How long TLS handshake took
  • %{time_starttransfer} — Time to first byte (server thinking time)
  • %{size_download} — Bytes received

This is how you measure performance without external tools.

Controlling the Request

HTTP Methods

curl -X GET https://api.example.com/users
curl -X POST https://api.example.com/users
curl -X PUT https://api.example.com/users/123
curl -X DELETE https://api.example.com/users/123
curl -X PATCH https://api.example.com/users/123

For GET requests, you can skip -X GET—it's the default.

Sending Data

# Form data (what browsers send from <form> elements)
curl -d "name=John&email=john@example.com" https://api.example.com/users

# JSON (what modern APIs expect)
curl -d '{"name":"John"}' -H "Content-Type: application/json" https://api.example.com/users

# From a file
curl -d @data.json -H "Content-Type: application/json" https://api.example.com/users

The -d flag implies POST. The @ prefix reads from a file.

File Uploads

# Upload a file
curl -F "file=@document.pdf" https://api.example.com/upload

# Upload with metadata
curl -F "file=@photo.jpg" -F "title=Sunset" https://api.example.com/photos

-F sends multipart form data—the same format browsers use for file uploads.

Headers

curl -H "Authorization: Bearer token123" \
     -H "Accept: application/json" \
     https://api.example.com/data

Every -H adds one header. Use this for API keys, content types, custom headers—anything the server needs to know about your request.

HEAD Requests

curl -I https://example.com

Ask for headers only, no body. Useful for checking if a resource exists or reading metadata without downloading the whole thing.

Authentication and Identity

Basic Auth

curl -u username:password https://api.example.com/secure

This encodes credentials as Base64 in the Authorization header. Not secure over plain HTTP.

Cookies

# Send a cookie
curl -b "sessionid=abc123" https://example.com

# Save cookies from response
curl -c cookies.txt https://example.com/login

# Use saved cookies
curl -b cookies.txt https://example.com/dashboard

Use -c to save, -b to send. For session-based APIs, you'll often do both.

User Agent

curl -A "Mozilla/5.0 (MyBot)" https://example.com

Some servers behave differently based on who they think you are.

Connection Behavior

Following Redirects

curl -L https://example.com

Without -L, curl stops at redirects and reports the 3xx status. With -L, it follows them like a browser would.

Timeouts

# Give up if connection takes more than 10 seconds
curl --connect-timeout 10 https://example.com

# Give up if the whole operation takes more than 30 seconds
curl --max-time 30 https://example.com

Always set timeouts in scripts. Otherwise a hung server hangs your script forever.

Retries

curl --retry 3 --retry-delay 5 https://example.com

Retry up to 3 times, waiting 5 seconds between attempts.

Resume Downloads

curl -C - -O https://example.com/largefile.zip

If the download fails, run the same command again. The -C - tells curl to figure out where it left off.

SSL/TLS

Skip Certificate Verification

curl -k https://self-signed.example.com

Never use this in production. It defeats the entire point of TLS. Use it only for local development with self-signed certificates.

Client Certificates

curl --cert client.pem --key client-key.pem https://api.example.com

For mutual TLS where the server wants to verify your identity.

Proxies

# HTTP proxy
curl -x http://proxy.example.com:8080 https://example.com

# SOCKS proxy
curl -x socks5://proxy.example.com:1080 https://example.com

# Proxy with authentication
curl -x http://user:pass@proxy.example.com:8080 https://example.com

Debugging

Verbose Mode

curl -v https://example.com

This shows everything: DNS lookup, TCP connection, TLS negotiation, request headers sent, response headers received. When something isn't working, this is where you start.

Full Trace

curl --trace-ascii debug.txt https://example.com

Even more detail than verbose, including the raw bytes. Use when -v isn't enough.

Force DNS Resolution

curl --resolve example.com:443:93.184.216.34 https://example.com

Make curl use a specific IP for a hostname. Essential for testing before DNS changes propagate, or for hitting a specific server in a load-balanced setup.

Patterns for Real Work

API Testing

curl -v \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer token123" \
  -d '{"name":"John","email":"john@example.com"}' \
  -w "\nStatus: %{http_code} | Time: %{time_total}s\n" \
  https://api.example.com/users

Reliable Downloads

curl -C - \
  --retry 3 \
  --retry-delay 5 \
  --max-time 300 \
  -O https://example.com/largefile.zip

Health Check

status=$(curl -sS -o /dev/null -w "%{http_code}" --max-time 10 https://example.com/health)
if [ "$status" = "200" ]; then
  echo "OK"
else
  echo "FAIL: $status"
fi

Configuration Files

Tired of typing the same options? Put them in ~/.curlrc:

user-agent = "MyApp/1.0"
connect-timeout = 10
retry = 3

These become defaults for all curl commands.

Frequently Asked Questions About curl Options

Was this page helpful?

😔
🤨
😃
Common curl Options • Library • Connected