LoginSignup
12
11

More than 5 years have passed since last update.

HTTP2のストリーム状態遷移

Last updated at Posted at 2015-04-04

後追いながら、HTTP2の勉強をしてます。

少しずつ理解できてきたような気がする。
間違っていたら詳しい方はご指摘ください。

ストリーム状態遷移

ストリームには状態があり、送信できるフレームと送信できないフレームがある。

                        +--------+
                send PP |        | recv PP
               ,--------|  idle  |--------.
              /         |        |         \
             v          +--------+          v
      +----------+          |           +----------+
      |          |          | send H/   |          |
,-----| reserved |          | recv H    | reserved |-----.
|     | (local)  |          |           | (remote) |     |
|     +----------+          v           +----------+     |
|         |             +--------+             |         |
|         |     recv ES |        | send ES     |         |
|  send H |     ,-------|  open  |-------.     | recv H  |
|         |    /        |        |        \    |         |
|         v   v         +--------+         v   v         |
|     +----------+          |           +----------+     |
|     |   half   |          |           |   half   |     |
|     |  closed  |          | send R/   |  closed  |     |
|     | (remote) |          | recv R    | (local)  |     |
|     +----------+          |           +----------+     |
|          |                |                 |          |
|          | send ES/       |        recv ES/ |          |
|          | send R/        v         send R/ |          |
|          | recv R     +--------+    recv R  |          |
| send R/  `----------->|        |<-----------'  send R/ |
| recv R                | closed |               recv R  |
`---------------------->|        |<----------------------'
                        +--------+

  H:  HEADERS フレーム (CONTINUATION が続く可能性がある)
  PP: PUSH_PROMISE フレーム (CONTINUATION が続く可能性がある)
  ES: END_STREAM フラグ
  R:  RST_STREAM フレーム

自分の理解のために表にしてみた。
HEADERSを送信できる状態は、その後にCONTINUATIONもDATAも送信できるものとする。

ストリーム状態 送信可能 遷移する状態 受信可能
idle HEADERS
PUSH_PROMISE(予約ID)
open
reserved (local)
reserved (remote)
HEADERS
PRIORITY
reserved (local) HEADERS
RST_STREAM
PRIORITY
half closed (remote)
closed
RST_STREAM
PRIORITY
WINDOW_UPDATE
reserved (remote) RST_STREAM
PRIORITY
WINDOW_UPDATE
half closed (local)
closed
HEADERS
RST_STREAM
PRIORITY
open HEADERS(END_STREAM)
RST_STREAM
half closed (local)
half closed (remote)
closed
PUSH_PROMISE以外
half closed (local) RST_STREAM
PRIORITY
WINDOW_UPDATE
closed 全て可能
half closed (remote) HEADERS(END_STREAM)
RST_STREAM
closed RST_STREAM
PRIORITY
WINDOW_UPDATE
closed PRIORITY reserved WINDOW_UPDATE(加算する必要あり)

half closedとはなにか

ある開いたストリームがclosed状態になるには3つのパターンがある。

  • GETに対するレスポンスなど、双方でデータの送受信を行う場合はEND_STREAMの送信と受信
  • 片方からだけプッシュする場合は、データ送信者のEND_STREAMの送信
  • RST_STREAMの送信か受信

half closedは、片方がそれ以上DATAを送信しない状態。(という理解で合ってると思う)

ドラフトの図を見るとhalf closedには二つある。

  • half closed (remote)
  • half closed (local)

remoteは、自分から見て現在のIDのストリームの相手の状態。
localは、自分から見て現在のIDのストリームの状態。

half closed(remote)

自分は何かを送るが、相手がそれ以上DATAを送らない状態。つまり相手からEND_STREAMを受けた状態。
図の左側は自分からPUSHしてるので、相手は受信するだけなのでこの状態になっている。相手はこれ以上送信してこないので、残りの作業は自分が送りたいものを送りきってEND_STREAMを送信すること。

これは相手が「GET /」を送ってきた後の状態に等しい。(たぶん)
サーバープッシュの場合はPUSH_PROMISEで予約が終わって、これから送りたいものを送る前の状態。

half closed(local)

自分はこれ以上DATAを送らない状態。つまり自分からEND_STREAMを送った状態。
残りの作業は相手から送られてくる様々なフレームを受信して、END_STREAMが来るまで待つ事。だから表では「全て受信可能」になっている。

これは自分が「GET /」を送った後の状態に等しい。はず。。
サーバープッシュの場合はPUSH_PROMISEで通知を受けて、これからDATAが降ってくるのを待っている状態。

END_STREAMフラグとRST_STREAM

なぜストリームを終了させるのにEND_STREAMフラグとRST_STREAMがあるのか?
RST_STREAMはキャンセルやエラー処理のための即断を意味するので、基本的にはEND_STREAMフラグで終了させるのが正しい。たぶん。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11