Unit 4 covered where extra information such as Content-Type travels in an HTTP message.
In headers, the Name: value lines before the blank line.
Headers carry metadata in both directions, as lessons 4-1 and 4-2 showed. This unit is about the two headers that give the stateless web a memory: Set-Cookie coming down, and Cookie going back up.
Every request is a stranger
HTTP is stateless: the server handles each request on its own and remembers nothing afterwards. Request #2 does not know request #1 happened. So how does a site keep you logged in across hundreds of requests?
Cookies. A cookie is a small piece of text the server asks the browser to remember, using the Set-Cookie response header:
HTTP/1.1 200 OK Set-Cookie: session=abc123; Path=/; HttpOnly; Max-Age=3600
The part before the first ; is the actual cookie: a name (session) and a value (abc123). Everything after are attributes, instructions about how to handle it:
Path=/: send it with requests to every path on this siteHttpOnly: page JavaScript cannot read it (protects it from scripts)Max-Age=3600: forget it after 3600 seconds
From then on, the browser automatically attaches the cookie to every request to that site, in the Cookie request header:
GET /inbox HTTP/1.1
Host: example.com
Cookie: session=abc123Parsing a Set-Cookie header
The same trimming patterns from lesson 1-2: cut off the header name, keep what is before the first semicolon, then split on =.
header="Set-Cookie: session=abc123; Path=/; HttpOnly; Max-Age=3600" raw=${header#Set-Cookie: } cookie=${raw%%;*} name=${cookie%%=*} value=${cookie#*=} echo "name: $name" echo "value: $value"
Output
name: session value: abc123
Four trims, each removing one layer. The header name goes first, then the attributes, then the name and value separate from each other.
Note that ${cookie#*=} uses the single # for the shortest match, which is deliberate. A cookie value containing an = would survive intact, whereas the doubled form would have cut at the last one and lost part of the value.
That is a real concern rather than a hypothetical, since session tokens are often base64 text, and base64 padding is made of = characters.
Listing the attributes
Strip everything through the first ; , then turn the remaining semicolons into newlines.
header="Set-Cookie: session=abc123; Path=/; HttpOnly; Max-Age=3600" attrs=${header#*; } echo "$attrs" | tr ';' '\n' | while read -r attr; do echo "attribute: $attr" done
Output
attribute: Path=/
attribute: HttpOnly
attribute: Max-Age=3600Reading the pipeline
${header#*; }removes everything up to and including the first;, leavingPath=/; HttpOnly; Max-Age=3600.tr ';' '\n'replaces each remaining semicolon with a newline, which turns one line into three so the loop can read them.read -rstrips the leading spaces for you, so each$attrcomes out clean without extra trimming.- Notice
HttpOnlyhas no value at all. Cookie attributes are a mix ofName=valuepairs and bare flags, so any real parser has to handle both shapes.
How the value gets back
The browser automatically adds a Cookie: session=abc123 request header.
That automatic echo is the whole mechanism. The server sets the cookie once, and the browser attaches it to every later request to that site without any code or any user action.
The site can then recognize request 500 as the same visitor as request 1, which is how a stateless protocol supports something as stateful as being logged in.
The automation is also the reason cookies need attributes. Since the browser sends them without being asked, Path, Max-Age, and HttpOnly exist to limit where they go, how long they last, and who can read them.