Dissecting what actually happens behind a single curl command line: from URL parsing, DNS resolution, TCP and TLS connection, to sending and receiving responses, plus getting to know the core options and exit codes.

After understanding curl's history and background in episode 1 — born from httpget in 1996, unified as curl in 1998, with libcurl as its engine — now it's time to dissect how curl works from the inside. This episode is the bridge between "why curl exists" and "how to use it", so pay close attention to the flow.
Many curl users treat it like a photocopier: press a button, see the result. But behind a single line of curl https://example.com there's a sequence of events that's orderly and predictable. Understanding this sequence — like opening the hood before driving — will make you far more confident when results don't match expectations, and it becomes the foundation for the verbose episode in episode 3.
Every time curl runs, it goes through the same six stages. Think of it like sending a package through a courier:
https, curl exchanges certificates and encryption keys. This is like showing identification and agreeing on a secret password.This pattern applies to all protocols supported by curl, not just HTTP. That's why understanding these six stages gives you a general capability that's never tied to any single protocol.
In episode 1 we mentioned that curl has two faces: the CLI and libcurl. The relationship is this: libcurl is the engine, the CLI is the steering wheel.
When you type a curl command in the terminal, what happens is: the CLI program reads your options, translates them one by one into libcurl settings, then calls the perform function to run all six transfer stages above. The result is returned to the CLI for display.
An important consequence of this design: every CLI option has a counterpart in libcurl. The -L option means CURLOPT_FOLLOWLOCATION, the -d option means CURLOPT_POSTFIELDS. You don't need to memorize the C names now — just understand that everything you learn in the CLI also applies in the library world.
Curl has more than 250 options, but don't panic. Just like learning a foreign language — start with the most frequently used vocabulary. The six options below are required vocabulary we'll deepen in the following episodes:
| Option | Long form | Function |
|---|---|---|
-X | --request | Set the HTTP method explicitly |
-d | --data | Send data in the request (usually POST) |
-H | --header | Add or modify a request header |
-o | --output | Write the result to a file, not the screen |
-L | --location | Follow redirects sent by the server |
-u | --user | Send user credentials and password |
The reading pattern is easy: short options use one dash (-d), long options use two dashes (--data). Both are equally valid and often interchangeable.
curl -L https://example.com
curl --location https://example.comEvery time curl finishes, it "speaks" through an exit code — a number returned to the shell. This is curl's primary signaling system for scripting, and the rule is very simple: 0 means success, anything else means there's a problem.
curl -s https://example.com
echo $?curl -s https://domain-yang-tidak-ada-xyz.example
echo $?In the second example, you'll see exit code 6 — meaning curl failed to resolve that host's DNS. Each number has a specific meaning documented in man curl under the EXIT CODES section. Some of the most common:
| Exit Code | Meaning |
|---|---|
| 0 | Success |
| 6 | Could not resolve host |
| 7 | Failed to connect to host |
| 28 | Timeout |
| 35 | TLS/SSL problem |
Tip
Exit codes are curl's main language for scripts. When you write if curl ...; then or curl ... || exit 1, you're reading this language. Later in the scripting episode, the habit of checking exit codes will separate reliable scripts from "just okay" ones.
One of the biggest beginner misconceptions is thinking curl "downloads a file to disk". The fact is: curl writes the output to stdout (screen) and doesn't touch any file unless you ask it to.
curl https://example.comWhat do you see? Only the HTML body, no headers, no saved file. To save to a file, you need -o (with a name you choose) or -O (with the file name from the URL). The overview:
| Command | Behavior |
|---|---|
curl URL | Body to screen, headers hidden |
curl -o name.html URL | Body saved to name.html |
curl -O URL | Body saved with the file name from the URL |
curl -i URL | Headers also displayed before the body |
curl -I URL | Headers only, sends a HEAD method |
The practical consequence: you can pipe curl's output straight into another program — curl -s URL | jq . — without the hassle of saving an intermediate file. This is a pattern you'll use every day.
Important
Remember this golden rule: curl doesn't write files unless asked. If you run curl URL expecting a file to be saved, you'll be disappointed — the output flows to the screen (or can be redirected with >). Get used to using -o to save, or redirect stdout. In the download episode later, we'll see -O which saves with the remote name.
Here's a short decision map you'll often face:
| You want... | Use |
|---|---|
| Display only the body | curl URL |
| Save the body to a file | -o name or -O |
| Follow redirects | -L |
| Add a custom header | -H |
| Send data (POST) | -d |
| Use a method other than GET | -X |
In this episode 2, you've dissected curl's architecture from the inside: the six transfer stages (parse URL, resolve DNS, connect TCP/TLS, send request, receive response, show output), the relationship of libcurl as the engine and the CLI as the steering wheel, six core options that will become required vocabulary, the exit code language, and the golden rule that curl doesn't write files unless asked.
Key takeaways:
-o, -O, -i, -I, -X, -d, -H, -L, -u are your starter vocabulary.In the next episode 3, we'll start the real hands-on work: basic HTTP requests — running your first GET to https://example.com, understanding the difference between GET and HEAD with -I, and dissecting the verbose -v output line by line so you can "read" what happens in every connection. See you in episode 3!