Search code examples
httphttp2

HTTP/2 HEADERS and DATA Frames


I am trying to understand HTTP/2 in detail. I read this article about streams, messages and frames: https://hpbn.co/http2/#streams-messages-and-frames. I don't know if I got the concept right.

I came to the following conclusion:

  • A message is a combination of a HEADER frame and one or more DATA frames.
  • A DATA frame can ONLY be sent with an HEADERS frame, because I don't see any indicators which shows the DATA frames Stream ID (RFC 7540, 6.1)
    • If this is true, A DATA Frame can only be sent within a message
  • A Stream can be chunked into many Frames, while it can be related to a Stream by its Stream ID

Furthermore: How is a message represented in the specification?


Solution

  • You got a few things incorrectly.

    A message is a combination of one or two HEADER frames (carrying the HTTP headers), zero or more DATA frames, and one optional terminal HEADER frame (carrying the HTTP trailers). You can look at examples in this section of RFC 7540. There is a special case for 100 Continue responses, that can begin with two HEADERS rather than one. In what follows we can ignore this case.

    A DATA frame does have a stream ID, because all frames share the frame header defined in this section of RFC 7540. What is described in section 6.1 is only the body of the DATA frame.

    A message is a half of a HTTP/2 stream. A message represents either a HTTP request or a HTTP response.

    A HTTP/2 stream is the combination of a request message and a response message. Note that this is not to be confused with the flag_end_stream that signals the last frame sent for that particular stream by either peer.

    A typical GET request performed by a browser will then have (assuming the stream ID is 13):

    • one HEADERS frame with ID=13, flag_end_headers=true and flag_end_stream=true (a GET request typically has no body)

    A typical response to that GET request will then have:

    • one HEADERS frame with ID=13 and flag_end_headers=true
    • one or more DATA frames, all with ID=13; the last DATA frame will have flag_end_stream=true.

    Note that due to multiplexing, frames can interleave; this means that if you have two concurrent responses (say for stream 13 and stream 15), for example, you can have this sequence:

    HEADERS(13) HEADERS(15) DATA(15) DATA(13) DATA(13] DATA(15) DATA(15]

    where the bracket ] means that it's the last frame in the stream.