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:
-
Framing indicator. This format uses a single integer to describe framing, which describes whether the message is a request or response and how subsequent sections are formatted; see Section 3.3.
-
For a response, zero or more informational responses. Each informational response consists of an informational status code and header section.
-
Control data. For a request, this contains the request method and target. For a response, this contains the status code.
-
Header section. This contains zero or more header fields.
-
Content. This is a sequence of zero or more bytes.
-
Trailer section. This contains zero or more trailer fields.
-
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.
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 (..),
}
Known-Length Field Section {
Length (i),
Field Line (..) ...,
}
Known-Length Content {
Content Length (i),
Content (..),
}
Known-Length Informational Response {
Informational Response Control Data (..),
Known-Length Field Section (..),
}
A known-length request consists of a framing indicator (
Section 3.3), request control data (
Section 3.4), a header section with a length prefix, binary content with a length prefix, a trailer section with a length prefix, and padding.
A known-length response contains the same fields, with the exception that request control data is replaced by zero or more informational responses (
Section 3.5.1) followed by response control data (
Section 3.5).
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.
Fields in the header and trailer sections consist of a length-prefixed name and length-prefixed value; see
Section 3.6.
The format allows for the message to be truncated before any of the length prefixes that precede the field sections or content; see
Section 3.8.
The variable-length integer encoding means that there is a limit of 2
62-1 bytes for each field section and the message content.
A request or response that is constructed without encoding a known length for each section uses the format shown in
Figure 2:
Indeterminate-Length Request {
Framing Indicator (i) = 2,
Request Control Data (..),
Indeterminate-Length Field Section (..),
Indeterminate-Length Content (..),
Indeterminate-Length Field Section (..),
Padding (..),
}
Indeterminate-Length Response {
Framing Indicator (i) = 3,
Indeterminate-Length Informational Response (..) ...,
Final Response Control Data (..),
Indeterminate-Length Field Section (..),
Indeterminate-Length Content (..),
Indeterminate-Length Field Section (..),
Padding (..),
}
Indeterminate-Length Content {
Indeterminate-Length Content Chunk (..) ...,
Content Terminator (i) = 0,
}
Indeterminate-Length Content Chunk {
Chunk Length (i) = 1..,
Chunk (..),
}
Indeterminate-Length Field Section {
Field Line (..) ...,
Content Terminator (i) = 0,
}
Indeterminate-Length Informational Response {
Informational Response Control Data (..),
Indeterminate-Length Field Section (..),
}
An indeterminate-length request consists of a framing indicator (
Section 3.3), request control data (
Section 3.4), a header section that is terminated by a zero value, any number of non-zero-length chunks of binary content, a zero value, a trailer section that is terminated by a zero value, and padding.
An indeterminate-length response contains the same fields, with the exception that request control data is replaced by zero or more informational responses (
Section 3.5.1) and response control data (
Section 3.5).
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 describing the number of bytes in the block. The Chunk Length is encoded as a variable-length integer.
Each Field Line in an Indeterminate-Length Field Section starts with a Name Length field. An Indeterminate-Length Field Section ends with a Content Terminator field. The zero value of the Content Terminator distinguishes it from the Name Length field, which cannot contain a value of 0.
Indeterminate-length messages can be truncated in a way similar to that for known-length messages; see
Section 3.8.
Indeterminate-length messages use the same encoding for Field Line as known-length messages; see
Section 3.6.
The start of each binary message is a framing indicator that is a single integer that describes the structure of the subsequent sections. The framing indicator can take just four values:
-
A value of 0 describes a request of known length.
-
A value of 1 describes a response of known length.
-
A value of 2 describes a request of indeterminate length.
-
A value of 3 describes a response of indeterminate length.
Other values cause the message to be invalid; see
Section 4.
The control data for a request message contains the method and request target. That information is encoded as an ordered sequence of fields: Method, Scheme, Authority, Path. Each of these fields is prefixed with a length.
The values of these fields follow the rules in HTTP/2 (
Section 8.3.1 of [
HTTP/2]) that apply to the
":method",
":scheme",
":authority", and
":path" pseudo-header fields, respectively. However, where the
":authority" pseudo-header field might be omitted in HTTP/2, a zero-length value is encoded instead.
The format of request control data is shown in
Figure 3.
Request Control Data {
Method Length (i),
Method (..),
Scheme Length (i),
Scheme (..),
Authority Length (i),
Authority (..),
Path Length (i),
Path (..),
}
The control data for a response message consists of the status code. The status code (
Section 15 of [
HTTP]) is encoded as a variable-length integer, not a length-prefixed decimal string.
The format of final response control data is shown in
Figure 4.
Final Response Control Data {
Status Code (i) = 200..599,
}
Responses that include informational status codes (see
Section 15.2 of [
HTTP]) are encoded by repeating the response control data and associated header section until a final status code is encoded; that is, a Status Code field with a value from 200 to 599 (inclusive). The status code distinguishes between informational and final responses.
The format of the informational response control data is shown in
Figure 5.
Informational Response Control Data {
Status Code (i) = 100..199,
}
A response message can include any number of informational responses that precede a final status code. These convey an informational status code and a header block.
If the response control data includes an informational status code (that is, a value between 100 and 199 inclusive), the control data is followed by a header section (encoded with known length or indeterminate length according to the framing indicator) and another block of control data. This pattern repeats until the control data contains a final status code (200 to 599 inclusive).
Header and trailer sections consist of zero or more field lines; see
Section 5 of [
HTTP]. The format of a field section depends on whether the message is of known length or indeterminate length.
Each Field Line encoding includes a name and a value. Both the name and value are length-prefixed sequences of bytes. The Name field is a minimum of one byte. The format of a Field Line is shown in
Figure 6.
Field Line {
Name Length (i) = 1..,
Name (..),
Value Length (i),
Value (..),
}
For field names, byte values that are not permitted in an HTTP field name cause the message to be invalid; see
Section 5.1 of [
HTTP] for a definition of what is valid and
Section 4 regarding the handling of invalid messages. A recipient
MUST treat a message that contains field values that would cause an HTTP/2 message to be malformed according to
Section 8.2.1 of [
HTTP/2] as invalid; see
Section 4.
The same field name can be repeated over more than one field line; see
Section 5.2 of [
HTTP] for the semantics of repeated field names and rules for combining values.
Messages are invalid (
Section 4) if they contain fields named
":method",
":scheme",
":authority",
":path", or
":status". Other pseudo-fields that are defined by protocol extensions
MAY be included; pseudo-fields cannot be included in trailers (see
Section 8.1 of [
HTTP/2]). A Field Line containing pseudo-fields
MUST precede other Field Line values. A message that contains a pseudo-field after any other field is invalid; see
Section 4.
Fields that relate to connections (
Section 7.6.1 of [
HTTP]) cannot be used to produce the effect on a connection in this context. These fields
SHOULD be removed when constructing a binary message. However, they do not cause a message to be invalid (
Section 4); permitting these fields allows a binary message to capture messages that are exchanged in a protocol context.
Like HTTP/2 or HTTP/3, this format has an exception for the combination of multiple instances of the
Cookie field. Instances of fields with the ASCII-encoded value of
"cookie" are combined using a semicolon octet (0x3b) rather than a comma; see
Section 8.2.3 of [
HTTP/2].
The content of messages is a sequence of bytes of any length. Though a known-length message has a limit, this limit is large enough that it is unlikely to be a practical limitation. There is no limit to the size of content in an indeterminate-length message.
Messages can be padded with any number of zero-valued bytes. Non-zero padding bytes cause a message to be invalid (see
Section 4). Unlike other parts of a message, a processor
MAY decide not to validate the value of padding bytes.
Truncation can be used to reduce the size of messages that have no data in trailing field sections or content. If the trailers of a message are empty, they
MAY be omitted by the encoder in place of adding a length field equal to zero. An encoder
MAY omit empty content in the same way if the trailers are also empty. A message that is truncated at any other point is invalid; see
Section 4.
Decoders
MUST treat missing truncated fields as equivalent to having been sent with the length field set to zero.
Padding is compatible with truncation of empty parts of the messages. Zero-valued bytes will be interpreted as a zero-length part, which is semantically equivalent to the part being absent.