TMIMI Explains

Explains Web Foundations 01 · HTTP

What does a client actually say to a server?

A few lines of text, always in the same shape. Here are real requests from a laptop browser, a phone and a command-line tool, the four main methods on one order, and the answers that came back.

Poster of the episode 01 film: What does a client actually say to a server?

Film coming soon

Short film · 4:31 · English narration (synthetic voice) · captions Watch on YouTube Everything in the film is on this page.

The short answerA request is a few lines of text: a first line with a method, a path and the version; headers, one per line; an empty line; and, when the client sends data, a body. The server answers with a status line that holds a three-digit status code, headers, an empty line, and usually a body. A browser, an app, a phone or a thermostat all send the same kind of message. The rules for these messages are HTTP, the Hypertext Transfer Protocol. Every message must respect this shape. What each method means is a convention, written in the standard. Following it is the server’s choice, and browsers and tools expect it to.

Two roles, many clients

Every exchange has two roles. The client asks. The server answers. Both are programs: the HTTP standard calls a client “a program that establishes a connection to a server” to send requests, and a server a program that accepts connections to answer them.

The client can be almost anything. A browser is the one you know, but the standard itself says browsers are “only a small percentage” of the kinds of client that exist. It lists others: “command-line tools, billboard screens, household appliances, scales, light bulbs, firmware update scripts, mobile apps”. Whatever the client is, the mechanism is the same.

Client
  • A browser on a laptop
  • A desktop app
  • A mobile app
  • The software in a small device, like a thermostat
Server
A program, on an ordinary computer
Four kinds of client, one mechanism: ① the client sends a request, ② the server sends back a response.

The client speaks first. A server waits for requests and answers them; it never starts an exchange on its own. The standard puts it simply: servers “only expect a request”, and clients “only expect a response”. Episode 02 shows why this rule matters for your home router.

A server is only a program, not a special machine. It can even run on your laptop: in this episode, it does. And a server can also be a client. When it calls another server, it sends its own request.

Client and server are roles, not machines Your browser sends a request to a shop’s server: the browser is the client and the shop’s server is the server. The shop’s server then sends its own request to a payment service: now the shop’s server is the client and the payment service is the server. Your browser CLIENT Shop’s server SERVER CLIENT Payment service SERVER request 1 request 2 Client and server are roles, not machines Your browser sends a request to a shop’s server: the browser is the client and the shop’s server is the server. The shop’s server then sends its own request to a payment service: now the shop’s server is the client and the payment service is the server. CLIENT Your browser request 1 SERVER Shop’s server CLIENT request 2 SERVER Payment service
The shop’s server answers your browser (it is the server), then asks a payment service to charge your card (now it is the client). Client and server are roles, not machines.

Three real requests, one shape

We ran a small orders service on a laptop at home. On the home network, the laptop’s address is 192.168.1.10, and the service answers on port 3000. Then three different clients asked it for the same order, http://192.168.1.10:3000/orders/42:

  • a browser on the laptop: Chromium 153;
  • a phone: Chrome 133 on Android 16, run in the Android Emulator;
  • a command-line tool: curl.exe 8.21.0, the one built into Windows.

Here is exactly what the service received from each, in the order it arrived. Nothing is left out or moved.

Laptop browser · Chromium 153 captured Sep 24, 2026
                GET /orders/42 HTTP/1.1
                Host: 192.168.1.10:3000
                Connection: keep-alive
                Upgrade-Insecure-Requests: 1
                User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36
                Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
                Accept-Encoding: gzip, deflate
                Accept-Language: en-US,en;q=0.9
                ↵ empty line
              
Phone · Chrome 133 on Android (emulator) captured Sep 24, 2026
                GET /orders/42 HTTP/1.1
                Host: 192.168.1.10:3000
                Connection: keep-alive
                Upgrade-Insecure-Requests: 1
                User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Mobile Safari/537.36
                Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
                Accept-Encoding: gzip, deflate
                Accept-Language: en-US,en;q=0.9
                ↵ empty line
              
Command-line tool · curl.exe 8.21.0 captured Sep 24, 2026
                GET /orders/42 HTTP/1.1
                Host: 192.168.1.10:3000
                User-Agent: curl/8.21.0
                Accept: */*
                ↵ empty line
              

The first line says what the client wants. It has a method, GET; a path, /orders/42; and the version of HTTP, HTTP/1.1. It is the same in all three requests.

The headers follow, one per line. Each header is a name, a colon, and a value. Host says which site the request is for. User-Agent says which client sent it. An empty line ends the headers. A GET normally carries no body, so nothing comes after it.

In HTTP/1.1, these lines are plain text: you could type them yourself. Each line ends with two invisible characters, a carriage return and a line feed.

What differs, and what doesn’t

  • The User-Agent. Each client describes itself: Windows NT 10.0 and Chrome/153, Android 10; K and Mobile, curl/8.21.0.
  • How many headers. Each browser sent 7; curl sent 3.
  • Their order. The browsers put User-Agent fourth; curl puts it right after Host.
  • The shape doesn’t change: a first line, headers, an empty line.

There is no fixed list of headers. The standard defines common ones, like Host, User-Agent and Content-Type, and there is an official register of many more. But a client can add any header, as long as it has that shape: a name, a colon, and a value.

  • A server ignores a header it doesn’t know. We sent our own header, Student: Salma, to the orders service and to example.com. Both answered 200 OK, as usual. You can try it below.
  • Servers and companies invent headers too. The answers from example.com carry two headers made up by Cloudflare, the company that serves the site: cf-cache-status and CF-RAY.
  • The shape has a few rules. A name has no spaces, and capitals don’t matter: host and Host are the same header. A value stays on one line.
  • Size has a limit. The standard sets none, but servers do. To a header of 20,000 characters, the orders service answered 431 Request Header Fields Too Large.

A User-Agent is self-declared. A client writes what it wants there. The phone runs Android 16, yet Chrome says Android 10; K: to reveal less about you, Chrome sends fixed values instead of the real version and phone model. The laptop runs Windows 11, and Chromium says Windows NT 10.0. Both browsers give only their main version number: Chromium 153.0.8010.12 says Chrome/153.0.0.0. And Windows PowerShell’s web command, captured the same day, starts its User-Agent with Mozilla/5.0, like a browser. A server can read this header, but it can’t trust it.

Both browsers then sent a second request of the same shape, for /favicon.ico: the small icon in the browser tab. Every request is a complete message on its own.

From the address bar to the request

The address you type is not sent as it is. The client splits it.

The address the browser opened

http://192.168.1.10:3000/orders/42

  • /orders/42goes into the first line: GET /orders/42 HTTP/1.1The path: what the client wants from this site.
  • 192.168.1.10:3000goes into the Host header: Host: 192.168.1.10:3000The site. Here, it is the laptop’s address at home and port 3000: episode 02 explains both.
  • http://is not in the request at all.It tells the client how to connect: also episode 02.
One address, split in two: the path goes into the first line, and the site’s name goes into Host.

The standard is strict about Host: it must be identical to the site part of the address, including the port when the address has one. A query string, such as ?page=2 in /orders?page=2, stays with the path in the first line. With https://, the client connects to port 443, unless the address gives another port, and it encrypts the whole message: first line, headers and body. What stays visible is episode 02 too.

Four methods on one order

The method is the verb of the request. We sent the four most common methods to the same orders service, with curl.exe. At the start, the service had one order: number 42, a notebook.

The four methods, sent to the same orders service
MethodFirst lineBody?Asks the server to…Typical success
GETGET /orders/42Nosend order 42200 OK
POSTPOST /ordersYesprocess this data; here, create a new order (the server picks its number)201 Created, with Location
PUTPUT /orders/42Yes: the complete orderreplace order 42 with this one (or create it)200 or 204; 201 if it created it
DELETEDELETE /orders/42Noremove order 42204, 200 or 202

The four real exchanges, in the order we sent them. Each request is on the left, and the server’s response on the right (below it on a phone).

GET reads order 42

“Show me order 42.”

① Request · curl.exe
                  GET /orders/42 HTTP/1.1
                  Host: 192.168.1.10:3000
                  User-Agent: curl/8.21.0
                  Accept: */*
                  ↵ empty line
                
② Response · the orders service
                  HTTP/1.1 200 OK
                  Content-Type: application/json
                  Content-Length: 40
                  Date: Thu, 24 Sep 2026 06:18:24 GMT
                  Connection: keep-alive
                  Keep-Alive: timeout=5
                  ↵ empty line
                  {"id":42,"item":"notebook","quantity":1}
                

Orders on the server: 42 · notebook × 1

POST sends data to process: a new order

“Here is a new order.”

① Request · curl.exe
                  POST /orders HTTP/1.1
                  Host: 192.168.1.10:3000
                  User-Agent: curl/8.21.0
                  Accept: */*
                  Content-Type: application/json
                  Content-Length: 28
                  ↵ empty line
                  {"item":"lamp","quantity":2}
                
② Response · the orders service
                  HTTP/1.1 201 Created
                  Content-Type: application/json
                  Content-Length: 36
                  Location: /orders/43
                  Date: Thu, 24 Sep 2026 06:18:24 GMT
                  Connection: keep-alive
                  Keep-Alive: timeout=5
                  ↵ empty line
                  {"id":43,"item":"lamp","quantity":2}
                

Orders on the server: 42 · notebook × 1 43 · lamp × 2 new

The request goes to /orders, not /orders/43: the server picks the new order’s number, then gives its address in Location.

PUT replaces order 42 with a complete new version

“Here is the whole of order 42.”

① Request · curl.exe
                  PUT /orders/42 HTTP/1.1
                  Host: 192.168.1.10:3000
                  User-Agent: curl/8.21.0
                  Accept: */*
                  Content-Type: application/json
                  Content-Length: 32
                  ↵ empty line
                  {"item":"notebook","quantity":3}
                
② Response · the orders service
                  HTTP/1.1 200 OK
                  Content-Type: application/json
                  Content-Length: 40
                  Date: Thu, 24 Sep 2026 06:18:24 GMT
                  Connection: keep-alive
                  Keep-Alive: timeout=5
                  ↵ empty line
                  {"id":42,"item":"notebook","quantity":3}
                

Orders on the server: 42 · notebook × 3 replaced 43 · lamp × 2

DELETE removes order 42

“Delete order 42.”

① Request · curl.exe
                  DELETE /orders/42 HTTP/1.1
                  Host: 192.168.1.10:3000
                  User-Agent: curl/8.21.0
                  Accept: */*
                  ↵ empty line
                
② Response · the orders service
                  HTTP/1.1 204 No Content
                  Date: Thu, 24 Sep 2026 06:18:24 GMT
                  Connection: keep-alive
                  Keep-Alive: timeout=5
                  ↵ empty line
                  no body
                

Orders on the server: 42 · notebook × 3 removed 43 · lamp × 2

  • The method only asks; the server decides. A server can refuse a method. example.com answers 405 Method Not Allowed to DELETE, PUT and POST: you can try it below.
  • GET and DELETE don’t carry a body. The standard gives data sent with them no general meaning, and some servers reject it.
  • To change only one field, APIs use another method, PATCH. It comes in module 5 of the JavaScript & Node.js course.

The body, and how the server knows its size

POST and PUT requests carry data. That data goes after the empty line: that part is the body. Two headers describe it. Content-Type says what the body is: here, application/json, data written as text. Content-Length says how many bytes it has, so the server knows where the message ends.

{"item":"lamp","quantity":2} 28 characters, 28 bytes: Content-Length: 28

{"item":"notebook","quantity":3} 32 characters, 32 bytes: Content-Length: 32

The first lines of an HTTP/1.1 message are always text, but the body can be anything: JSON here, an image or a video elsewhere. Some servers send the body in pieces instead, and say so with Transfer-Encoding: chunked; you will see it on example.com below.

The server is the boss. It decides which paths and methods it accepts, and what it does with them. And to the client, it is a black box: the client sees the answers, never the program inside.

So, like a restaurant, the server publishes a menu for its customers: the paths, the methods each one accepts, and what to send. Developers call it the API documentation. API stands for Application Programming Interface: the part of a server that programs talk to. The client reads the menu, and follows it.

Here is the menu of our orders service, written the way API documentation usually is. It describes what the service really did in our tests.

The orders service’s API documentation: each path, the methods it accepts, and what they do
Method and pathWhat it doesYou sendYou get back
GET /orders/{id}Reads one order.Nothing.200 and the order, in JSON. 404 if there is no such order.
POST /ordersAdds an order. The service picks its number.The order in JSON: item and quantity.201, the new order, and its path in Location.
PUT /orders/{id}Replaces an order with the one you send.The complete order, in JSON.200 and the order as stored.
DELETE /orders/{id}Removes an order.Nothing.204, with no body.

{id} stands for an order’s number, as in /orders/42. Any other method on these paths gets 405 Method Not Allowed, and an unknown path gets 404 Not Found. We checked both with PATCH /orders/42, GET /orders and GET /menu, sent to the service itself. Public services put their menu on their website, often in a standard format called OpenAPI, which tools can read too.

What every message must respect, and what is a convention

The shape is required. A first line; headers, each a name, a colon and a value; an empty line; and a body when the headers announce one. Break it, and the server can’t use the message: it refuses it, or waits for the rest. We tried it on the orders service:

  • no Host header: 400 Bad Request;
  • lines that end with a line feed only, without the carriage return: 400 Bad Request (the standard allows a server to accept this one, but ours didn’t);
  • no empty line: no answer at all, because the server kept waiting for the end of the headers.

What each method means is a convention, written in the standard. GET is “safe”: the client asks for no change. PUT and DELETE are “idempotent”: sending the same request twice has the same effect as sending it once. POST is neither.

Following the conventions is the server’s choice. A good server follows them. But the server is the boss, and nothing checks what it does inside its black box. It could add an order when it receives GET /orders/add?item=lamp. The message has the right shape, so it would work, until other programs meet it. Browsers and other tools all expect GET to only read:

  • Browsers may load a link before you click it, to save time. Each early load would add an order.
  • Search engines follow every link they find, with GET. Their robots would add orders all day.
  • Caches may answer a repeated GET with a copy they kept. The server never sees that request, so some orders would never be added.
  • After a network error, a browser may send the same GET again on its own, because repeating a read is supposed to be harmless.

The standard itself warns of “unfortunate side effects when automated processes perform a GET on every URI reference”. So two rules. As a client, read the server’s documentation, because only the server knows what it really does. When you build a server, follow the conventions: to add an order, use POST. They let every client work with every server.

The response and its status code

The server answers with the same shape. It starts with a status line: the version, a three-digit status code, and usually a short phrase. Then come headers, an empty line, and usually a body. Look at the DELETE above: 204 No Content has nothing after the empty line.

The first digit gives the family. A client must understand at least the family of every code it receives.

  • 2xx The 200s: success. 200 OK, 201 Created, 204 No Content.
  • 3xx The 300s: look somewhere else. 301: it moved. 304: use the copy you already have.
  • 4xx The 400s: the request has a problem. 404 Not Found, 405 Method Not Allowed.
  • 5xx The 500s: the server has a problem. 500 Internal Server Error: it failed.

There is a fifth family, 1xx: short information messages sent before the real answer, such as 100 Continue. You will rarely see them.

Your app asks for order 99 and gets 404 Not Found. Is the server down?

No. The server answered. It simply has no order 99. A status code is an answer.

GET asks for order 99

The service has no order 99.

① Request · curl.exe
                  GET /orders/99 HTTP/1.1
                  Host: 192.168.1.10:3000
                  User-Agent: curl/8.21.0
                  Accept: */*
                  ↵ empty line
                
② Response · the orders service
                  HTTP/1.1 404 Not Found
                  Content-Type: application/json
                  Content-Length: 27
                  Date: Thu, 24 Sep 2026 06:18:24 GMT
                  Connection: keep-alive
                  Keep-Alive: timeout=5
                  ↵ empty line
                  {"error":"order not found"}
                

When nothing answers, there is no status code at all, only an error. Open http://no-such-site.invalid/ in Chromium: no status, just net::ERR_NAME_NOT_RESOLVED. That name can’t exist, so nobody ever received a request.

The number counts, not the phrase. OK or Not Found is only a label for people. Clients act on the number, and the standard tells them to ignore the phrase. We tested it in Chromium 153: a server answering HTTP/1.1 404 Everything is fine was recorded as a 404, a failure.

What your DevTools will show: HTTP/2 and HTTP/3

Many websites, this one included, answer over newer versions: HTTP/2 and HTTP/3. They carry the same parts, but packed into binary frames, so you can no longer read them by eye. In your browser’s DevTools, the Protocol column then shows h2 or h3, and the parts get new names:

  • the first line becomes special fields: :method, :path and :scheme (http or https);
  • Host becomes :authority;
  • the status line becomes :status, a number with no phrase;
  • header names are written in lowercase.

This site answers over HTTP/2. Here is a request for its home page, sent by a small test program, and the start of the answer, decoded:

mehditmimi.com over HTTP/2 · decoded Sep 24, 2026
              sent
              :method: GET
              :path: /
              :authority: mehditmimi.com:443
              :scheme: https
              received
              :status: 200
              cache-control: public, max-age=3600
              expires: Thu, 24 Sep 2026 01:16:23 GMT
              content-type: text/html
              ⋯ 9 more headers, then the page
            

Our test program wrote the port in :authority, mehditmimi.com:443. A browser leaves it out, because 443 is already the default port of https: both mean the same site.

The missing phrase shows in DevTools too. https://example.com/this-page-does-not-exist answers over HTTP/2, and Chromium shows status 404 with no text after it. Over http://, the same page answers 404 Not Found in HTTP/1.1.

Try it yourself

See real requests on your own computer

No programming: a browser and a terminal are enough.

A. In your browser (on a computer, 5 minutes)

  1. Open a website you use. Press F12 (on a Mac: Cmd+Option+I), open the Network tab, and reload the page.
  2. Right-click the column titles and add Method and Protocol.
  3. Click the first row: the page itself. In Headers, under General, find Request Method, Status Code and Remote Address. Under Request Headers, find User-Agent, and Host (called :authority if the Protocol column says h2 or h3).
  4. Type method:POST in the filter box, then use the site: search, like a post, send a form. Click a POST row and open Payload: that is the body.
  5. Open https://example.com/this-page-does-not-exist. Status: 404. A server answered.
  6. Now open http://no-such-site.invalid/. No status code at all, only an error. Nobody answered. Why that can happen is episode 02.

B. In a terminal

  1. On Windows, type curl.exe, not curl. In Windows PowerShell 5.1, plain curl is a shortcut for another command, Invoke-WebRequest. The options below don’t work with it: curl -i http://example.com stops and asks you for a “Uri”. In the Command Prompt (cmd), both work. On macOS and Linux, type curl.
  2. Type this, then press Enter:

    curl.exe -i http://example.com

    It prints the response: the status line, the headers, an empty line, and the body, the page’s HTML.

    curl.exe -i http://example.com Sep 24, 2026
                        HTTP/1.1 200 OK
                        Date: Thu, 24 Sep 2026 06:51:44 GMT
                        Content-Type: text/html
                        Transfer-Encoding: chunked
                        Connection: keep-alive
                        Server: cloudflare
                        Last-Modified: Tue, 22 Sep 2026 20:16:57 GMT
                        Allow: GET, HEAD
                        ⋯ 4 more headers
                        ↵ empty line
                        <!doctype html><html lang="en"><head><title>Example Domain</title>
                        ⋯ the rest of the page
                      
  3. curl.exe -v http://example.com

    This one prints your request too. Lines that start with > are the request, and lines that start with < are the response. The lone > is the empty line. Lines that start with * are curl’s own notes about the connection.

    curl.exe -v http://example.com Sep 24, 2026
    * Host example.com:80 was resolved.
    ⋯ 5 more lines that start with *
    > GET / HTTP/1.1
    > Host: example.com
    > User-Agent: curl/8.21.0
    > Accept: */*
    > 
    * Request completely sent off
    < HTTP/1.1 200 OK
    < Date: Thu, 24 Sep 2026 06:51:44 GMT
    < Content-Type: text/html
    ⋯ 9 more lines of headers
    < 
    ⋯ then the page’s HTML, and one last line that starts with *
  4. curl.exe -v -H "Student: Salma" http://example.com

    The -H option adds a header of your own. Your request now has a > Student: Salma line, and the answer is still 200 OK: the server ignores a header it doesn’t know.

  5. curl.exe -i -X DELETE http://example.com/

    This sends a DELETE. The answer starts with HTTP/1.1 405 Method Not Allowed. The method only asks, and the server decides. The Allow header above had already said which methods this page accepts.

  6. Optional: send a PUT with a body to a service that sends back what it received.

    curl.exe -X PUT https://httpbin.org/anything/orders/42 -d "status=paid"

    Look for "method": "PUT" and your data. The "origin" line is your public address, which is episode 02. Don’t post it anywhere.

Quick check

Pick an answer, then see why

1. Your app sends DELETE /orders/42 to a shop’s server and gets 405 Method Not Allowed. What happened?

Show the answer

B. The server received the request and answered: 405 means “not this method, here”. The method only asks, and the server decides. A deletion that worked comes back in the 200s, like the 204 No Content above. And a server that is down sends no status code at all.

2. Order 42 has the wrong delivery address. The app sends the whole corrected order. Which request fits?

Show the answer

C. PUT asks the server to replace what is at /orders/42 with what you send. POST /orders would ask for a new order: number 43. To send only the field that changed, APIs use PATCH (module 5).

3. A shop’s server receives your order, then asks a payment service to charge your card. In that second exchange, the shop’s server is…

Show the answer

B. Whoever sends the request is the client. In the standard’s words, “the terms client and server refer only to the roles that these programs perform for a particular connection”.

4. Which of these requests will every HTTP/1.1 server refuse, whatever its program does?

Show the answer

C. Host is part of the required shape in HTTP/1.1, and a server must answer 400 Bad Request when it is missing: the orders service did. A is fine: there is no fixed list of headers, and a server ignores one it doesn’t know. B breaks a convention, not the shape, and the server is the boss, so it would run it. That is exactly why it is dangerous.

Common mistakes

  1. Changing data with a GET. A link such as /orders/42/delete looks handy. But browsers, search engines and caches treat every GET as a harmless read: they may load it early, follow it, or answer it with a copy. For anything that changes data, use POST, PUT or DELETE. The standard says the server’s owner “MUST disable or disallow” such an action when it arrives with a safe method like GET.
  2. Thinking POST hides or protects data. POST puts the data in the body instead of the address. Anyone who can read the message reads the body just as easily: DevTools’ Payload tab shows it in clear. What protects both is HTTPS encryption (episode 02).
  3. Using PUT to change one field. PUT asks the server to replace the whole thing with what you send, so a field you leave out can be erased. For partial changes, APIs use PATCH (module 5 of the JavaScript & Node.js course).
  4. Reading the words instead of the number. The phrase after the code is only a label, and the standard says clients should ignore it. Tested in Chromium 153.0.8010.12 on September 24, 2026: a server answering HTTP/1.1 404 Everything is fine was recorded as status 404, a failure.

Let’s recap

  1. The client speaks first, the server answers.
  2. A request has a method, a path, headers, and sometimes a body.
  3. A response has the same shape: a status line, headers, and usually a body.
  4. GET reads, while POST, PUT and DELETE change data.
  5. The server is the boss, so read its documentation.
  6. A status code’s first digit gives its family.

Each point links to its section, if you want to read it again.

Before and after

You need

Nothing. It goes with module 0 of the Web Foundations course, How the Web Works.

Next episode

But how does your request reach the right server? And how does the answer come back to you? Episode 02 follows it, step by step: 02 · How does a request reach the server, and how does the answer come back?

Sources and credits

  • HTTP semantics, RFC 9110: client and server are programs, and roles (§3.3); a server responds to a client’s request (§3.4); every kind of client, from browsers to light bulbs (§3.5); header names, not case-sensitive, with an official register, and unknown headers ignored (§5.1); no fixed size limit, but a server refuses what is too big for it (§5.4); new headers as HTTP’s main way to grow (§16.3); the default port may be left out of an address (§4.2.3); Host (§7.2); Content-Type (§8.3) and Content-Length (§8.6); the methods (§9.1); safe methods, prefetching and robots, and the “MUST disable or disallow” rule (§9.2.1); idempotent methods and automatic retries (§9.2.2); GET (§9.3.1), POST and 201 with Location (§9.3.3), PUT (§9.3.4), DELETE (§9.3.5); User-Agent (§10.1.5); status codes and their five families (§15), 404 (§15.5.5), 405 (§15.5.6).
  • HTTP/1.1, RFC 9112: message format, the empty line, and “only expect a request” (§2.1); the first line (§3); Host must match the address (§3.2); the status line, and why clients ignore the phrase (§4); headers (§5); the body and its length (§6).
  • HTTP/2 and HTTP/3 fields such as :method and :status: RFC 9113 §8.3 and RFC 9114 §4.3. Names ending in .invalid are reserved and can never exist: RFC 2606 §2. 431 Request Header Fields Too Large: RFC 6585 §5. How caches answer with a stored copy: RFC 9111 §4. The OpenAPI format for API documentation: spec.openapis.org.
  • Every request and response on this page was captured on September 24, 2026: Chromium 153.0.8010.12; Chrome 133.0.6943.137 on Android 16 in the Android Emulator; curl.exe 8.21.0 on Windows; Windows PowerShell 5.1. The orders service is a small test program that ran on the laptop; it is not shown, because this episode is about the messages. The HTTP/2 exchange with mehditmimi.com was also made by a small test program. The same day, we sent the broken requests and the 20,000-character header to the orders service, and the Student: Salma header to both the orders service and example.com. The menu describes what the service answered. The course version of this topic: module 0, Anatomy of HTTP messages.
  • The film is animated in code with Remotion. Its narration is a synthetic voice, designed for this series with Qwen3-TTS. The script, the film and this page were prepared with AI assistance.
All episodes