[114] server push は、クライアントから明示的な要求がなくても、 予めサーバーから応答を送信するものです。
[121] 一番最初にフックとなるクライアントからサーバーへの要求が必要とはいえ、 通常の HTTP とは異なり、 サーバーが主体的にクライアントに情報を送信できる仕組みとなっています。
[35] HTTP/2 server push は、 応答とそれに対応する「約束」要求を、 先にクライアントが開始した要求に関連付ける形でサーバーから予め送信 (push) するものです >>34。
[36] server push は、クライアントが元の要求に対する応答を完全に処理するために当該応答が必要になるであろうとわかっている場合に便利です >>34。
[55] server push は、意味的にはクライアントの要求にサーバーが応答を返す通常の場合と同じですが、
要求をクライアントではなくサーバーが (クライアントへと)
PUSH_PROMISE
フレームにより送信します >>34。
[44] サーバーからクライアントへと送信する要求を、 約束要求といいます。
[39] 約束要求は、要求本体を含んではなりません >>34。
[56] PUSH_PROMISE
フレーム (と CONTINUATION
フレーム) が、要求の header block を含みます。
要求のヘッダーを妥当かつ完全に含まなければなりません。 >>34
[49] サーバーは、当該サーバーが権限を有する (authoritative)
:authority
疑似ヘッダー値を含めなければなりません
>>34。
[37] 約束要求は、キャッシュ可能でなければなりません >>34。
[58] サーバーは、 :method
疑似ヘッダーに安全でキャッシュ可能な要求メソッドを指定しなければなりません >>34。
[61] サーバーは、約束された応答を参照するフレームを送信する前に、
PUSH_PROMISE
フレームを送信するべきです。
これによりクライアントが PUSH_PROMISE
フレームを送信する前に別途要求を発行することを防ぐことができます。 >>34
[71] 複数の著者の資源を提供するサーバーは、 他の著者の管轄下のはずの資源をプッシュできてしまわないようにしなければなりません >>70。
[48] 約束要求に続いてサーバーからクライアントへと送信する応答を、 プッシュ応答といいます。
[65] サーバーは PUSH_PROMISE
フレーム
(と CONTINUATION
フレーム) に続けて
(同じストリームで) プッシュ応答を配送開始できます >>34。
[119] Webページは HTML文書から参照される CSS や JavaScript などいろいろなファイルの集合体として構成されますが、 その読み込みの最適化のため、 HTML文書の応答中に server push を使って他の構成ファイルが送信されることがあります。
[120] Web Push Protocol では、 プッシュメッセージ購読資源、 プッシュメッセージ購読集合資源、 受領証購読資源で server push が使われます。
[60] クライアントは、約束要求に完全で妥当なヘッダーの集合が含まれていなければ、
ストリームエラー PROTOCOL_ERROR
としなければなりません >>34。
[40] クライアントは、キャッシュ可能でない約束要求を受信したら、
ストリームエラー PROTOCOL_ERROR
としなければなりません >>34。
[41] クライアントは、安全でない約束要求を受信したら、
ストリームエラー PROTOCOL_ERROR
としなければなりません >>34。
[59] クライアントは、 :method
疑似ヘッダーに安全でない要求メソッドが指定されていれば、
ストリームエラー PROTOCOL_ERROR
としなければなりません >>34。
[42] クライアントは、要求本体の存在を示した約束要求を受信したら、
ストリームエラー PROTOCOL_ERROR
としなければなりません >>34。
[50] クライアントは、サーバーが権限を有する (authoritative)
かプロキシであって対応する要求に関するプッシュ応答を提供するよう設定されていることを検証しなければなりません。
それ以外の値の :authority
疑似ヘッダーが含まれていたら、
ストリームエラー PROTOCOL_ERROR
としなければなりません >>34。
[69] DNS-ID または共通名として example.com
が指定された証明書を使っているサーバーの場合、
https://www.example.org/doc
のプッシュ応答を提供してはなりません。 >>34
[45] プッシュ応答は、キャッシュ可能なら、 クライアントの HTTPキャッシュに蓄積できます >>34。
[46] プッシュ応答は、ストリームが open である間、起源サーバーで成功裏に検証されたものとみなします >>34。
[47] プッシュ応答は、キャッシュ可能でなければ、 HTTPキャッシュに蓄積してはなりません。 別途応用に提供しても構いません。 >>34
[51] 中間器は、サーバーからの push をクライアントへと転送しないことにしても構いません。 またサーバーから送られてこなくても独自にクライアントに push しても構いません。 >>34
[66] クライアントは、 PUSH_PROMISE
フレームを受信し、
プッシュ応答を受け入れることにしたら、
そのストリームが閉じられるまでの間、
その応答に対する要求を発行するべきではありません >>34。
[67] クライアントは、何らかの理由でプッシュ応答を受信したくない時や、
サーバーがプッシュ応答を送信し始めるまでの時間がかかりすぎている時は、
RST_STREAM
フレームに誤り符号 CANCEL
や
REFUSED_STREAM
を指定し、当該ストリーム識別子を指定して送信できます >>34。
[73] サーバーが authoritative でない応答をキャッシュしたり、 使ったりしてはなりません >>70。
[75] 例えば example.com
のサーバー証明書を持つ TLS接続上で
https://example.net/
の応答がプッシュされても、
使ってはなりません。
[30] Firefox も Chrome も、異なる起源の約束要求を受信した時、
ストリームエラー REFUSED_STREAM
とするようです。
[106] Firefox も Chrome も、この検査を (PUSH_PROMISE
の受信時でも fetch 時でもなく) 応答の受信時に行うようです。
[111] 同じ :path
の約束要求を受信したら、
Chrome はストリームエラー PROTOCOL_ERROR
、
Firefox はストリームエラー INTERNAL_ERROR
とします。この検査は PUSH_PROMISE
受信時点で行い、
約束ストリームに対して送信します。
[77] クライアントは、 reserved (remote) 状態にあるストリームの数を制限するべきです。
超過したらストリームエラー ENHANCE_YOUR_CALM
とできます。 >>76
PUSH_PROMISE
フレーム[9] PUSH_PROMISE
フレーム (フレーム型 0x5
) は、
peer に対してストリームを開始することを予め通知するものです >>8。
[23] PUSH_PROMISE
によって予約する順序は、そのストリームを利用する順序と一致していなくても構いません >>8。
[57] ストリーム識別子は、要求が属するストリームを表します >>34。 0x0 を指定することはできません。
[64] PUSH_PROMISE
フレームは、
任意のクライアントが開始したストリームに対して、
サーバーが送信することができます >>34。
[21] peer が開始したストリームで状態が open か half-closed (remote) である場合にしか送信してはなりません >>8, >>34。
[86] 送信すると、指定した約束ストリームIDのストリームの状態は、 idle から reserved (local) へと遷移します >>83。
[3] 設定 SETTINGS_ENABLE_PUSH
が 0 に設定されていれば、
PUSH_PROMISE
フレームを送信してはなりません >>1, >>8。
[81] 受信者は、payload が短すぎるか、設定 SETTINGS_MAX_FRAME_SIZE
より長いなら、接続エラー FRAME_SIZE_ERROR
としなければなりません
>>82。
[4] 設定 SETTINGS_ENABLE_PUSH
を 0 に設定し、
acknowledge されたエンドポイントは、
PUSH_PROMISE
フレームを受信したら、
接続エラー PROTOCOL_ERROR
としなければなりません >>1, >>8。
[22] ストリーム識別子が 0x0
なら、
接続エラー PROTOCOL_ERROR
としなければなりません >>8。
[108] 未使用のストリーム識別子の PUSH_STREAM
を受信すると、約束ストリーム識別子のストリームの側で
Firefox はストリームエラー PROTOCOL_ERROR
、
Chrome はストリームエラー STREAM_CLOSED
とするようです。ただし約束ストリーム識別子が 0
なら、接続エラー PROTOCOL_ERROR
とするようです。
[109] 要求送信済みで HEADERS
受信前のストリーム (PUSH_PROMISE
で作成されたストリーム含む。)
のストリーム識別子で PUSH_PROMISE
を受信したら、 Firefox も Chrome もエラーとはしません。
[110] END_STREAM
受信済みのストリームで PUSH_PROMISE
を受信したら、 Firefox は接続エラー PROTOCOL_ERROR
、
Chrome はストリームエラー PROTOCOL_ERROR
とします。
[28] 約束ストリーム識別子が idle 状態でないなら、
接続エラー PROTOCOL_ERROR
としなければなりません >>8。
[93] 明記されていませんが、送信者が開始できないストリーム識別子や 0の場合も同様に扱うべきと思われます。Chrome や Firefox はそのようにしています。
[26] 受信者は、ストリームの状態が open でも half-closed (local)
でもなければ、接続エラー PROTOCOL_ERROR
としなければなりません
>>8。
[27] ただし、RST_STREAM
を送信した後 (の closed 状態) には、
受信した PUSH_PROMISE
を処理しなければなりません >>8, >>83。
[32] 受信者は、詰めに 0 以外があれば接続エラー PROTOCOL_ERROR
としても構いません。 >>29
[33] 受信者は、詰め長が可能な長さより長ければ、
接続エラー PROTOCOL_ERROR
としなければなりません >>29。
[24] 受信者は、約束されたストリーム識別子を参照する
RST_STREAM
フレームを返送することで、
約束ストリームを拒絶することができます >>8。
[84] PUSH_PROMISE
フレームを受信すると、
その約束ストリームIDのストリームは、idle 状態から
reserved (remote) 状態へ遷移します。 >>83
[88] 約束ストリームIDのストリームは、ストリーム識別子のストリームに (重みは既定値で) 依存性を持つ状態となります >>87。
[25] ストリームの状態遷移の項、ヘッダーリストの項も参照。
[19] END_HEADERS
フラグが設定されていない場合、
次のフレームが CONTINUATION
で無いか、
違うストリームなら、接続エラー PROTOCOL_ERROR
としなければなりません >>8。
[53] サーバーは、PUSH_PROMISE
フレームを受信したら、
接続エラー PROTOCOL_ERROR
としなければなりません >>34。
[107] PUSH_PROMISE
のヘッダーが奇形な場合、
Chrome はエラーの種別に応じて接続エラー COMPRESSION_ERROR
または約束ストリームのストリームエラー PROTOCOL_ERROR
、
Firefox は接続エラー PROTOCOL_ERROR
とするようです。
[122]
JavaScript の Promise
とは無関係です。
[2] SETTINGS_ENABLE_PUSH
(0x2
) は、
server push を無効化するために使うことができます。 >>1
[5] 値 1 は、 server push を認めることを表します。これは初期値です。 >>1
[6] 値 0 は、 server push を認めないことを表します >>34。
[7] 1
と 0
以外の値は、接続エラー PROTOCOL_ERROR
としなければなりません >>1。
[54] クライアントは、 SETTINGS_ENABLE_PUSH
が 0
以外の値に設定されようとしたら、
拒絶して接続エラー PROTOCOL_ERROR
としなければなりません
>>34。
[102] 実際には Chrome も Firefox も、値の検査をしていないようです。
[68] クライアントは、設定 SETTINGS_MAX_CONCURRENT_STREAMS
によってサーバーが並行してプッシュできる応答の数を制限できます。
0 を設定することで、server push のためのストリームの作成を抑制できます。
ただし PUSH_PROMISE
フレームの送信を禁止するものではありません。 >>34
[92] Chrome や Firefox は、 fetch に当たり PUSH_PROMISE
を受け取っていれば、新たに要求を送信せずにその応答を待つようです。
しかし fetch の呼び出し方法 (やタイミング?) によって別途要求を送信することもあります。
[127] Improving HTTP Latency, , https://web.archive.org/web/20010603065233/http://archive.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/mogul/HTTPLatency.html
[89] IIS 10.0 と ASP.NET 4.6 で HTTP/2 のサーバープッシュが使えるようになっていたので試した - しばやん雑記 ( 版) http://blog.shibayan.jp/entry/20150506/1430846908
[90] HTTP/2 server push support · Issue #51 · whatwg/fetch ( 版) https://github.com/whatwg/fetch/issues/51
[91] HTTP/2 Push + browser cache - Google ドキュメント ( 版) https://docs.google.com/document/d/1v3rjj0DMDTocUtZSjOwdwt8D-yhCw6R5SVaax4MPgMc/edit?pli=1
[94] Issue 135485 - chromium - SPDY - Pushed stream - crash accessing https://jetty.intalio.com:10111/spdy - An open-source project to help move the web forward. - Google Project Hosting ( 版) https://code.google.com/p/chromium/issues/detail?id=135485
[95] Issue 377538 - chromium - Robust support for HTTP/2 server-push - An open-source project to help move the web forward. - Google Project Hosting ( 版) https://code.google.com/p/chromium/issues/detail?id=377538
[96] Issue 328167 - chromium - Server-push for proactive cache management - An open-source project to help move the web forward. - Google Project Hosting ( 版) https://code.google.com/p/chromium/issues/detail?id=328167
[97] 958712 – HTTP/2 push continuations not completely implemented ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=958712
[98] draft-thomson-webpush-http2-02 - Generic Event Delivery Using HTTP Push ( 版) http://tools.ietf.org/html/draft-thomson-webpush-http2-02
[99] 1072478 – loading never stops due to slow SPDY push ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=1072478
[100] 1167851 – HTTP/2 pushes and WINDOW_UPDATA frame ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=1167851
[103] 1127618 – PUSH_PROMISE is immediately rejected with a RST_STREAM ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=1127618
[104] Issue 331663007: Implement PUSH_PROMISE handling in spdy_session - Code Review ( 版) https://codereview.chromium.org/331663007
[105] Issue 331663007: Implement PUSH_PROMISE handling in spdy_session - Code Review ( 版) https://codereview.chromium.org/331663007
[112] Preload ( 版) https://w3c.github.io/preload/#server-push-http-2
[115] RFC 8030 - Generic Event Delivery Using HTTP Push () https://tools.ietf.org/html/rfc8030
[117] google/node-h2-auto-push () https://github.com/google/node-h2-auto-push
[118] preload, destinations, and module scripts · Issue #486 · whatwg/fetch () https://github.com/whatwg/fetch/issues/486
[123] HTTP/2 | 2020 | The Web Almanac by HTTP Archive () https://almanac.httparchive.org/en/2020/http2#goodbye-server-push
[124] Web Performance Calendar » HTTP/2 Push: The details () https://calendar.perfplanet.com/2016/http2-push-the-details/
[125] Intent to Remove: HTTP/2 and gQUIC server push () https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/vOWBKZGoAQAJ?pli=1
[126] b5428cd580034a30c7c76769241ebe565461fc53 - chromium/src - Git at Google, https://chromium.googlesource.com/chromium/src/+/b5428cd580034a30c7c76769241ebe565461fc53