cURL - The Ultimate Reference Guide
cURL short for “Client for URL” is a computer software project providing the libcurl library and curl command-line tool for transferring data such as downloads and uploads using various network protocols. The curl tool and libcurl library support a large selection of network protocols such as: DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. This rich support for common data transfer protocols makes curl and libcurl a powerful tool in the arsenal of anyone interacting with network protocols.
I recently watched the above master class presentation on Mastering the Curl Command Line (slides) with Daniel Stenberg (@badger) the founder and lead developer of cURL and libcurl which was very detailed and full of useful information regarding the cURL command-line tool. From the video I added a plethora of new notes to my curl note collection. From these notes I decided to share them as a comprehensive reference and guide to the curl command-line tool. These notes are a compilation of my personal notes as well as notes taken while watching Mastering the Curl Command Line.
Before Starting
If you’re just learning about curl or are a seasoned curler looking to try new commands I highly recommend installing Wireshark while fiddling with curl. This allows you to see the network traffic you’re sending with curl.
Many commands and protocols can be tested against solutions such as Python’s http.server. Allowing you to test curl commands against localhost.
sudo python3 -m http.server 80
Installing cURL
Linux
Ubuntu & Debian
apt install curl
Redhat & CentOS
yum install curl
nix
nix-env -i curl
Arch Linux
pacman -S curl
SUSE and openSUSE
zypper install curl
SUSE SLE Micro and openSUSE MicroOS
transactional-update pkg install curl
macOS
brew install curl
Windows
Ensure that winget is installed on your Windows PC.
winget install cURL.cURL
Docker
The curl command-line is available as curlimages/curl on docker hub.
docker pull curlimages/curl:8.2.1
Run with Docker
docker run --rm curlimages/curl:8.2.1 --version
Running curl with docker
docker run --rm curlimages/curl:8.2.1 -L -v https://curl.haxx.se
Finding Help & Usage
curl --help
curl --help all
curl --manual
Version
-V, —version - options to show curl version number and quit
curl --version
Verbose
-v, —verbose - options for verbose output.
curl --verbose http://example.com
—trace-time - option to add timestamps to trace and verbose output.
curl --verbose --trace-time http://example.com
—trace - to write a debug trace to a file.
curl --trace trace.txt http://example.com
—trace-ascii - to write a debug trace to a file without hex.
Be careful when sharing trace files!
Config File
Config files allow users to write complex curl commands by storing options in a config file. Pass a config file to curl using the -K, —config option.
curl -K config.txt https://curl.se/logo/curl-logo.jpg
Passwords
-u, —user - combination to pass a username:password combination.
curl -u alice:12345 http://example.com/
.netrc
To avoid password leakage you can pass a .netrc or config file. The command -n, --netrc will look for a .netrc file in the home directory.
Pass your own netrc file using the --netrc-file option.
curl --netrc-file .netrc http://example.com
curl https://daniel.haxx.se/
Multiple URLs
curl https://example.com/file1 https://curl.se/file2
Progress Meters
-s, —silent, —no-progress-meter - for silent, no output.
curl -s "https://example.com
curl --silent "https://example.com
curl --no-progress-meter "https://example.com
Use the -#, —progress-bar to display a transfer progress bar.
Reset URL State
When using multiple URLs use the -:, —next command to reset the state of each URL forcing each URL to use it’s own unique options.
curl -H “header: one” https://example.com/one --next -H “header: two” https://example.com/two
Write Out
-w, —write-out - option to output variables after command completion.
curl --write-out "Type: %{content_type}\nCode: %{response_code}\n" http://example.com
See a full list of information on over 50 variables.
Downloads
Supports outputting using the -o, --output (specify filename) and -O, --remote-name (use server name) options.
Use the --remote-header-name to use content-disposition name for the filename, use with the -O, --remote-name option.
Output Options
-o, --output - Write to file instead of stdout
-O, --remote-name - Write output to a file named as the remote file
--output-dir - saves the -O, --remote-name data in another directory.
curl -O --output-dir tmp https://curl.se/logo/curl-logo.jpg
--create-dirs - Create necessary local directory hierarchy (useful to output to a dir that doesn’t exist
curl -O --create-dirs --output-dir tmp https://curl.se/logo/curl-logo.jpg
Single URL to File
-o, --output - Write to file instead of stdout
curl -o index.html https://daniel.haxx.se/
-O, --remote-name - Write output to a file named as the remote file
curl --remote-name index.html https://daniel.haxx.se/
--remote-header-name - Use the content-disposition name for the filename, use with the -O, —remote-name
curl --remote-name --remote-header-name https://curl.se/logo/curl-logo.jpg
Multiple URLs to Files
-o, --output - Write to file instead of stdout
curl -o file1 https://example.com/file1 https://curl.se/file -o file2
-O, --remote-name - Write output to a file named as the remote file
curl -O https://example.com/file1 -O https://curl.se/file2
--remote-name-all - to use the remote name for all URL’s
curl --remote-name-all https://example.com/a.html https://example.com/b.html https://example.com/c.html https://example.com/d.html https://example.com/e.html
Retry
Useful for transient errors such as the momentary loss of network connectivity to components and services.
--retry - perform a number of retries
curl --retry 5 http://example.com
--retry-max-time - during this timeframe
curl --retry-max-time 60 http://example.com
--retry-delay - Wait this long before retries
curl --retry-delay 60 http://example.com
--retry-connrefused - Retry on connection refused (can be considered transient), use with --retry
curl --retry 99 --retry-connrefused http://example.com
--retry‐all-errors - Consider all errors transient
curl --retry-all-errors http://example.com
Uploads
-T, --upload-file - Transfer local file to destination.
curl --upload-file file $URL
If URL has no file name, appent the -T, --upload-file to the URL
curl -T file ftp://example.com/path/
Transfer Controls
-Y, --speed-limit - Stop transfers slower than this
-y, --speed-time - Trigger ‘speed-limit‘ abort after this
curl --speed-time 15 --speed-limit 1000 https://example.com/
--limit-rate - Limit transfer speed rate
curl https://example.com/ --limit-rate 200K
Transfer limits and time units
curl --rate 2/s https://example.com/[1-20].jpg
curl --rate 3/h https://example.com/[1-20].html
curl --rate 14/m https://example.com/day/[1-365]/fun.html
Naming Tricks
Provide a name + port => address mapping - use --resolve <host:port:address[,address]...> the host+port to this address.
curl --resolve example.com:80:127.0.0.1 http://example.com
Provide a name + port => name + port mapping - use --connect-to <HOST1:PORT1:HOST2:PORT2> to connect to host.
curl --connect-to example.com:80:localhost:8080 http://example.com
Set a fake host header (may fail certificate checks with TLS)
curl -H “host: curl.fake” http://example.com/
Network Layer Race Conditions
Curl uses both IPv4 and IPv6, fix the Internet Protocol (IP) version with --ipv4 or --ipv6
--ipv4
Resolve names to IPv4 addresses
curl --ipv4 http://example.com
--ipv6
Resolve names to IPv6 addresses
curl --ipv6 http://example.com
Connections
Curl options such as --interface, --local-port, --keepalive-time, --dns-ipv4-addr, --dns-ipv6-addr can be used to specify network interfaces, ports, keep alive, and dns addresses can be used for granular control over connections.
--interface
Use network INTERFACE (or address)
curl --interface enp3s0 https://example.com
--local-port
Force use of RANGE for local port numbers
curl --local-port 1000-3000 https://example.com
--keepalive-time
Interval time for keepalive probes
curl --keepalive‐time 23 https://example.com
--dns-ipv4-addr
IPv4 address to use for DNS requests
curl --dns-ipv4-addr 10.1.2.3 https://example.com
--dns-ipv6-addr
IPv6 address to use for DNS requests
curl --dns-ipv6-addr 10.1.2.3 https://example.com
Timeouts
Controls the timeouts
-m, --max-time
Maximum time allowed for the transfer
curl --max-time 15.42 https://example.com
--connect-timeout
Maximum time allowed for connection
curl --connect-timeout 3.14 https://example.com/
Exit Status
The numerical value curl returns to the shell as an exit code.
curl -o save https://example.com/
Return code use $?
echo $?
SSH
curl will attempt to use public key in the .ssh directory
SCP
curl scp://172.16.186.131 -u kali:kali
curl scp://172.16.186.131/~/file.txt -u kali:kali
SFTP
curl sftp://example.com/file.zip -u user
curl sftp://172.16.186.131/~/todo.txt -u kali:kali
Reading Email
POP3
List message numbers & sizes
curl pop3://example.com/
Download email 1
curl imap://example.com/1
--request DELE - delete message 1
curl --request DELE pop3://mail.example.com/1
IMAP
List emails in work
curl imap://example.com/work
Get mail using UID 57 from mailbox “stuff“
curl imap://server.example.com/stuff;UID=57
Get the mail with index 57 from the mailbox “fun”
curl imap://server.example.com/fun;MAILINDEX=57
Sending Email
Curl can send email with the -T, --upload-file with SMTP. The file needs to have all the mail headers and formatted correctly.
curl -T data smtp://example.com/ -u user:password
MQTT - IoT Messaging Standard
MQTT is an OASIS standard messaging protocol for the Internet of Things (IOT) using a publishing/subscribe messaging transport.
Subscribe
Subscribe to the bedroom temperature in the subject
curl mqtt://example.com/home/bedroom/temp
-d, --data - Set the kitchen dimmer
curl -d 75 mqtt://example.com/home/kitchen/dimmer
TFTP
Trivial File Transfer Protocol (TFTP) is a simple protocol that provides basic file transfer function with no user authentication.
Download
curl -O tftp://localserver/file.boot
Upload
curl -T file.boot tftp://localserver/
Telnet
Teletype Network (Telnet) - Telnet is an early client/server application protocol used to access remote system terminals over networks, transmitting data including usernames and passwords in plaintext, making it unsuitable for secure applications. Its popularity has diminished in favor of more secure protocols like SSH, with some proposed extensions to add encryption to Telnet.
Session
curl telnet://example.com:80
Dictionary
Provides lookups (downloads)
curl dict://dict.org/m:curl
curl dict://dict.org/d:heisenbug:jargon
curl dict://dict.org/d:daniel:gcide
WebSocket
Still experimental
curl wss://example.com/wss
h2c - Headers to cURL Command Line
h2c allows you to convert a series of headers into a curl command.
GET / HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1
curl --header "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" --compressed --header "Accept-Language: en-US,en;q=0.5" --header "Connection: keep-alive" --header "Sec-Fetch-Dest: document" --header "Sec-Fetch-Mode: navigate" --header "Sec-Fetch-Site: none" --header "Sec-Fetch-User: ?1" --header "Upgrade-Insecure-Requests: 1" --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0" https://localhost:8080/
--libcurl
The --libcurl command allows you to generate libcurl source code from the command line.
curl --header "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" --compressed --header "Accept-Language: en-US,en;q=0.5" --header "Connection: keep-alive" --header "Sec-Fetch-Dest: document" --header "Sec-Fetch-Mode: navigate" --header "Sec-Fetch-Site: none" --header "Sec-Fetch-User: ?1" --header "Upgrade-Insecure-Requests: 1" --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0" https://localhost:8080/ --libcurl coolcode.c
TLS Versions
Curl uses latest versions, ciphers automatically
-1, --tlsv1, --tlsv1.0
Use TLSv1.0 or greater
curl --tlsv1 https://example.com
--tlsv1.1
Use TLSv1.1 or greater
curl --tlsv1.1 https://example.com
--tlsv1.2
Use TLSV1.2 or greater
curl --tlsv1.2 https://example.com
--tlsv1.3
Use TLSV1.3 or greater
curl --tlsv1.2 https://example.com
--tls-max
Set maximum allowed TLS version
curl --tls-max 1.3 https://example.com
curl --cacert /etc/ssl/certs/ca-certificates.crt 'https://www.google.com'
--capath
CA directory to verify peer against
curl --cacert /etc/ssl/certs/ 'https://www.google.com'
-k, --insecure
Allow insecure server connections when using SSL, don't use insecure!
curl --insecure https://example.com
Online Certificate Status Protocol (OCSP) Stapling
Online Certificate Status Protocol (OCSP) is an internet protocol described in RFC2560 that checks the validity status of a certificate in real-time. It is an alternative to Certificate Revocation Lists (CRL) described in RFC5280.
curl --cert-status https://google.com/
Client Certificates
Client Certificates are digital certificates for users and individuals to prove their identity to a server. Client certificates tend to be used within private organizations to authenticate requests to remote servers.
curl --cert mycert:mypassword https://example.com
curl --cert mycert:mypassword --key mykey https://example.com
Ciphers
Cipher suites are a combination of ciphers used to negotiate security settings during the SSL/TLS handshake.
--ciphers
List of SSL ciphers to us
curl --ciphers ECDHE-RSA-AES128-GCM-SHA256 https://google.com/
--tls13-ciphers
List of TLS 1.3 ciphers to use
curl --tls13-ciphers TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384 https://google.com/
--proxy-ciphers
List of SSL ciphers to use for proxy
curl --proxy-ciphers ECDHE-RSA-AES128-GCM-SHA256 https://google.com/
TLS Backends
When curl is built, it gets told to use a specific TLS library (backend). That TLS library (backend) is the engine that provides curl with the powers to speak TLS over the wire.
SSLKEYLOGFILE
The curl command-line tool can push secrets to SSLKEYLOGFILE which can be read by Wireshark to decrypt traffic.
Set the SSLKEYLOGFILE environment variable pointing to a file.
Tell Wireshark to read from the SSLKEYLOGFILE.
Run curl
Read decrypted traffic in Wireshark
Proxy
A proxy server is a system or router that provides a gateway between users and the internet.
-x, --proxy
Use this proxy
curl -x myproxy.com:8080 https://reqbin.com/echo
Proxy Authentication
The authentication method that should be used to gain access to a resource behind a proxy server.
-U, --proxy-user
Proxy user and password
curl -x myproxy.com:8080 -U login:password https://reqbin.com/echo
--socks5‐basic
Enable username/password auth for SOCKS5 proxies
curl --socks5-basic --socks5 hostname:4096 https://example.com
--socks5‐gssapi
Enable GSS-API auth for SOCKS5 proxies
curl --socks5-gssapi --socks5 hostname:4096 https://example.com
--proxy-basic
Use Basic authentication on the proxy
curl --proxy-basic --proxy-user user:passwd -x proxy https://example.com
--proxy-digest
Use Digest authentication on the proxy
curl --proxy-digest --proxy-user user:passwd -x proxy https://example.com
--proxy-negotiate
Use HTTP Negotiate (SPNEGO) authentication on the proxy
curl --proxy-negotiate --proxy-user user:passwd -x proxy https://example.com
--proxy-ntlm
Use NTLM authentication on the proxy
curl --proxy-ntlm --proxy-user user:passwd -x http://proxy https://example.com
Proxy Environment Variables
Users may set proxy environment variables with [scheme]_proxy syntax. The curl command-line tool will check for their existence.
Set the environment variable
http_proxy=http://proxy.example.com:80
2. Make curl request
curl -v www.example.com
Proxy Headers
Use --proxy-header to set a header specifically for the proxy and NOT the remote server
--proxy-header
Pass custom header(s) to proxy
curl --proxy-header "User-Agent: magic/3000" -x proxy https://example.com/
HTTP
Hypertext Transfer Protocol (HTTP) is an application-layer protocol that serves as the foundational protocol for retrieving web resources, including HTML documents, and serves as the backbone for all data exchanges on the Internet. It operates as a client-server protocol, with requests typically initiated by the recipient, often a web browser.
HTTP Methods
HTTP request methods are commands used by a client to indicate the desired action for a resource on a web server, such as GET for retrieving data or POST for submitting data.
HTTP Headers in Terminal
A HEAD request is a type of HTTP request method used to retrieve only the headers of a resource without actually fetching the resource's body content.
-I, --head
Show document info only
curl --head http://example.com
HTTP Response Code
HTTP response status codes indicate whether a specific HTTP request has been successfully completed.
curl --write-out "Response Code: %{response_code}\n" http://example.com
-f, --fail
Fail silently (no output at all) on HTTP errors
curl https://curl.se/download/curl-yadayada -O --fail
HTTP Response Headers
A response header is an HTTP header that can be used in an HTTP response and that doesn't relate to the content of the message.
-v, --verbose
Make the operation more talkative
curl -v https://petergirnus.com/
-I, --head
Show document info only
curl -I https://petergirnus.com/
-D, --dump-header
Write the received headers to file
curl -D headers.txt https://petergirnus.com/
HTTP Response Bodies
HTTP Message Body is the data bytes transmitted in an HTTP transaction message immediately following the headers
-o, --output
Write to file instead of stdout
curl -o out https://example.com
-O, --remote-name
Write output to a file named as the remote file
curl -O https://example.com/a.html
--compressed
Request compressed response, will uncompress automatically
curl -O --compressed https://example.com/a.html
HTTP Authentication
HTTP Authentication is defined in RFC7235 which can be used by a server to challenge a client to authenticate.
401 Unauthorized
The HyperText Transfer Protocol (HTTP) 401 Unauthorized response status code indicates that the client request is unauthorized and must authenticate.
407 Proxy Authentication Required
The HTTP 407 Proxy Authentication Required client error status response code indicates the client request is unauthorized and must authenticate to a proxy between it and the server.
-u, --user
Server user and password
curl -u peter:1234 https://example.com/a.html
--anyauth
Pick any authentication method, use most secure method the remote server supports.
curl --anyauth --user me:pwd https://example.com
--basic
Use HTTP Basic Authentication, explicitly request this method.
curl --basic --user me:pwd https://example.com
--digest
Use HTTP Digest Authentication
curl --digest --user me:pwd https://example.com
--ntlm
Use HTTP NTLM authentication
curl --digest --user me:pwd https://example.com
--ntlm-wb
Use HTTP NTLM authentication with winbind
curl --ntlm-wb --user me:pwd https://example.com
--negotiate
Use HTTP Negotiate (SPNEGO) authentication
curl --negotiate -u : https://spnego-enabled-site/file
HTTP Ranges
An HTTP Range request in which the server is asked to send only a portion of the HTTP server back.
-r, --Range
Retrieve only the bytes within RANGE
curl -O --range 500-999 https://curl.se/download/curl-8.2.1.tar.gz
-C, --continue-at
Resumed transfer offset
curl -O --continue-at 999 https://curl.se/download/curl-8.2.1.tar.gz
HTTP Versions
HTTP (HyperText Transfer Protocol) has undergone many changes in it’s evolution from from a laboratory environment in 1989 to today’s modern world wide web.
--http0.9
Allow HTTP 0.9 responses
curl --http0.9 https://example.com/file.txt
--http1.0
Use HTTP 1.0
curl --http1.0 https://example.com/file.txt
--http1.1
Use HTTP 1.0
curl --http1.1 https://example.com/file.txt
--http2
Use HTTP 2
curl --http2 https://example.com/file.txt
--http3 (Experimental)
Use HTTP 3
curl --http3 https://example.com/file.txt
--http2-prior-knowledge
Use HTTP 2 without HTTP/1.1 Upgrade
curl --http2-prior-knowledge https://example.com/file.txt
What HTTP version does the server support?
curl -sI https://curl.se -o/dev/null -w '%{http_version}\n'
curl -sI --http3 https://curl.se -o/dev/null -w '%{http_version}\n'
HTTP Time Based Conditions
Transfer resource only if… Newer
curl --time-cond “Wed 01 Sep 2021 12:18:00” https://example.com/file
Transfer resource only if… Older
curl --time-cond “-Wed 01 Sep 2021 12:18:00” https://example.com/file
Transfer resource only if… newer than local file
curl --time-cond file https://example.com/file
-R, --remote-time
Set the remote file's time on the local output
curl -R -O https://example.com/file
HTTP Entity Tag (ETags)
The Entity Tag (ETag) is an identifier for a specific version of a resource.
--etag-save
This option saves an HTTP ETag to the specified file.
curl --etag-save remember -O https://example.com/file
--etag-compare
This option makes a conditional HTTP request for the specific ETag read from the given file by sending a custom If-None-Match header using the stored ETag.
curl --etag-compare remember -O https://example.com/file
Transfer resource only if … resource is different
curl --etag-save remember --etag-compare remember -O https://example.com/file
curl -d 'name=admin&shoesize=12' https://example.com/
curl -d name=admin -d shoesize=12 https://example.com/
curl -d @filename http://example.com
--data-raw
HTTP POST data, '@' allowed
curl --data-raw '@string' https://example.com
--data-binary
HTTP POST binary data
curl --data-binary @filename https://example.com
HTTP POST: content-type
The content-type header is used to tell the server what the media (MIME) type of the resource the client is sending.
-d, --data defaults to Content-Type: application/x-www-form-urlencoded
curl -d dust -H 'Content-Type: stuff/dream' https://example.com
HTTP POST - JSON
--json
Sends a JSON object to a server
curl --json '{"tool": "curl"}' https://example.com/
Send a JSON file to a server
curl --json @json.txt https://example.com/
Send JSON from STDIN
echo '{"a":"b"}' | curl --json @- https://example.com/
Create JSON easily
jo -p name=jo n=17 parser=false | curl --json @- https://example.com/
Receive/parse JSON easily
curl --json '{"tool": "curl"}' https://example.com/ | jq
jo -p name=jo n=17 | curl --json @- https://example.com/ | jq
HTTP POST - URL Encoding
URL Encoding is a method to encode limited ASCII characters that conforms to the URI standard.
--data-urlencode
HTTP POST data url encoded
curl --data-urlencode "name=John Doe (Junior)" http://example.com
--data-urlencode [content] where content is…
anything - URL encode the content
=anything - URL encode the content (leave out the ‘=’)
any=thing - Send as “any=[URL encoded thing]”
@anything - Read content from file, URL encode and use
any@thing - Send as “any=[URL encoded file contents]”
HTTP POST - Convert to GET (query)
-G, --get
Put the post data in the URL and use GET
curl --get -d name=admin -d shoesize=12 https://example.com/
--url-query
This is the recommended way as it’s more convenient & powerfull!
curl --url-query name=mrsmith --url-query color=blue http://example.com
HTTP POST: Expect 100-continue
For HTTP/1.1 only, the HTTP 100 Continue header used by curl when POST or PUT greater than 1MB. Is used to avoid sending data when server refused data, when server responds with 100, continue transmission.
Disable 100 Continue
Can waste time as often ignored by servers, so disable with curl
curl -H Expect: https://example.com/
HTTP POST - Chunked
For HTTP/1.1 only, sends data without specifying transmission size at start.
curl -H "Transfer-Encoding: chunked" -d @file http://example.com
HTTP POST - <form>
Enter <form> fields with curl using a POST, use the action= attribute to see where to send POST request. Use the copy as curl option in the browsers developer tools.
HTTP multipart form-data
Use the Content-Type multipart/form-data media type which uses a series of parts with each part having it’s own name, header, file name, etc and it separated by a boundary.
-F, --form
Specify multipart MIME data as plain text
curl -F “name=Peter Girnus” http://127.0.0.1
Specify multipart MIME data as a file
curl -F file=<file.txt http://127.0.0.1
Specify multipart MIME data as a file upload
curl -F file=@file.txt http://127.0.0.1
Specify multipart MIME data as a file upload using a different file name
curl -F "file=@file.txt;filename=elif.txt" http://127.0.0.1
Specify multipart MIME data with custom content-type
HTTP Redirects
URL Redirects is technique in which the server redirects a client to another page, using a 3xx status code.
-L, --location
Follow redirects
curl -L https://google.com
--max-redirs
Maximum number of redirects allowed
curl -L --max-redirs 7 http://google.com
--location-trusted
Like --location but also send auth credentials to following hosts
curl --location-trusted -u peter:1234 https://google.com
HTTP Request Modification
-X, --request
Specify request command to use
curl -X POST -d "user=peter&role=admin" http://127.0.0.1
-H, --header
Pass custom header(s) to server
curl -H "User-Role: Admin" http://127.0.0.1
Add an HTTP header
curl -H "curl-master: very-soon" http://example.com/
Change an HTTP header
curl -H "Host: test.example" http://example.com/
Remove an HTTP header
curl -H "User-agent:" http://example.com/
Blank HTTP header
curl -H "User-agent;" http://example.com/
--request-target
Specify the target for this request
curl http://127.0.0.1 --request-target http://leet.com/path/ -H "Host: 0x1337"
--user-agent
Send User-Agent <name> to server
curl --user-agent "0x007" http://127.0.0.1
-e, --referer
Referrer URL
curl --referer http://really.google.com http://127.0.0.1
HTTP PUT
The HTTP PUT method creates or replaces a resource on a target.
-T, --upload-file
Transfer local FILE to destination and/or replace
curl -T localfile https://example.com/destination/replacement
Transfer from STDIN to destination and/or replace
curl -T - https://example.com/destination/replacement
Transfer local file to destination and place as local filename
curl -T file https://example.com
Use globbing techniques to PUT multiple files
curl -T "img[1-1000].png" http://example.com/images/
curl --upload-file "{file1,file2}" https://example.com
Living on the rebellious side with -X and -d
curl -d "data to PUT" -X PUT http://example.com/new/resource/file
HTTP Cookies
An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to a user's web browser. The browser may store the cookie and send it back to the same server with later requests. Typically this cookie is used to store sessions, personalize the browser experience, and tracking the user.
HTTP Cookies - Sending
-b, --cookie
Send cookies from string/file
curl -b "name=daniel;talks=alot" http://127.0.0.1
HTTP Cookies - Start Engine
By default curl ignores cookies, you need to enable cookies first. Cookies are stored in memory, forgets cookies that expire, and sends cookies according to the rules.
Start cookies with a blank string or read to file.
curl -b "" https://example.com
Start cookies combined with redirect following.
curl -L -b "" https://example.com
HTTP Cookies - Cookie Jar
Since curl defaults to saving cookies in memory if we need to save cookies we can do so with -c, --cookie-jar, which saves cookies to a file. The cookie jar is a readable text file, uses the netscape cookie format, and includes sessions.
-c, --cookie-jar
Write cookies to <filename> after operation
curl -L -b "" -c cookies.txt https://example.com
Read from and write to the cookie jar (can be different files)
curl -L -b cookies.txt -c cookies.txt https://example.com
HTTP cookies - Session
When interacting with sessions curl does not know when a session ends. You need to specify when a new session starts.
-j, --junk-session-cookies
Ignore session cookies read from file
curl -j -b cookies.txt https://example.com
HTTP/2
By default curl attempts to negotiate HTTP/2 for all HTTPS transfers. You can ask curl to use HTTP/2 for HTTP transfers with the --http2 option. With HTTP/2 curl can do multiplexed transfers with -Z, --parallel
-Z, --parallel
Perform transfers in parallel
curl --http2 --parallel --config urls.txt
--parallel-immediate
Do not wait for multiplexing (with --parallel)
curl --http2 --parallel --parallel-immediate --config urls.txt
--parallel-max
Maximum concurrency for parallel transfers
curl --http2 --parallel --parallel-immediate --parallel-max 3 --config urls.txt
HTTP/3
In HTTP/3 is done over Quick UDP Internet Connections (QUIC), a new transport protocol.
In curl the HTTP protocol differences are obfuscated from the user, HTTP/3 is experimental in curl and it only available for HTTPS with the --http3.
--http3 races against HTTP/1 and HTTP/2 and picks a winner.
-Z, --parallel
Perform transfers in parallel
curl --http3 --parallel --config urls.txt
--parallel-immediate
Do not wait for multiplexing (with --parallel)
curl --http3 --parallel --parallel-immediate --config urls.txt
--parallel-max
Maximum concurrency for parallel transfers
curl --http3 --parallel --parallel-immediate --parallel-max 3 --config urls.txt
HTTP alt-svc
The Alt-Svc Header allows a server to indicated another location in the network can be treated as the authority when making requests.
--alt-svc
Enable alt-svc with this cache file
curl --alt-svc altcache.txt https://example.com/
HTTP - HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (HSTS) is a standard to protect web users by ensuring that their browsers always connect to a website over HTTPS. Uses the Strict-Transport-Security response header. With curl the HSTS data can be saved and can be used later.
--hsts
Enable HSTS
curl --hsts hsts.txt http://example.com/
File Transfer Protocol (FTP)
File Transfer Protocol (FTP) is a way to download, upload, and transfer one network location to another. Originally built on top of the Network Control Protocol (NCP) or ARPANET which uses a simplex protocol that uses two port addresses, establishing two connections. The 2nd connection server-to-client (active) or client-to-server (passive)
--ftp-pasv
Use PASV/EPSV instead of PORT
curl -O --ftp-pasv ftp://127.0.0.1/demo.zip
-P, --ftp-port
Use PORT instead of PASV
curl -O --ftp-port 127.0.0.1 ftp://127.0.0.1/file.txt
FTP Authentication
By default the user: anonymous password:ftp@example.com
-u, --user
Server user and password
curl -O -u peter:1234 --ftp-pasv ftp://127.0.0.1/demo.zip
FTP Directory Listing
With FTP curl can list the contents of a remote directory, use trailing /
curl ftp://example.com/pub/linux/
l, --list-only
List only mode, show only file names
curl --list-only ftp://example.com/pub/linux/
FTP Upload
Like other protocols use the -T, --upload-file command. Normally requires -u, --user to allow uploads.
-T, --upload-file
Transfer local FILE to destination with different name
curl -T localfile ftp://example.com/pub/linux/newfilename
Transfer local FILE to destination
curl -T localfile ftp://example.com/pub/linux/
-a, --append
Append to target file when uploading
curl --append -T localfile ftp://example.com/pub/linux/
--ftp-create-dirs
Create the remote dirs if not present
curl --ftp-create-dirs -T localfile ftp://example.com/pub/linux/
FTPS - FTP-Secure or FTP Secure
FTPS (FTP-Secure or FTP Secure) is an extension of FTP with the addition of Transport Layer Security (TLS) formerly Secure Sockets Layer (SSL) for added data security.
--ssl-reqd
Require SSL/TLS
curl --ssl-reqd ftp://example.com
Use FTPS:// if using (rare) implicit TLS. However, using this option is more problematic for stateful firewalls to handle.
Conclusion
The Mastering the Curl Command Line (slides) with Daniel Stenberg (@badger) was a massive talk that dove into great detail on this amazing tool from the author himself! If you’d like to learn more about curl you can visit the official Everything curl guide as well check out the official GitHub Repo. While you’re at it be sure to check out the curl releases webpage which gives information such as curl version, data, bugfixes, changes, and vulnerabilities.
I hope you found this cheatsheet helpful and happy curling!