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.