주의: 아직 작성중인 문서이므로 언제든지 내용이 바뀔 수 있습니다.
이 글은 RFC7540을 일부 번역한 글입니다.

5. Streams and Multiplexing

“Stream”은 Frame이 클라이언트와 서버 사이에서 양 방향으로 교환되는 독립적인 일련의 Frame들을 뜻한다.

  • 한 HTTP/2 연결은 동시에 열려있는 여러 개의 stream을 가질 수 있고, 양 쪽 모두 여러 개의 stream에서 오는 frame들을 (한 줄로)끼워서 처리한다.
  • stream은 혼자서 만들고 사용하거나, client와 server가 공유할 수 있다.
  • 양 쪽 모두 stream을 닫을 수 있다.
  • 한 stream 내에서 수신측은 frame이 도착한 순서대로 처리하므로 stream 내에서 frame이 전송되는 순서는 중요하다. 특히 HEADERSDATA frame의 순서는 의미적으로 중요하다.
  • stream은 stream을 시작하는 쪽에서 붙이는 정수형의 stream identifier에 의해 구분된다.

5.1 Stream 상태

Stream의 Lifecycyle은 다음 그림(Figure 2)과 같이 표현될 수 있다.

                         +--------+
                 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   |
`----------------------->|        |<----------------------'
                         +--------+

   send:   endpoint sends this frame
   recv:   endpoint receives this frame

   H:  HEADERS frame (with implied CONTINUATIONs)
   PP: PUSH_PROMISE frame (with implied CONTINUATIONs)
   ES: END_STREAM flag
   R:  RST_STREAM frame

Figure 2: Stream의 상태

위 다이어그램은 상태의 전이와 그 전이에 영향을 주는 frame과 flag만을 나타낸다. 예를 들어 CONTINUATION frame은 상태 전이를 일으키지 않는다; 하지만 이 frame은 앞서 전송된 HEADERSPUSH_PROMISE frame의 일부분이다. 상태 전이의 측면에서 END_STREAM flag는 이를 포함하는 frame과는 별개의 이벤트로 처리된다; END_STREAM flag를 가진 HEADERS는 두 번의 상태 전이를 일으킬 수 있다.

양 측은 frame이 오고 가는중인 stream에 대해 서로 다른 state라고 보고있을 수 있다. 이들은 stream의 생성에 대해 협력하지 않는다; stream은 어느 한 쪽에 의해서 생성된다. 상태의 불일치로 인한 부정적 결과는 RST_STREAM frame이 전송된 이후의 “closed” 상태 뿐인데, 몇 개의 frame은 stream이 닫히고 난 이후에 수신될 수 있기 때문이다.

Stream은 다음과 같은 상태들을 가질 수 있다:

idle:

모든 stream은 “idle”상태에서 시작한다.

이 상태에서는 다음의 상태 전이가 가능하다:

  • HEADERS frame의 수신이나 송신은 stream을 “open”상태로 만든다. Stream identifier는 Section 5.1.1에 설명된 대로 선택된다. 그리고 같은 HEADERS는 stream이 즉시 “half-closed”상태가 되도록 할 수도 있다.
  • PUSH_PROMISE frame을 다른 stream에 송신하면 idle상태인 stream을 이후에 이용하기 위해 예약한다. 예약된 stream의 상태는 “reserved(local)” 상태로 변한다.
  • PUSH_PROMISE frame을 다른 stream에서 수신하면 idle상태인 idle상태인 stream을 이후에 이용하기 위해 예약한다. 예약된 stream의 상태는 “reserved(remote)”상태로 변한다.
  • PUSH_PROMISE frame은 idle상태인 stream에서 송신되지 않고, 새로 예약된 stream을 Promised Stream ID 필드로 참조한다.

idle상태인 stream에서 HEADERSPRIORITY이외의 frame을 수신할 경우 이는 PROTOCOL_ERROR형식의 connection error(Section 5.4.1)로 처리되어야 한다.

reserved (local):

“reserved (lcoal)”상태의 stream은 PUSH_PROMISE frame을 보냄으로써 약속된 stream이다. PUSH_PROMISE frame은 idle stream을 상대편에 의해 시작된 open stream과 연관시킴으로써 예약한다(Section 8.2 참고).

이 상태에서는 다음의 상태 전이만이 가능하다:

  • HEADERS frame을 송신할 수 있다. 이는 stream을 “half-closed (remote)”상태로 만든다.
  • 양 측 누구든 RST_STREAM frame을 송신해서 stream을 “closed”상태로 만들 수 있다. 이는 stream 예약을 해제한다.

이 상태에서는 HEADERS, RST_STREAM, 그리고 PRIORITY 이외의 frame은 절대로 보내면 안된다.

PRIORITYWINDOW_UPDATE frame은 이 상태에서 수신될 수 있다. RST_STREAM, PRIORITY, 그리고 WINDOW_UPDATE 외의 frame을 이 stream에서 수신하는 것은 반드시 PROTOCOL_ERROR형식의 connection error(Section 5.4.1)으로 처리되어야 한다.

reserved (remote):

“reserved (remote)”상태의 stream은 상대편에 의해 예약된 stream이다.

이 상태에서는 다음의 상태 전이만이 가능하다:

  • HEADERS frame의 수신은 stream을 “half-closed (local)”상태로 만든다.
  • 양 측 누구든 RST_STREAM frame을 송신해서 stream을 “closed”상태로 만들 수 있다. 이는 stream 예약을 해제한다.

이 상태에서 stream의 우선순위를 재지정하기 위해 PRIORITY frame을 송신하는 것은 가능하다. 하지만 RST_STREAM, WINDOW_UPDATE, 그리고 PRIORITY 이외의 frame은 절대로 보내면 안된다.

HEADERS, RST_STREAM, PRIORITY 외의 frame을 stream에서 수신하는 것은 반드시 PROTOCOL_ERROR형식의 connection error(Section 5.4.1)로 처리되어야 한다.

open:

“open”상태의 stream에서는 양측 모두가 모든 형식의 frame을 보낼 수 있다. 이 상태에서는 송신하는 측이 알려진(통지된) stream-level flow-control 제한을 확인할 수 있다(Section 5.2).