In HTTP/2, a stream is a request/response interaction.
According to the HTTP/2 Standard, each stream is created in state
and goes through a couple of states until it eventually reaches
Run the Echo Server
We will re-use the Echo Server from the Server Push Demo to run the stream-info examples below. The Echo Server takes a POST request, and then sends the received data back to the client using a Server Push message.
Download and compile the Echo Server as follows:
In order to run it, learn the correct ALPN version for your JDK
(see table 14.1), and download the ALPN boot JAR from Maven Central.
With the right
<path-to-alpn-boot.jar>, run the Echo Server as follows:
h2c stream-info command is intended to be used when debugging a server,
where we can set breakpoints and go through each interaction step-by-step.
However, if we put a bunch of
h2c stream-info commands into a shell script,
they are usually executed fast enough to see the state transitions.
Create a shell script
./test.sh with the following commands
(the example runs on Linux and OS X. For Windows use cygwin):
Note that the
post command is run in the background, because if we wait for
post to be finished, we will only see streams in state
Start h2c like this:
In another shell window, run
Stream States for the POST request
The output shows stream states for two streams:
- The POST request with stream ID
- The Server Push message with stream ID
Let’s analyze the stream states for the POST request with stream ID
We cannot observe the initial
idle state, because when the stream is created,
it switches to
open immediately sending the request header.
When the request body is sent (
DATA frame with
END_STREAM), the state
half closed (local), indicating that the client is done with
its part of the request/response interaction.
Receiving the response moves the stream state to
Stream States for the Server Push message
PUSH_PROMISEto indicate that the server will send a “promised” response for the URL
- The header of the “promised” response.
- The body of the “promised” response.
The corresponding state transitions for stream ID
2 are as follows:
Again, we cannot observe the initial
idle state, because when the
stream is created upon receiving the
PUSH_PROMISE, the stream
goes immediately from
Receiving the header moves the stream state to
half closed (local),
receiving the body moves the state to
Note that the “promised” stream goes from
closed only through
receiving frames, there is no sent frame involved.