HTTP/2 HEADERS and DATA Frames
Asked Answered
T

2

8

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?

Tucson answered 9/6, 2017 at 14:14 Comment(0)
A
12

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.

Aerophobia answered 9/6, 2017 at 20:51 Comment(2)
I analysed your response, know I understand the concept! Can't thank you enough! Cheers!Tucson
Just to add, if the entire header block does not fit in a single HEADERS frame, the rest of the header block can be sent in CONTINUATION frames. But in such a case, all the CONTINUATION frames for a given stream ID have to be sent one after the other. If a HEADERS frame that is not complete is followed by a frame with a different stream ID, it would result in a connection error (RFC 7450 section 6.2).Xray
P
2

A supplement:

A DATA frame can ONLY be sent with an HEADERS frame

Not true. DATA frames can also be sent with PUSH_PROMISE.

I don't see any indicators which shows the DATA frames Stream ID (RFC 7540, 6.1)

That's because section 6.1 shows the Payload of a frame, which does not include the header part. 4.1 tells you what the 9 bytes header looks like:

enter image description here

Pasargadae answered 10/6, 2017 at 10:43 Comment(1)
So the Payload DATA frames from 6.1 is inside the Frame Payload of 4.1?Tucson

© 2022 - 2024 — McMap. All rights reserved.