Skip to main content

3. Format

Section 6 of [HTTP] defines the general structure of HTTP messages and composes those messages into distinct parts. This format describes how those parts are composed into a sequence of bytes. At a high level, binary messages are comprised of:

  1. Framing indicator - A single integer describing whether the message is a request or response and how subsequent sections are formatted
  2. For a response - Zero or more informational responses (each with status code and header section)
  3. Control data - Request method/target (for requests) or status code (for responses)
  4. Header section - Zero or more header fields
  5. Content - A sequence of zero or more bytes
  6. Trailer section - Zero or more trailer fields
  7. Optional padding - Any amount of zero-valued bytes

All lengths and numeric values are encoded using the variable-length integer encoding from Section 16 of [QUIC]. Integer values do not need to be encoded on the minimum number of bytes necessary.

3.1. Known-Length Messages

A request or response that has a known length at the time of construction uses the format shown in Figure 1.

Known-Length Request {
Framing Indicator (i) = 0,
Request Control Data (..),
Known-Length Field Section (..),
Known-Length Content (..),
Known-Length Field Section (..),
Padding (..),
}

Known-Length Response {
Framing Indicator (i) = 1,
Known-Length Informational Response (..) ...,
Final Response Control Data (..),
Known-Length Field Section (..),
Known-Length Content (..),
Known-Length Field Section (..),
Padding (..),
}

For a known-length encoding, the length prefix on field sections and content is a variable-length encoding of an integer. This integer is the number of bytes in the field section or content, not including the length field itself.

3.2. Indeterminate-Length Messages

A request or response that is constructed without encoding a known length for each section uses indeterminate-length encoding. The indeterminate-length encoding only uses length prefixes for content blocks. Multiple length-prefixed portions of content can be included, each prefixed by a non-zero Chunk Length integer.

3.3. Framing Indicator

The framing indicator is a single integer that describes the structure of subsequent sections:

  • 0 = Request of known length
  • 1 = Response of known length
  • 2 = Request of indeterminate length
  • 3 = Response of indeterminate length

Other values cause the message to be invalid.

3.4. Request Control Data

The control data for a request contains: Method, Scheme, Authority, Path. Each field is prefixed with a length. Values follow HTTP/2 rules for ":method", ":scheme", ":authority", and ":path" pseudo-header fields.

3.5. Response Control Data

The control data for a response consists of the status code encoded as a variable-length integer (not a length-prefixed decimal string).

3.5.1. Informational Status Codes

Informational status codes (1xx) can appear zero or more times before the final response.

3.6. Header and Trailer Field Lines

Each field line is encoded as a length-prefixed name followed by a length-prefixed value. Field names MUST be converted to lowercase. Both name and value are length-prefixed byte sequences.

3.7. Content

Content is encoded differently for known-length vs. indeterminate-length messages. For known-length: a single length-prefixed block. For indeterminate-length: multiple chunks, each with a length prefix, terminated by a zero-valued integer.

3.8. Padding and Truncation

Any number of zero-valued bytes can be appended to a message as padding. Messages can be truncated at specific boundaries without rendering them invalid.