Cookies
HTTP, at heart, has no memory: each request
arrives as if from a stranger. Cookies
are the workaround. A server hands your
client a name-and-value pair in a
Set-Cookie header — "remember this" — and
the client presents it on later requests,
which is how logins survive from one page to
the next. curl, being a tool that does
exactly what it's told, does none of this by
default: no jar, no memory. You switch each
half on explicitly.
Receiving: -c saves the jar
$ curl -s http://127.0.0.1:8901/whoami
No cookie sent.
$ curl -s -c jar.txt http://127.0.0.1:8901/set-cookie
Cookie set. Now visit /whoami.
$ cat jar.txt
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE / FALSE 0 session specimen-abc123
Before the cookie: /whoami, the lab's
cookie echo, reports none sent. -c
(--cookie-jar) tells curl to write any
cookies the response sets into jar.txt —
here, the server set session=specimen-abc123,
and the jar's last line is that cookie in
the ancient Netscape format: domain, a flag
for subdomains, path, "secure connections
only?", expiry (epoch seconds; 0 means a
session cookie, gone when the browser
would close), name, value, tab-separated.
The file is plain text and yours to inspect
— do look; cookies that surprise you are
common.
Sending: -b presents cookies
Writing the jar only saved the cookie. The
first /whoami above was before, and a
second request without -b would still be a
stranger. -b (--cookie) is the sending
half:
$ curl -s -b jar.txt http://127.0.0.1:8901/whoami
Cookie received: session=specimen-abc123
Given a filename, -b reads the jar and
sends every cookie whose domain and path
match the request. Given a string containing
=, it sends that literally, no file
involved:
$ curl -s -b 'session=specimen-abc123' http://127.0.0.1:8901/whoami
Cookie received: session=specimen-abc123
Same result, nothing stored. (That = is
how curl tells a value from a filename: no
=, it assumes a file.) The inline form is
handy for one request with a token a
program handed you; the jar is the form that
scales, because real sites set several
cookies, rotate them, and expire them.
The session pattern
Most cookie work is one ritual: log in once, then make several requests as the logged-in client. Both flags on every call, same jar:
curl -s -b jar.txt -c jar.txt -d 'user=...&pass=...' https://site/login
curl -s -b jar.txt -c jar.txt https://site/account
curl -s -b jar.txt -c jar.txt https://site/settings
(Shown as a pattern, not a capture — the
lab's one cookie can't act out a whole login
dance, and the shape is what matters.) Read:
-b presents what we hold; -c writes back
whatever the server set or refreshed. The
jar evolves exactly as a browser's does,
minus the browser.
Respect what the jar is: a file full of
bearer credentials. A session cookie is
chapter 5's token wearing a different hat —
whoever reads jar.txt can be you, at that
site, until it expires. Keep jars out of
repositories, don't email them, give script
jars their own directory with private
permissions, and let --cookie-jar paths in
old scripts be a small red flag when you
audit them. The companion risk runs the
other way too: a jar you accept from
somewhere and -b at a site carries cookies
you never inspected.
Check: after -c, jar.txt exists and
names the session cookie; -b jar.txt at
/whoami is greeted by name; without either
flag the lab still sees a stranger. If a
real site's flow breaks for you, chapter 3's
-v shows the Cookie: header (or its
absence) on the way out and every
Set-Cookie on the way back — cookies,
debugged, are just headers with a memory.
Next: TLS — the padlock, and the one option that removes it.