0

GOAWAY フレーム (HTTP)

[45] GOAWAY フレームは、 HTTP接続を閉じるものです。

仕様書

意味

[2] GOAWAY フレーム (フレーム型 0x7) は、接続終了 (shutdown) をはじめたり、 誤り条件 (error condition) を通知したりするものです >>1

[3] GOAWAY を使って、エンドポイントは既存のストリームの処理は続けつつ、 新しいストリームの受付は中止し、華麗 (graceful) に停止することができます >>1

[4] サーバーのメンテナンスなど管理操作に有用です >>1

構文

[13] ストリーム識別子0x0 でなければなりません。 GOAWAY フレーム接続全体に適用されます >>1

[12] フラグはありません >>1。 0 でなければなりません >>39受信者は無視しなければなりません >>39

width
8
  1. 1 0
  2. 1 0
  3. 1 0
  4. 1 0
  5. 1 0
  6. 1 0
  7. 1 0
  8. 1 0

[26] payload は次の欄で構成されます。

[27] R
1ビットのフラグとして予約されています。
[15] 最終ストリーム識別子 (Last-Stream-ID)
符号無し31ビット整数 (ネットワークバイト順 >>78) のストリーム識別子です。 送信者が何らかの動作を行った、または今後なお行うかもしれない最大の番号のストリーム識別子を指定します。 0 であれば、どのストリームも処理していないことを表します。 ここで「処理」とは、何らかのデータを何らかの上位層ソフトウェアに渡して、そこで何らかの動作が行われたかもしれないことを表します。 >>1
[23] 誤り符号 (Error Code)
32ビット誤り符号 (ネットワークバイト順 >>38) で、接続を閉じる理由を含むものです >>1
[24] 追加デバッグデータ (Additional Debug Data)
診断目的のみで意味を持たない不透明データです。 payload の末尾にあっても構いません。 セキュリティー上やプライバシー上繊細なデータを含むことがありますから、 記録その他の目的で永続的に保存する時は、認められないアクセスを防ぐ安全策を講じなければなりません>>1

[35] 既にアプリケーション層にデータがわたっていれば、そのストリームよりも大きなストリーム識別子を指定しなければなりません >>34

[5] GOAWAY フレームの送信と peer の新しいストリームの開始には競合条件がありますから、 GOAWAY フレームには peer が開始した (上で送信者が処理した、またはしたかもしれない) 最後 (最大) のストリームストリーム識別子を指定します。 送信者は、GOAWAY フレームの送信以後、 そのストリーム識別子よりも大きなストリーム識別子フレームを無視します。 >>1

[46] ストリームの状態が open 以降なら、処理したとみなしてもいいのかもしれません。 より厳密に判定するなら、 open 以降でも実際にアプリケーション層に引き渡す前なら未処理と考えてもよいかもしれません。

[22] ただし送信者は、接続の状態を変えるフレームを完全に無視することはできません。 例えば HEADERSPUSH_PROMISECONTINUATION は、最低でもヘッダー圧縮のための状態の管理のための処理は行わなければなりませんDATA フレームは、接続フロー制御窓の加算は行わなければなりません>>1

[25] 送信者追加デバッグデータがどう扱われるとも保証されませんから、 開発者モードのような特別な設定がある場合を除き、 本欄を使うべきではないでしょう。 fingerprinting vector ともなります。

width
32
  1. 1 R
  2. 31 最終ストリーム識別子
  3. 32 誤り符号
  4. 32... 追加デバッグデータ

文脈

[9] エンドポイントは、接続を閉じる前に GOAWAY フレームを送信するべきです >>1, >>36

[37] 自身が送信したフレームが処理されたのか、それとも未処理なのか判定できるようにするためです。
[10] おかしな動作の peer に対しては、 GOAWAY フレームを送らずに接続を閉じても構いません >>1

[47] Chrome は正常終了時には GOAWAY を送信せずに接続を閉じます (ソースコードには、無線が寝ている場合に起こさないためとの注記があります)。 Firefox誤り符号 NO_ERRORGOAWAY を送信し、直ちに接続を閉じます。

[11] GOAWAY フレームを既に受信している場合も、 当該接続をそれ以上使わなくなった時点で、 接続を閉じるより前に GOAWAY フレームを送信するべきです>>1

[18] エンドポイントは、状況が変わったら、新たに GOAWAY フレームを送信して構いません >>1。 ただし最終ストリーム識別子がより大きな値になってはなりません >>1

[19] 例えば NO_ERROR で送信した後、接続を直ちに閉じなければならない状況が発生したら、 改めて新しい誤り符号で送信できます >>1

[20] 華麗に終了したいサーバーは、まず最終ストリーム識別子が 231-1で NO_ERRORGOAWAY フレームを送信するべきです。 進行中のストリーム作成のための時間 (最低でも1RTT) が経過したら、 改めて新しい最終ストリーム識別子による GOAWAY フレームを送信することができます。 >>1

[21] プロキシなど、処理されなかった要求を再試行できないクライアントが存在するための配慮です >>1

[52] Firefox は正常終了時の GOAWAY最終ストリーム識別子を常に 0 とします。

[32] 誤り符号 NO_ERROR (0x0) は、 誤りではないことを表します。例えば、 GOAWAY では接続の華麗な終了を表します。 >>30

[33] GOAWAY 以外で使えるのかどうかは不明です。

[29] 接続エラーでは GOAWAY フレームを送信するべきです >>44。 その後TCP接続を閉じなければなりません >>44

[28] フロー制御のエラーで送信されることがあります。

[43] サーバーは、ストリーム識別子が枯渇したら、 GOAWAY フレームを送信してクライアントに新しい接続を開かせることができます >>42

[51] ChromeFirefox も、受信した GOAWAY フレームに関する接続エラーでも GOAWAY フレームを送信します。

処理

[14] 受信者は、ストリーム識別子0x0 以外なら、 接続エラー PROTOCOL_ERROR としなければなりません >>1

[40] 受信者は、payload が短すぎるか、設定 SETTINGS_MAX_FRAME_SIZE より長いなら、接続エラー FRAME_SIZE_ERROR としなければなりません >>41

[8] GOAWAY フレーム受信者は、 示されたストリーム識別子より大きなストリーム識別子ストリームは最初から作られなかったものとして扱うことができます。 >>1

[6] GOAWAY フレーム受信者は、新しいストリームを開いてはなりません>>1

[7] 新しい接続を確立して新しいストリームを開始しても構いません >>1

[17] 接続が閉じられるより前に完全に閉じられていない、 最大ストリーム識別子以下ストリーム識別子ストリームでは、 冪等な動作を除き、何らの動作も再試行できません。 最大ストリーム識別子より大きなストリーム識別子ストリームでは、 新しい接続で安全に再試行できます。 >>1

[16] GOAWAY フレーム無しで閉じられた接続では、 実質的な最終ストリーム識別子は最大のストリーム識別子とします。 >>1

[48] ChromeFirefox も、 GOAWAY を受信しても、 自身にとって特にエラーでなければ、エラー無しと扱うようです。 (接続を閉じる場合、受信した誤り符号に関わらず、 FirefoxNO_ERRORGOAWAY を送信します。)

[49] ChromeFirefox も、 NO_ERROR なら、 最終ストリーム識別子より小さなストリーム識別子ストリームは、 引き続き処理を続行します。 (接続を閉じませんし、 GOAWAY の次に更にフレームがあれば通常通り処理します。) 大きなストリーム識別子ストリームは、 ネットワークエラーとします。 その後 closed でないストリームがなくなった時点で、 (FirefoxNO_ERRORGOAWAY を送信して) 接続を閉じます。

[50] 最終ストリーム識別子より大きなストリームも、自動再試行はしないようです。
[53] APNs Provider API () <https://developer.apple.com/jp/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html>

APNsは、確立済みのHTTP/2接続を停止しようとする場合、GOAWAYフレームを送信します。GOAWAYフレームのペイロードにはJSONデータがあり、そのreasonキーに、停止の理由を表す値が入っています。