[25] 
[[HTTP]]
の
[DFN[[CODE(HTTP)@en[[[RST_STREAM]]]]]] [[フレーム]]は、
[[ストリームエラー]]その他の理由で[[ストリーム]]を終了させることを表します。

* 仕様書

[REFS[
- [17] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-2.2>
- [18] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-4.1>
- [19] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-5.1>
- [13] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-5.4.2>
- [1] '''[CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-6.4>'''
- [27] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-8.3>
- [36] [CITE@en-US[Fetch Standard]] ([TIME[2016-03-25 18:55:45 +09:00]] 版) <https://fetch.spec.whatwg.org/#concept-http-fetch>
]REFS]

* 意味

[2] [CODE[[[RST_STREAM]]]] [[フレーム]] ([[フレーム型]] [CODE[[[0x3]]]])
は、[[ストリーム]]を直ちに終わらせるものです [SRC[>>1]]。

[35] [CODE[[[END_STREAM]]]] [[フラグ]]とは違って、異常終了を表します。
おおよそいつでも送信できます。

* 構文

[8] [[ストリーム識別子]]を指定しなければ[['''なりません''']] [SRC[>>1]]。
[CODE[[[0x0]]]] は指定できません。

;; [30] [[接続]]を閉じるときは [CODE(HTTP)@en[[[GOAWAY]]]] [[フレーム]]を使います。

[6] [[フラグ]]はありません [SRC[>>1]]。 0 でなければ[['''なりません''']] [SRC[>>18]]。
[[受信者]]は無視しなければ[['''なりません''']] [SRC[>>18]]。

[FIG(packet)[
:width:8

= 1 0
= 1 0
= 1 0
= 1 0
= 1 0
= 1 0
= 1 0
= 1 0
]FIG]

[4] [[payload]] は、次の欄を含みます。
[FIG(list members)[
:[5] [RUBYB[[[誤り符号]]]@en[Error Code]]:
[[符号無し]]32ビット[[整数]]
([[ネットワークバイト順]] [SRC[>>17]]) で[[誤り符号]]を表します [SRC[>>1]]。
[[誤り符号]]は、[[ストリーム]]を終わらせる理由を表します [SRC[>>1]]。
]FIG]

[FIG(packet)[
:width:32

= 32 誤り符号
]FIG]

* 文脈

[3] [CODE[[[RST_STREAM]]]] [[フレーム]]は、[[ストリームエラー]]の際に送信されます [SRC[>>13]]。

[10] [[idle]] 状態の[[ストリーム]]に送信しては[['''なりません''']] [SRC[>>1, >>19]]。
その他の状態の[[ストリーム]]で送信できます。ほとんどいつでも送信できますが、
(他の[[ストリーム]]も含めて) [CODE[[[CONTINUATION]]]] [[フレーム]]が送られるべき位置で送ることはできません。

[14] 受信した [CODE[[[RST_STREAM]]]] [[フレーム]]に対して
[CODE[[[RST_STREAM]]]] [[フレーム]]を送信しては[['''なりません''']] [SRC[>>13]]。

[20] [[reserved (local)]] 状態の[[ストリーム]]について、
予約解除のために使うことができます [SRC[>>19]]。

[15] [[フロー制御]]の都合で送信されることがります。

[16] [[クライアント]]からの[[要求]]の送信途中で[[サーバー]]がもう[[要求]]の続きは不要であることを示すために
[CODE[[[RST_STREAM]]]] を送信することができます。

;; [[HTTP応答]]を参照。

[26] [[サーバープッシュ]]が不要と示すために、 [CODE(HTTP)@en[[[RST_STREAM]]]]
を送信することができます。

;; [[サーバープッシュ]]を参照。

[22] [CODE[[[RST_STREAM]]]] [[フレーム]]を送信した直後は、通常の [[closed]]
状態とは異なり、一部の[[フレーム]]を部分的にのみ処理したり、無視したりします [SRC[>>19]]。
いずれにせよ、受信する準備をしておかなければ[['''なりません''']] [SRC[>>13]]。

[24] [CODE(HTTP)@en[[[RST_STREAM]]]] [[フレーム]]を複数回送信する[['''べきではありません''']]。
ただし [[closed]] になった後 1[[RTT]] を経過しても[[フレーム]]を受信し続ける場合を除きます。
[SRC[>>13]]

;; [[ストリーム]]の状態遷移の項を参照。

[28] [CODE(HTTP)@en[[[CONNECT]]]] では、[[TCP]] [CODE[[[RST]]]] などのエラーに相当します。

;; [CODE(HTTP)@en[[[CONNECT]]]] 参照。

[37] [CODE(HTTP)[303]] を除く [[HTTPリダイレクト]]の受領直後に[[クライアント]]が
[CODE(HTTP)[RST_STREAM]] を送信することが[RUBYB[推奨]@en[encourage]]されています [SRC[>>36]]。

* 処理

[9] [[受信者]]は、[[ストリーム識別子]]が [CODE[[[0x0]]]] なら、
[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]] としなければ[['''なりません''']] [SRC[>>1]]。

[34] [[ストリーム]]の状態遷移の項も参照。

[11] [[受信者]]は、[[ストリーム]]が [[idle]] 状態なら、
[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]] としなければ[['''なりません''']] [SRC[>>1]]。

[33] [[Chrome]] も [[Firefox]] も、未使用 ([[idle]]) の[[ストリーム]]の
[CODE[[[RST_STREAM]]]] を受信しても、エラーとはしません。 [TIME[2015-10-10T11:58:17.300Z]]

[31] [[Firefox]] は [CODE[[[HEADERS]]]] より前に [CODE[[[RST_STREAM]]]]
を受信したら[[接続エラー]] [CODE[[[PROTOCOL_ERROR]]]] とするようです。
([[Chrome]] は何も送信しません。) 自身が [CODE[[[HEADERS]]]]
を送信したら [[open]] 状態になっているはずなので、[[接続エラー]]とするのは不審です。
[TIME[2015-10-10T11:42:35.00Z]]

[12] [[受信者]]は、[[payload]] の長さが 4 以外なら、
[[接続エラー]] [CODE[[[FRAME_SIZE_ERROR]]]] としなければ[['''なりません''']] [SRC[>>1]]。

[7] 指定された[[ストリーム]]を [[closed]] 状態へと移行させます [SRC[>>19]]。
[[受信者]]は、以後 [CODE[[[PRIORITY]]]] 以外の[[フレーム]]を送信しては[['''なりません''']]
[SRC[>>1]]。しかし[[送信者]]はなおも受信する準備をしなければ[['''なりません''']]
[SRC[>>1]]。

[32] [CODE[[[END_HEADERS]]]] より後で [CODE[[[END_STREAM]]]] より前に
[CODE[[[RST_STREAM]]]] を受信すると、[[Firefox]] も [[Chrome]]
も[[ネットワークエラー]]とします。その [CODE[[[RST_STREAM]]]]
やそれ以後の同じ[[ストリーム]]の[[フレーム]]は無視するようです。 [TIME[2015-10-10T11:53:35.600Z]]

[23] [[closed]] 状態で受信した [CODE(HTTP)@en[[[RST_STREAM]]]] は、
状況によって無視したり、エラーとしたりします [SRC[>>19]]。

* DoS 攻撃

[48] 
令和5年10月に大規模 [[DoS攻撃]]があり、 [[HTTP/2]] プロトコル実装上の[[脆弱性]]と報告されました。

[44] [CITE@en[CVE Record | CVE]], [TIME[2023-10-10T20:41:36.000Z]], [TIME[2023-10-11T05:10:56.217Z]] <https://www.cve.org/CVERecord?id=CVE-2023-44487>

[42] [CITE@en[HTTP/2 Rapid Reset: deconstructing the record-breaking attack]], [TIME[2023-10-11T05:09:43.000Z]] <https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/>

[43] [CITE@en[HTTP/2 Zero-Day Vulnerability Results in Record-Breaking DDoS Attacks]], [TIME[2023-10-11T05:10:27.000Z]] <https://blog.cloudflare.com/zero-day-rapid-reset-http2-record-breaking-ddos-attack/>

[45] [CITE@en-US[How AWS protects customers from DDoS events | AWS Security Blog]], [TIME[2023-10-12T22:51:49.000Z]], [TIME[2023-10-13T14:34:40.751Z]] <https://aws.amazon.com/jp/blogs/security/how-aws-protects-customers-from-ddos-events/>

[46] [CITE@en[Google Cloud mitigated largest DDoS attack, peaking above 398 million rps | Google Cloud Blog]], [TIME[2023-10-13T14:35:09.000Z]] <https://cloud.google.com/blog/products/identity-security/google-cloud-mitigated-largest-ddos-attack-peaking-above-398-million-rps?hl=en>

[47] [CITE@en[How it works: The novel HTTP/2 ‘Rapid Reset’ DDoS attack | Google Cloud Blog]], [TIME[2023-10-13T14:35:37.000Z]] <https://cloud.google.com/blog/products/identity-security/how-it-works-the-novel-http2-rapid-reset-ddos-attack?hl=en>

[49] >>47 [CODE[GOAWAY]] による対処についても言及あり、

* 関連

[29] [[TCP]] の [CODE[[[RST]]]] や [[TLS]] の [[error alert]] と役割が似ています。

* 歴史

[41] 
[[HTTP/2]] で導入されました。

[21] [CITE@en[Allow user agents to transmit RST_STREAM upon seeing a redirect · whatwg/fetch@af0dc92]]
([TIME[2016-03-26 11:55:58 +09:00]] 版)
<https://github.com/whatwg/fetch/commit/af0dc923f7636751996a9762309904511725a1a7>

[38] [CITE@en[Abortable fetch]]
([[jakearchibald]]著, [TIME[2017-09-20 21:59:57 +09:00]])
<https://github.com/whatwg/fetch/commit/0bcd5dfc71ef44319873887f4b83119bd6d0b71d>

[39] [CITE@en[More eargerly send RST_STREAM on redirects]]
([[annevk]]著, [TIME[2017-11-24 20:11:46 +09:00]])
<https://github.com/whatwg/fetch/commit/fd286755e9664d570260c16f7c1933f424d2f39a>

[40] [CITE@en[More eargerly send RST_STREAM on redirects by annevk · Pull Request #638 · whatwg/fetch]]
([TIME[2017-11-30 23:34:01 +09:00]])
<https://github.com/whatwg/fetch/pull/638>