A request and a reply, in plain text
In the previous guide you opened a socket and saw the client-server arrangement: one side listens, the other connects, and bytes flow through a door the operating system holds open. But once that door is open, what do the two sides actually say to each other? On the Web the answer is HTTP, the HyperText Transfer Protocol. HTTP lives at the application layer, the very top of the stack, riding on the reliable byte stream that TCP provides underneath.
The first surprising thing about HTTP is how plain it is. It is a text protocol: the message a browser sends is just lines of ordinary readable characters, the kind you could type by hand. A request starts with one line naming a method and a path, then a stack of headers, a blank line, and an optional body. The reply has the same skeleton: a status line, headers, a blank line, then the body, which is usually the HTML or image or JSON you asked for. The whole web rests on this one tidy shape.
REQUEST (browser -> server) RESPONSE (server -> browser)
----------------------------------- -----------------------------------
GET /index.html HTTP/1.1 HTTP/1.1 200 OK
Host: example.com Content-Type: text/html
User-Agent: Firefox/123 Content-Length: 1270
Accept: text/html Cache-Control: max-age=3600
<blank line>
<blank line> <!doctype html> ...the page...
^ method ^ path ^ version ^ version ^ code ^ phraseThe URL: a precise address for a thing
Before the browser can send anything, it needs to know where to send it and what to ask for. That is the job of the URL, the web address you type or click. A URL packs several layers of addressing into one string, and reading it left to right is like reading a postal address from country down to apartment.
Take https://example.com:443/photos/cat.jpg as an example. The scheme https tells the browser which protocol and whether to wrap it in TLS. The host example.com is a domain name that DNS, the Internet's phone book from the earlier rung, turns into an IP address. The port 443 is the apartment number on that machine (it is usually left out because https implies 443). And the path /photos/cat.jpg names the specific resource the server should fetch or build. Same scheme, same host, but two different paths are two completely different requests.
Methods and status codes: verbs and verdicts
That first word of the request, GET, is the method, and it is the verb of the sentence. The HTTP request methods are a small, deliberate vocabulary. GET means "give me this resource" and should change nothing on the server. POST means "here is some data, do something with it", like submitting a form. PUT means "store this here", DELETE means "remove it", and HEAD means "send me only the headers, not the body". The discipline that GET only reads while POST may change things is called safety, and a method you can repeat without extra effect (like PUT or DELETE) is called idempotent. These are conventions the Web agreed on, not rules TCP enforces.
The reply opens with a three-digit status code that is the server's verdict on what happened. The first digit sorts them into families. 1xx is informational and rare. 2xx means success, and 200 OK is the one you want. 3xx means redirection, go look elsewhere; 301 says "moved permanently". 4xx means you, the client, made a mistake, and the famous 404 Not Found and 403 Forbidden live here. 5xx means the server broke, like 500 Internal Server Error or 503 Service Unavailable. Knowing just the first digit usually tells you who is at fault.
Headers: the metadata that makes it work
The lines between the first line and the blank line are the HTTP headers, a stack of name-value pairs that carry everything about the message except the content itself. They are the labels and instructions written on the outside of the parcel. Content-Type says what kind of thing the body is (text/html, image/jpeg, application/json), so the browser knows whether to draw a page or show a picture. Content-Length says how many bytes the body has, so the receiver knows when it has read the whole thing.
Other headers negotiate and instruct. Accept lets the client say "I would prefer HTML, but JSON is fine". Cache-Control tells caches how long they may keep a copy, which connects to the web-caching and CDN ideas from earlier. Authorization carries credentials. The beauty of headers is that they are open-ended: new ones can be added without changing the core protocol, which is a big part of why HTTP has stayed useful for over thirty years. The header block is where most of HTTP's flexibility lives.
One connection, many requests
A modern web page is not one file. It is an HTML document plus dozens of images, stylesheets, scripts and fonts, each its own resource at its own path. The earliest HTTP opened a fresh TCP connection for every single one of those, paid the three-way handshake cost again and again, and tore it down after one reply. On a page with fifty assets that is fifty handshakes, and remember from the earlier rung that a handshake costs a full round trip you cannot speed up by buying more bandwidth, because you cannot beat the speed of light.
The fix is the persistent connection, the default since HTTP/1.1. Instead of slamming the door after one reply, the client and server keep the same TCP connection open and reuse it for request after request. One handshake, then a stream of requests and replies down the same pipe. This single change cut page-load times dramatically, because the expensive setup is paid once rather than per resource.
HTTP/1.1 even let the client fire several requests back to back without waiting for each reply, an idea called pipelining. But there was a catch that haunts the next guide in this rung: the replies had to come back in the exact order the requests went out, so one slow response stalled everything queued behind it. That is head-of-line blocking, and beating it is precisely the story of HTTP/2 and HTTP/3. For now, hold the picture: persistent connections made HTTP fast, but they did not yet make it parallel.
HTTP remembers nothing
Here is the design choice that shapes everything built on top of HTTP: it is a stateless protocol. Each request is handled on its own, as if the server had never seen you before. The server does not, by itself, remember that you logged in two requests ago, or what is in your shopping cart. When this request finishes, as far as HTTP is concerned, you are a stranger again.
That sounds like a flaw, but it is a deliberate and powerful trade-off. Because no request depends on the memory of a previous one, any server in a fleet can answer any request, which is exactly what lets CDNs and load balancers spread millions of users across many machines, like a chain of identical local warehouses any of which can fill your order. The cost is that genuine continuity, staying logged in, keeping a cart, has to be rebuilt on top, and the very next guide shows how cookies do that. Statelessness is not HTTP forgetting by accident; it is HTTP refusing to remember on purpose, and getting scalability in return.