cURL tips and tricks
cURL1 (or curl as I will refer to it for the rest of the article) is an incredible tool and a worthy asset in your developer toolkit. Like every great craftsman, you as a developer deserve great tools. Granted curl can be daunting and seemingly tough to learn at first, I promise you its worth your investment. This is a write up of basic to more advanced tips and tricks that I accumulated of the years of reading blog posts, curl man pages, StackOverflow, …
The basics 📓
Let’s start with some basic commands to get data from the server and also let’s figure out how we can send data. Feel free to execute these commands step by step while you go through the article.
First of let’s try a simple GET request.
If all goes well you should be presented with a response quite similar to this one:
That was quite easy, wasn’t it? Learning curl with httpbin is quite nice because it echoes whatever you send to it right back at you. So now what if we just want to send a HEAD
request:
Are there any other types of requests we can send?
The -X
parameter allows you to change the method. The following methods are supported:
- GET
- POST
- PATCH
- PUT
- DELETE
Right now what happens if we send a request to a server and get redirected. Before running the next command try requesting https://httpbin.org/redirect-to?url=https://www.google.com
with the commands you already know.
So how do we follow the redirect with curl
?
As it sounds, such a request follows the Location header to reach the endpoint.
Tip: HTTP response codes The first digit of an HTTP response defines the error group:
- 1xx: informational
- 2xx: success
- 3xx: redirections
- 4xx: client-side errors
- 5xx: server-side errors
And oh yeah you can also customize the headers you send over via curl::
Cookies 🍪
Nom nom cookies. HTTP Cookies are key/value pairs that a client stores on behalf of the server. They are sent back and forth on every request to allow clients to store state between requests. curl
has a couple of ways to allow a cookie to be sent to the server. In it’s simplest form you can just use --cookie
:
Get a cookie from the server and write it to a file.
You can add -i
to print the headers and do some debugging. With -L
like you learned earlier you can follow the redirect. This will then print the cookies.
You can get the current cookies back with -b
.
Tip: Cookie file format?
cURL uses a cookie format called Netscape, which each line is a single piece of information represented by following fields (read from left-to-right):
JSON Combo {}
Most of the time I use curl to request resources that return a JSON response. These can become long and as just plaintext hard to reason with, parse or filter. For that, we will need to create a combo with an amazing tool called jq
. It’s free to install on most operating systems:
Let’s start with piping a JSON response from curl directly into jq
.
Now that’s pretty neat, we get our JSON response back and thanks to some colouring form jq
we can more easily digest the response. We could also try and filter the response and just select the id.
There is much more you can accomplish by combining curl
and jq
. jq
has amazing documentation https://stedolan.github.io/jq/manual that can help you learn more about how to use it.
Uploading ⬆️
Ok, let’s look at some more advanced commands we can construct and figure out if we can upload or download a file.
-T
Uploads the given file--date @filename
yes you can use the the--data
or-d
parameter with an@
to simply upload a file
Sometimes you might get some data via a pipe, even in this case curl got your back:
To download a file from a server you use -o
, the next argument will be the name of the file after it is downloaded.
You can also use capital o -O
this will create a file named exactly like it was on the server.
But wait I got a form that gets posted and I need to fill in some data. No worries curl still got you covered.
This is an example of a multipart form post.
Authentication
Basic authentication
Capital -U is used for proxy authentication
Little gems 💎
Do you support HTTP/2 or HTTP/3?
HTTP/3 needs to be explicitly enabled during the build process. Please refer to this upgrade guide if you want to play with it: https://github.com/curl/curl/blob/master/docs/HTTP3.md
Another interesting gem:
Don’t squash sequences of /../ or /./ in the given URL path.
Writes out information after transfer has completed by using a special %{variable}. 2