Skip to content

HTTP Messages

HTTP communication, based on a client-server architecture, relies on exchanging messages. These messages are either requests sent by a client to a server, or responses sent by a server back to a client. This request/response protocol operates typically over a reliable TCP/IP connection (or QUIC for HTTP/3).

An HTTP client (e.g., a web browser, a mobile application, or a tool like curl) establishes a connection to a server to send one or more HTTP request messages. An HTTP server (e.g., Nginx, Apache, Node.js with Express) accepts these connections, processes the requests, and sends back HTTP response messages.

HTTP uses Uniform Resource Identifiers (URIs), most commonly URLs, to identify resources and establish connections. Once a connection is established (including a TLS handshake for HTTPS), HTTP messages are exchanged. For HTTP/1.1, these messages are text-based and follow a structure somewhat similar to internet mail (RFC 5322) and MIME (RFC 2045-2049) in their header format. HTTP/2 and HTTP/3 use a binary framing layer for message transport but maintain the same semantic components.

HTTP/1.1 Message Structure:
  • A Start-line: Describes the request (for requests) or its status (for responses).
  • Zero or more Header fields: Provide metadata about the message, the resource, or the client/server. Each header is a name-value pair, followed by CRLF (Carriage Return Line Feed).
  • An Empty line: A single CRLF, indicating the end of the header fields.
  • Optionally, a Message-body: Contains the payload data (e.g., HTML content, JSON data, image bytes).
Start-Line Types:
`start-line = Request-Line | Status-Line`

We will discuss Request-Line and Status-Line in detail in the chapters on HTTP Requests and HTTP Responses, respectively. Here are examples:

// Request-Line sent by the client:
GET /index.html HTTP/1.1
// Status-Line sent by the server:
HTTP/1.1 200 OK

HTTP header fields provide essential information about the request or response, or about the object sent in the message body. Headers are colon-separated name-value pairs in clear text (for HTTP/1.1) and are case-insensitive in their names.

Categories of Headers (Conceptual):

  • General Headers: Apply to both request and response messages but not to the entity itself (e.g., Connection, Date). These are now mostly considered Representation Data or Message Metadata in newer RFCs.
  • Request Headers: Provide more information about the request or the client (e.g., User-Agent, Accept, Authorization).
  • Response Headers: Provide more information about the response or the server (e.g., Server, Set-Cookie, Allow).
  • Representation Headers (formerly Entity Headers): Describe the payload of the message body (e.g., Content-Type, Content-Length, Content-Encoding). If no body is present, they describe the resource identified by the request.
All headers follow the generic format: `header-field-name: field-value`

Examples of various header fields:

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Host: www.example.com
Accept-Language: en-US,en;q=0.9
Date: Mon, 21 Feb 2022 12:28:53 GMT
Server: nginx/1.21.6
Last-Modified: Wed, 16 Feb 2022 19:15:56 GMT
ETag: "abcdef1234567890"
Content-Length: 1234
Content-Type: application/json; charset=utf-8
Connection: keep-alive

The message body is an optional part of an HTTP message. If present, it carries the payload associated with the request or response. The presence and interpretation of a message body are often determined by the request method (e.g., GET and HEAD requests usually don’t have bodies) or the response status code (e.g., 204 No Content responses have no body).

Headers like Content-Type and Content-Length describe the nature and size of the body. The body can contain various types of data:

  • HTML, CSS, JavaScript for web pages.
  • JSON or XML for API communications.
  • Image data (JPEG, PNG, GIF, WebP).
  • Plain text.
  • Form data (application/x-www-form-urlencoded or multipart/form-data).

Example of a JSON message body:

{
"username": "john.doe",
"email": "john.doe@example.com"
}

Example of an HTML message body:

<!DOCTYPE html>
<html>
<head><title>Hello</title></head>
<body>
<h1>Hello, World!</h1>
</body>
</html>

While the conceptual structure (start-line, headers, body) remains the same, HTTP/2 and HTTP/3 use binary framing. Headers are compressed (HPACK/QPACK), and messages are broken into frames, which can be interleaved over a single connection. This significantly improves performance but is an abstraction layer below the HTTP semantics described here.