WalkthroughDifficulty: Beginner2 min

An HTTP/1.1 Exchange, Line by Line

An HTTP/1.1 request is lines of text: what to do, details about it, a blank line, then the content.

An HTTP/1.1 message is plain text in three parts: a start line, header fields, and an optional body, with an empty line between the headers and the body. A request's start line says what to do and to what; a response's says how it went. Because version 1.1 is text, a raw exchange can be read, and even typed, by a person.

Below is a request that adds an item to a shopping cart, and the response. The exchange is illustrative.

Raw HTTP/1.1 exchangetext
POST /cart/items HTTP/1.1
Host: shop.example.com
Content-Type: application/json
Content-Length: 31

{"item":"book-17","quantity":2}

HTTP/1.1 201 Created
Location: /cart/items/88
Content-Length: 0
An illustrative request and response; every line ends with a carriage return and line feed.

The start line. In a request it is the method, the target and the version: POST /cart/items HTTP/1.1. In a response it is the version, a status code and a short reason: HTTP/1.1 201 Created. The code is what programs read; the reason is for people.

The headers. One field per line, a name, a colon and a value. They carry everything about the message that is not the content: which site is meant (Host, required in HTTP/1.1, because many sites share one address), what format the body is in (Content-Type), how long it is, and where a new resource lives (Location). Names are not case sensitive.

The empty line. A line with nothing on it ends the headers. Everything after it is the body. It is the only separator; there is no closing marker for the headers.

The body. The content itself, here 31 bytes of JSON. Because TCP delivers a stream, the receiver needs to know where the body ends: Content-Length gives its size in bytes, or chunked transfer encoding sends it in pieces, each with its own size. A response with Content-Length: 0 has no body at all.

HTTP/2 and HTTP/3 carry the same parts, method, target, status, headers and body, in binary frames instead of text, so the meaning stays the same while the bytes on the wire change.

So when debugging a request, read it in these four parts: what was asked, the headers that qualify it, the empty line, and the body that follows.