Baud
All protocols

HTTP/1.1

The web's language: readable text, a request line, headers, a blank line.

A request

Every byte is readable text. The ASCII row under the hex shows the letters.

HTTP/1.1 request · 72 bytes of text01632486447G45E54T20 2F/20 48H54T54T50P2F/3112E.3110DCR0ALF48H6Fo73s74t3A:20 65e78x61a6Dm70p6Cl65e2E.63c6Fo6Dm0DCR0ALF55U73s65e72r2D-41A67g65e6En74t3A:20 63c75u72r6Cl2F/3882E.3440DCR0ALF41A63c63c65e70p74t3A:20 2A*2F/2A*0DCR0ALF0DCR0ALFMethodSpaceTargetSpaceVersionCRLFHost headerUser-Agent headerAccept headerBlank lineClick a field to inspect it

Whole frame

The whole request is readable ASCII: a request line, three headers and a blank line. There is no length field; the blank line is the delimiter.

FieldOffsetExample valueMeaning
MethodByte 0–2GETWhat to do with the resource. GET = fetch it. Others: POST (send data), PUT (replace), DELETE, HEAD (headers only).
SpaceByte 30x20A single space (0x20) separates the parts of the request line.
TargetByte 4/The path (and query) being requested. '/' is the site root.
SpaceByte 50x20Another separator.
VersionByte 6–13HTTP/1.1The protocol version, spelled out in ASCII.
CRLFByte 14–150D 0ACarriage Return + Line Feed (0D 0A) ends every line. HTTP/1.1 is a text protocol: you could type this into a raw TCP connection by hand.
Host headerByte 16–34Host: example.com'Name: value' lines are headers. Host is the only mandatory one in HTTP/1.1: it tells a server hosting many sites which one you want, since the IP address alone cannot.
User-Agent headerByte 35–56User-Agent: curl/8.4Identifies the client software. Servers use it for statistics, and sometimes for guessing what content to send.
Accept headerByte 57–69Accept: */*Which content types the client can handle. */* means anything.
Blank lineByte 70–710D 0AAn empty line (just CRLF) marks the end of the headers. A GET has no body, so the request ends here; for a POST the body would follow.

Overview

HTTP/1.1 is the text format browsers and servers have used since 1997. A request is a request line (method, path, version), headers, a blank line, and an optional body; a response mirrors it with a status line. Everything is plain ASCII up to the body, and every line ends in CRLF.

HTTP/2 and HTTP/3 change the encoding (binary frames, header compression, QUIC) but keep the same ideas: methods, status codes and headers.

Key facts

Transport
TCP (80, or 443 with TLS)
Encoding
ASCII text, CRLF lines
Style
Request / response
Mandatory header
Host
Body length
Content-Length or chunked
Standard
RFC 9112 / 9110

A response

A status line, headers, a blank line and then exactly Content-Length bytes of body.

HTTP/1.1 response · 78 bytes01632486448H54T54T50P2F/3112E.31120 32230030020 4FO4BK0DCR0ALF43C6Fo6En74t65e6En74t2D-54T79y70p65e3A:20 74t65e78x74t2F/70p6Cl61a69i6En0DCR0ALF43C6Fo6En74t65e6En74t2D-4CL65e6En67g74t68h3A:20 3113330DCR0ALF0DCR0ALF48H65e6Cl6Cl6Fo2C,20 77w6Fo72r6Cl64d21!VersionSpaceStatus codeSpaceReason phraseCRLFContent-Type headerContent-Length headerBlank l…BodyClick a field to inspect it

Whole frame

Status line, headers, blank line, body. Content-Length says exactly how many body bytes to read.

FieldOffsetExample valueMeaning
VersionByte 0–7HTTP/1.1The server's HTTP version.
SpaceByte 80x20Separator.
Status codeByte 9–11200The outcome as a number: 2xx success, 3xx redirect, 4xx client error (404 not found), 5xx server error.
SpaceByte 120x20Separator.
Reason phraseByte 13–14OKA human-readable label for the code. Programs ignore it and look at the number.
CRLFByte 15–160D 0ACarriage Return + Line Feed (0D 0A) ends every line. HTTP/1.1 is a text protocol: you could type this into a raw TCP connection by hand.
Content-Type headerByte 17–42Content-Type: text/plainWhat kind of data the body is, so the client knows how to interpret it (text/plain, text/html, application/json, image/png...).
Content-Length headerByte 43–62Content-Length: 13The body length in bytes. This is how the client knows where the body ends, since the connection may stay open for the next request.
Blank lineByte 63–640D 0AEnd of the headers.
BodyByte 65–77Hello, world!The content itself: exactly Content-Length bytes.

Requests on one connection

Keep-alive reuses the TCP connection.

Browser192.168.1.20:51234Web server203.0.113.50:80GET /Host: example.com200 OKContent-Length: 13GET /logo.pngsame connectionTCP connectedTCP connected

Whole exchange

HTTP is request and response, one after another, on top of a reliable TCP stream.

  1. 1Request

    Sent inside the established TCP connection (see the TCP page for the handshake that comes before this).

  2. 2Response

    The server answers on the same connection. With HTTP/1.1 keep-alive the connection stays open, so the next request skips the handshake.

  3. 3Next request, no new handshake

    Reusing the connection saves a round trip per request. HTTP/2 and HTTP/3 go further and interleave many requests at once.

Where you meet it

  • Every website and nearly every web API (REST, JSON over HTTP)
  • `curl -v` prints exactly these lines, which is the quickest way to see HTTP
  • Webhooks, package downloads, software updates

Watch out for

  • A bare LF instead of CRLF, or a missing blank line, makes strict servers answer 400 Bad Request.
  • Content-Length must match the body byte count (not characters): multibyte text breaks naive length code.
  • Plain HTTP is readable by anyone on the path. HTTPS wraps the same text in TLS.

Standards

  • RFC 9112: HTTP/1.1
  • RFC 9110: HTTP Semantics

Related protocols