8 min
  • HTTP

The anatomy of an HTTP message

HTTP is a text format, and for one version of it you can read the whole thing on the wire. A request is a line, some fields, a blank line, and optionally a body.

http
GET /index.html HTTP/1.1Host: www.example.comAccept: text/htmlUser-Agent: ExampleBrowser/1.0 

The first line names a method, a target and a version. The lines after it are fields — key, colon, value — in no significant order. Then a blank line, and that blank line is not a separator or a stylistic choice: it is the framing. It is the only thing that tells the receiver the fields have ended and a body may begin.

Loading the HTTP Explorer simulation…

The response has the same shape

Status line, fields, blank line, body. Content-Length counts the octets of that body, which is how the receiver knows where the message ends on a connection that is about to carry another one.

Host deserves a mention on its own: it is mandatory in HTTP/1.1 and is the reason a single address can serve thousands of sites. The connection went to an IP; the field is what says which of the many sites at that IP you meant.

Check yourself
What is the blank line between the fields and the body actually doing?

Methods are promises

The method is not just a label. Each one carries a contract that caches, proxies and client libraries rely on without asking the application:

MethodSafe?Idempotent?Meaning
GETYesYesGive me this; change nothing
HEADYesYesThe same, but headers only
PUTNoYesMake this resource be exactly this
DELETENoYesMake this resource not exist
POSTNoNoProcess this, however you like

Safe means it changes nothing, so it can be prefetched. Idempotent means sending it twice leaves the same state, so it can be retried automatically. POST is neither, which is why a browser warns before resubmitting one.

Loading the HTTP Explorer simulation…
Predict what happens next
An app implements 'delete item' as a GET on /items/7/delete. What goes wrong?

Key takeaways

  • A request is a request-line, fields, a blank line, and maybe a body. The response has exactly the same shape.
  • The blank line is the framing that ends the field section — it is required even when there is no body.
  • Host is mandatory in HTTP/1.1 and is what lets one address serve many sites.
  • Content-Length counts octets, and is how a receiver knows where one message ends on a reused connection.
  • Safe and idempotent are promises intermediaries act on. A GET with side effects breaks a contract with the entire web, not just with your client.

Take it further