Once the HTTP/2 connection is established, it is possible to exchange "frames" between the two endpoints.
Format of the frame
+-----------------------------------------------+ | Length (24) | +---------------+---------------+---------------+ | Type (8) | Flags (8) | +-+-------------+---------------+-------------------------------+ |R| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0...) ... +---------------------------------------------------------------+
The format of the frame is as shown. All frames start with a 9-byte frame head followed by a variable-length payload.
The field of the frame header is defined as follows:
- Length: The payload length of the frame, expressed as an unsigned 24-bit integer. Unless the recipient sets a larger value for settings_max_frame_size, the length cannot be greater than 2^14
(16,384). The 9-byte frame header is not counted within the length.
- Type:8 bit, frame type. The frame type determines the format and semantics of the frame. Any unknown frame type will be ignored and discarded.
- The flags:8 bit, reserved for the Boolean identity associated with the frame type. Boolean identifiers are given different semantics depending on the type of frame being indicated. A Boolean identity that has no defined semantics for a frame type must be ignored and must be left out of the set state (0x0) when it is sent.
- R:1 bits, reserved fields. The semantics of this field are undefined and must be left out of the set state (0x0) when it is sent and must be ignored when it is received.
- Stream Identifier: Stream identifier, expressed as an unsigned 31-bit integer. The value 0x0 is preserved, indicating that the frame is associated with the entire connection, not with a stream.
The structure and content of the payload of a frame is entirely dependent on the frame type.
The size of the frame
The payload size of the frame is limited by the maximum value advertised by the receiver in the Settings_max_frame_size setting. This setting can be any value between 2^14 (16,384) and 2^24-1 (16,777,215) bytes.
All implementations of the HTTP/2 must have the ability to receive and minimally handle frames up to 2^14 byte length (plus a frame header of 9 bytes in length). When describing the size of a frame, the size of the frame header is not included. Some frame types, such as ping frames, add additional restrictions on the data size of the payload.
If the frame exceeds the maximum length defined by the settings_max_frame_size, or exceeds any limit defined by the frame type, or is too small to contain the forced frame data, the endpoint must send a frame_size_error error code. Frame size that can modify the entire connection state in a frame error must be treated as a connection error, including all frames carrying header blocks (that is, headers,push_promise and continuation) or settings, and all frames with a stream identifier of 0.
The endpoint is not obligated to use all the free space in the frame. Using frames smaller than the maximum length can improve responsiveness. When sending a time-sensitive frame (for example, rst_stream,window_update or priority), sending a large size frame can cause delays. If the transmission is blocked by a large frame, performance is affected.
Header compression and decompression
As with http1.x, the HTTP/2 header field contains a name and one or more values. The header fields are used in HTTP requests and responses, and also in service-side push operations.
The header list is a collection of 0 or more header fields. When transmitting over a connection, the header list is serialized into a header block using HTTP header compression. The serialized header block is then sliced into one or more byte sequences (called "Header Block Fragments"), which are then transmitted as payloads for frames such as headers,push_promise or continuation.
The cookie header field is handled specially by HTTP mapping.
The receiving end reconstructs the header block by the connection fragment, and then unzip the header block to reconstruct the header list.
A complete header block consists of:
- A headers or push_promise frame with the end_headers identity set, or
- A headers or push_promise frame that clearly identifies the end_headers, and one or more continuation frames, where the last continuation frame sets the End_headers identity.
Header compression is stateful. In the entire connection, a compression context is used and an extract contexts. The decoding error in the header block must be treated as a connection error of type Compression_error.
Each header block is treated as a discrete unit. The header block must be transmitted as a continuous frame sequence, with no interleaved frames of any type or any other stream. The end_headers identity must be set in the last frame in the headers or continuation frame sequence. The end_headers identity must be set in the last frame in the push_promise or continuation frame sequence. This allows a header block to be logically equivalent to a separate frame.
Header block fragments can only be used as payloads for headers,push_promise or continuation frames, because these frames carry data that modifies the compression context that is maintained by the receiving side. Endpoints that receive headers,push_promise or continuation frames need to reorganize the header blocks and perform the decompression operations, even if the frames are discarded. If the receiving end does not extract the header block, then it must terminate the connection with a connection error of type Compression_error.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
(iii) Frame of HTTP/2