[535] HTTP 通信の直接の当事者間の仮想回路を、 接続といいます。
[564] 接続の両端はクライアントと鯖ですが、串が介在する場合、 一方又は両方が串となることもあります。
[46] 接続は、2つのエンドポイントの間のトランスポート層の接続です >>45。
[50] 接続のエンドポイントは、クライアントかサーバーかのいずれかです。
[48] HTTP/0.9 や HTTP/1.0、HTTP/1.1、HTTP/2 >>47 の接続は、 TCP接続上で動作するアプリケーション層プロトコル輸送路です。
[204] 利用者エージェントは、 接続プールとして接続群を保持します >>203。
[205] 接続は、起源とcredentialsの組で識別されます >>203。
[119] エンドポイントは、接続ごとに次の状態を持ちます。
[217] WebSocket接続は、更に WebSocket 固有の状態を持ちます。
[566] 接続がどのように処理されるかは、HTTPの版によって異なっています。 HTTPの版は、 HTTP/1.1 以下と HTTP/2 のいずれであるかは TLS の ALPN により示され、更に HTTP/1.1 以下の場合には接続上を流れるHTTPメッセージの先頭行でそのいずれであるかが示されます。
[10] HTTP/1.1 以下の場合、理論上は要求ごと、 あるいは応答ごとに異なるプロトコルの版を記述することもできますが、 普通はそのようなことはありません。 そのような状況で受信者がどう処理するべきかは不明です。
[136] 実際の Webブラウザーは、 HTTP/1.1 と HTTP/1.0 と HTTP/0.9
が同じ接続内に混在しても、それぞれの動作に従い処理します。
1xx
と最後の応答でプロトコルの版が異なっていても構いません。
[11] 鯖がおかしなメッセージを返したことによって HTTP/1.1 や HTTP/1.0 の接続の途中で HTTP/0.9 メッセージが出現したと判断し、おかしな動作をする Webブラウザーもありました。セキュリティー上の問題となる可能性もありますから、 注意が必要です。
[54] HTTPの版の決定方法については、プロトコルの版を参照してください。
[206] 利用者エージェントクライアントが起源起源、
boolean credentials、
boolean 事前 (既定値は偽)
について接続を得るには、
次のようにします >>203。
[231] 事前が真の場合、HTTP接続の確立 (>>209) はできれば完全に行うべきですが、 資源制約その他の理由で叶わなければ、 一部または全部を省略して構いません >>230。
[219] 後述の通り、同じサーバーに複数の接続を同時に確立できます。 接続プールには、起源とcredentialsの組が同じ接続が複数含まれているかもしれません。 何個まで含められるかや、それらからどうやって選ぶか(選ばないか)は、 クライアントに委ねられています。 (パフォーマンスや利用可能資源などのトレードオフを考慮する必要があります。) 事前が真なら、 既に十分な数の接続があれば、新たな接続を確立しないことにするかもしれません。 事前が偽なら、接続数が減少するまでHTTP接続の確立の実処理を遅延させる必要がありそうです。
[216] WebSocket接続を得る手順は、これとは別に用意されています (詳細はそちらの項を参照)。 通常のHTTP接続を得る手順とおおむね同趣旨ではあるのですが、 WebSocket は必ず新しい接続を使うので、接続プールは参照しません。 (これは事前接続が利用されないことも意味します。)
[218] これらは、 HTTP-network fetch から呼び出されます。
[224] 接続を得るは、事前接続の開始からも呼び出されます。
[531] 接続先の鯖は、他のインターネットのアプリケーション層プロトコルと同じように、 URL などによって指定されたドメイン名や IPアドレスなどとポート番号とを使って識別されます。
[67] URL scheme が http:
なら TCP を、
https:
なら TLS over TCP を下位層として使います。
http:
URL
に接続する前に https:
URL へと書き換えます。
この処理は fetch で行われます。 HTTP接続の確立の段階では、
既に書き換え済みです。[197] クライアントが代替サービスに対応しており、接続先の URL scheme、 ホスト、ポートの組に対して適用可能な代替サービスを知っている場合、 接続先のプロトコル、ホスト、ポートをその代替サービスのものとします。
[285] Firefox は、 Opportunistic HTTP/2 Security が利用可能なら、 そちらに切り替えます。
[533] プロキシは、利用者エージェントの設定などの実装依存の方法で指定されます。 串が指定されている場合は、接続先はサーバーではなく、プロキシとなります。
[19] 串に名前解決を委ねる場合を除き、通常はホスト部の名前解決を行い、
IPアドレスを取得し、それを接続先の鯖とします。名前解決は DNS
によって行うのが基本ですが、 /etc/hosts
や NetBIOS
など当該システムが実装している他の名前解決の仕組みが用いられることもあります。
[530] 接続は、クライアントが鯖 (または串) に対して下位層プロトコルの接続を確立することにより、開始されます。 鯖は下位層プロトコルと OS 等の API (ソケットなど) の規定に基づき予め接続を受け付ける状態で待っている必要があります。
[536] HTTP/1.1 以下では、他の多くのアプリケーション層プロトコルとは違って、 接続の初期化のようなプロトコル上の手続きはなく、すぐに要求を送信できます。
[568] 接続が確立されると、クライアントは鯖に要求を送信します。 その送信のタイミングは特に規定されていませんが、通常は即座に送信します。 後述の通り、鯖は通常タイムアウトを設定しており、一定時間内に要求が送信されなければ、 エラーとして扱います。
[20] クライアントが名前解決に失敗した場合や下位層プロトコルの接続の確立に失敗した場合は、 当然ながら HTTP接続を利用することはできず、要求を送信できません。
[121] HTTP/1.1 以下は単純なテキストベースのプロトコルなので、 攻撃者の指示によりクライアントが他のプロトコルに接続できる文字列を送ることができてしまう場合があります (プロトコル横断攻撃)。
[113] Webブラウザーは port blocking により他のプロトコルが使うことが多いポートへのアクセスを拒み、 cross-protocol attack を難しくしています。
[110] HTTP/2 over TLS は ALPN によりプロトコルを明示でき、 また暗号化のため TCP 上のバイト列を制御することが難しいため、 cross-protocol attack は困難です >>111。
[123] HTTP/1.1 以下 over TLS は暗号化のため、平文プロトコルを攻撃することは困難です。 しかし ALPN を使わなくて良いため、 TLS 上の非 HTTP プロトコルは攻撃できるかもしれません。
[112] HTTP/2 over TCP は接続序文により HTTP/1.1 以下の実装の誤動作を防ごうとしていますが、 非 HTTP プロトコルに対する cross-protocol attack を防ぐものではありません >>111。
[311] HTTPサーバーの実装によっては、 HTTPS が期待されるところにHTTP要求を受信すると、 エラーのHTTP応答を返します。
[87] HTTP/1.1 以下では、1つの接続で同時に送受信できる応答は1つだけです。 1つの文書に埋め込まれた複数の画像が存在する場合など、 クライアント側の処理性能の向上のためには複数の接続を並列に確立する必要があります。
[88] HTTP/1.0 の keep-alive や HTTP/1.1 の持続的接続やパイプライン化を用いると 1つの接続を再利用して次の応答を受信することができ、 TCP接続の再確立や次の要求の送受信の時間を節約できますが、 前の応答が完了するまで次の応答は送信できませんから、 すぐにレンダリング開始したいなら、やはり複数の接続が必要となります。
[89] しかし接続数が多すぎるとサーバーやネットワークに過剰な負荷を与えてしまう虞があるため、 クライアントは適当な上限を設けるべきです。
[550] 旧仕様の RFC 2616 までは、あるクライアントからある鯖 (や串) への同時接続数は2以下とするべきだとされていました >>549。
[551] RFC 7230 は、応用によっては非現実的なので、特定の上限は設けないが、 クライアントは接続を開くのには保守的であるようにと求めています >>548。
[552] 多くの Webブラウザーは、00年代前半までは RFC の上限を既定値とし、 設定によっては更に増やすこともできるようになっていました。 しかしその後 Ajax の普及などに伴い徐々に制限が緩和されています。
[91] HTTP/2 では持続的接続が基本動作となっており、 クライアントは必要が無いと判断するまで接続を閉じずにいることが期待されています >>90。クライアントは 1つの接続で複数のストリームを使って並行して応答を受信できます。 クライアントは、プロキシを含むサーバーへの接続を、 ホストとポートの組に対して複数開くべきではありません >>90。
[93] HTTP/2 クライアントは、異なる値を SNI に指定する場合や異なる TLS クライアント証明書を指定する場合は、同じ IPアドレスと TCPポートに対して複数の接続を開いて構いません。 しかし同じ指定で複数の接続を開くことは避けるべきです。 >>90
[92] HTTP/2 クライアントは、既存の接続がストリーム識別子空間を使い果たしつつある場合や、 TLSセッションの鍵の更新のため必要な場合、 エラーを検出した場合には、代替となる接続を新たに開くことができます >>90。
[237] WebSocket に関しては、他の接続が閉じられるのを待つ処理が明文化されています。
[236] 他の接続を待つ場合は、次のようにしなければなりません >>234。
[238] この制限は、著者が多数の WebSocket接続を開いて DoS攻撃することを難しくするためのものです >>234。
[241] HTTP/1 (非 WebSocket) と HTTP/2 に関しては明文規定はありませんが、 n 以外は同様に処理するべきものと思われます。 (プロキシへの接続と起源サーバーへの接続とでも n は違いそうです。)
[94] HTTP/1.0 keep-alive、HTTP/1.1 持続的接続、HTTP/2 では、同じ接続を複数の要求と応答の組の送受信に再利用できます。
[95] HTTP/1.0 と HTTP/1.1 でどのような場合に接続を再利用できるのかは、 明確な規定がありません。
[96] HTTP/2 の起源サーバーへの接続は、直接のものであれ CONNECT
トンネル経由であれ、 authority が異なっていても当該起源サーバーが
authoritative である限り、再利用できます。 >>90
[97] 具体的には、 TLS 無しの TCP では、ホストが同じ IPアドレスに解決されることをいいます。 >>90, >>108, >>109 (もちろんポート番号も一致する必要があります。)
[98] https
では、 TCP のみの場合の条件に加え、
サーバー証明書が新しい TLS接続の場合と同様の検査を満足しなければなりません。
>>90, >>108, >>109
[104] サーバーの構成によっては、 SNI で指定されたホストによって中間器が異なる起源サーバーを選択する場合など、
クライアントが (機密かもしれない) 要求を誤ったサーバーに送ってしまう可能性もあります。
サーバーは、クライアントに接続を再利用してほしくない場合、
authoritative でないことを 421
応答によって表明できます。 >>90
421
応答を返すよう注意が必要です。[401] 通常の HTTP の通信では、HTTPメッセージが接続上を送受信されます。
[523] HTTPメッセージは、要求メッセージまたは応答メッセージです。 現在の HTTP ではクライアントから鯖へと送信されるのが要求、 鯖からクライアントへ送信されるのが応答と決まっています。
[52] テキスト形式プロトコルである HTTP/1.1 以下では、 メッセージは RFC 822 風のテキスト形式で表現され、 接続上を直接送受信されます。
[53] バイナリー形式プロトコルである HTTP/2 では、 メッセージは複数のフレームの列で表現され、 接続内のストリーム上のバイト列として送受信されます。
[55] 要求をクライアントからサーバーへと送信し、 それに対して応答をサーバーからクライアントへと送信するのが基本的な動作です。 接続を開き、送受信を行ってから、接続を閉じます。
[522] 持続的接続機能を使うと、1つの接続で複数の要求と応答の組をやりとりすることができます。
[513] 要求と応答の対応関係は、明示されません。 要求が送信されたのと同じ順に応答が送信されます。 >>512
[525] 応答は、必ず要求に対する反応として送信されます。 要求がないのに応答が送信されることは、原則としてありません。
[528] メッセージの境界は、メッセージ自体によって、または接続が閉じられることにより識別されます。下位層プロトコルはオクテット列の送受信のみが要求されています。
[132] 鯖は、少なくても1つは要求行の前の CRLF を無視するべきです >>131。 実際には他の改行と同じく、省略可能な CR とその後の LF が無視されるようです。
[133] Apache も nginx も、要求の前の任意の個数の改行を無視するようです。
[546] パイプライン化により、要求に対する応答の到着を待たずに次の要求を送ることもできます。
[402] CONNECT
メソッドに対して 2xx
応答が返された場合、メッセージはそこで終端され、
以後はトンネルとなります。詳しくは CONNECT
の項を参照してください。
[562] Upgrade:
によってプロトコルが切り替えられる場合、
鯖によって 101
が返され、それよりも後は新しいプロトコルに切り替わります。
詳しくは Upgrade:
や WebSocket接続の確立、
WebSocket接続の項を参照してください。
CONNECT
や Upgrade:
の組み合わせは思わぬ副作用を生むかもしれません。例えば別のプロトコルに切り替わる前にクライアントがデータを送信していると、
鯖がそれをどう解釈するかが曖昧となり、セキュリティーや相互運用性の問題を引き起こすことがあります。
RFC 7472 や HTTPS の歴史の項も参照。[167] 前の応答を受信し終えてから次の要求の送信を始めるまでの間に受信したデータは、 どのブラウザーも捨てるようです。
[168] 素のHTTP ではどのブラウザーも最初の要求の送信前に受信した (であろう) データは最初の要求への応答とみなすようです。
[169] HTTPS では Chrome と IE は (TLS handshake 後に送られた) 最初の要求の送信前にデータを受信したら、最初の要求をネットワークエラーとするようです。
[171] Firefox は HTTPS で最初の要求の前に受信しても最初の応答とみなすように見えます。 しかし応答後に受信したデータがあると次の要求にその接続を使わないように見えます。 (Chrome では HTTP と同じく応答後のデータは無視するように見えます。)
[265] nginx や Apache は最初の要求の前に LF または CRLF があれば、これを無視します。 それ以外の CR と LF の列があると、 nginx はおかしな状態になり、 Apache は要求行として解釈しようとしてエラーを返します。
[266] nginx は最初の要求と次の要求の間で任意の CR と LF の列を無視します。 Apache は LF または CRLF の任意個の繰り返しを無視します。
[80] ストリームの処理については、ストリームやフレームを参照。
[81] メッセージの送受信については、HTTPメッセージ、 HTTP要求、HTTP応答、サーバープッシュを参照。
[51] 両エンドポイントは、メッセージを構成するフレームの他、
適宜 PING
フレーム、
フロー制御のための WINDOW_UPDATE
フレーム、
設定変更のための SETTINGS
フレームなどを送受信することになります。
[284] Opportunistic Security for HTTP/2 では、
実際の要求と応答の送受信の前に、
/.well-known/http-opportunistic
の送受信が発生します。
ただし、HTTPキャッシュにより省略される場合もあります。
[225] 基本的には、接続が確立されたら、すぐに最初の要求が送信されます。
[226] 事前接続を用いる場合は、接続の確立から最初の要求の送信までに若干の時間があるかもしれません。
[228] 同じ接続を再利用 (>>94) して次の要求を送信する場合もあります。 これも前の要求と応答の後すぐに送信される場合もあれば、時間を置く場合もあります。
[227] サーバーは、一定時間内に要求が送信されなければ、 タイムアウト (>>554) で接続を閉じるかもしれません。
[569] 応答が送信されるタイミングは、特に規定されていません。 鯖が要求の末尾まで読み終えるよりも先に送信される可能性もありますし、 要求がすべて読み終わってからしばらく経ってようやく送信される可能性もあります。 要求が送信され始めるより前に応答が返されることもあるかもしれません。 long poll では、応答の送信開始や送信完了までの待機時間が長いかもしれません。
[579] 要求が非妥当である場合や、要求の要求行やヘッダー、
あるいはメッセージ本体の途中で鯖が処理できないと判断した場合、
鯖が要求をすべて読み終わる前やクライアントが要求を送信し終わる前に鯖がエラー
(400
や 413
や 505
など) を返したり、
接続を閉じたりすることがあります。
[44] クライアントは通常タイムアウトを設定しており、一定時間内に応答の一部または全部が返されなければ、 通信やサーバーのエラーとみなします。タイムアウトまでの時間は、アプリケーションの性質やサーバーやクライアントの用途、 想定されるネットワークの状態など様々な因子に依存するため、一概には決められません。
[572] メッセージを構成するデータの送信速度は、一様でなくても構いません。
例えば、鯖が multipart/x-mixed-replace
応答を返す場合、
ある程度の時間をあけて複数の本体部分を送信し続けることになります。
[573] 用途によっては、 payload body が無限に長いこともあります。 その場合は、相手側によって接続が閉じられたり、 ネットワークエラーなど外部的な要因で接続が閉じられたりしない限り、 データの送信が継続されます。
1xx
応答[514] 1xx
応答が最終応答より前に送信される場合には、
1つの要求に複数の応答が対応することとなります。 >>512
[56] 1xx
応答は、 HTTP/1.1 以上の場合に、
最後の応答の前に0個以上使うことができます。
[570] 要求に 100-continue
が指定されている場合には、
要求のヘッダー部を読み終えた時点で鯖が 100
応答を返し、その後要求のメッセージ本体を処理してから最終的な応答を返すことが期待されています。
(詳しくは 100-continue
を参照してください。)
[65] HTTP/2 では、クライアントが要求するかわりにサーバーが要求をクライアントへ送信し、 その後サーバーからクライアントへ応答を送信できます。
[66] 構文上はサーバーは任意の URL の応答を送信できます。 実際には当該サーバーが authoritative であることなどいくつかの制限があります。
[558] クライアント、鯖、串はいずれも任意の時点で接続を閉じて構いません >>553, >>73。
[61] HTTP/2 では、まず GOAWAY
フレームを送信するべきです
>>60, >>90, >>73。
しかし送信しない実装もあります。 GOAWAY
を参照。
[184] Firefox は、相手が GOAWAY
なしで接続を閉じた場合でも、
(他に問題がなければ) 誤り符号 NO_ERROR
の GOAWAY
を送信してから、接続を閉じます。 Chrome はすぐに接続を閉じます。
[576] 鯖は過負荷時に (503
を返すか、または)
直ちに接続を閉じても構いません >>577。
[540] 接続はいつでも予告なく閉じられることがあります >>539 から、実装は、接続の終了に対して頑強でなければなりません。
[567] HTTP/0.9 や HTTP/1.0 では、 Keep-Alive
が有効な場合を除き、
メッセージの終わりで接続も閉じなければなりません。
[537] 持続的接続の終了は、 Connection: close
によって表します。
[4] HTTP/1.1 以下では、メッセージ本体の終了を接続を閉じることによって通知することがあります。
[561] 鯖は、下位層プロトコルの特性によりメッセージの一部又は全部が失われないように注意して接続を閉じる必要があります。 詳しくはTCPリセット問題を参照してください。
[165] サーバーによっては FIN
を受け取った時点で応答の残りの転送を取りやめるようなので、
クライアントは応答の受信が終わるまで、要求の送信が終わったとしても接続を閉じてはいけません。
[64] HTTP/2 では、ストリーム識別子が枯渇するとそれ以上メッセージを送受信できなくなってしまいます。
クライアントは、新しい接続を確立して新しいストリームを作成できます
>>62。サーバーは、 GOAWAY
フレームを送信してクライアントに新しい接続を開くように求められます >>62。
[135] Chrome と Firefox は、 abort a document による fetch
の中止の際は、正常に (FIN
で) 接続を閉じるようです。
IE は RST
を使うようです。
[5] メッセージ本体が存在し、 Transfer-Encoding:
ヘッダーの最後の転送符号化が chunked
以外である要求メッセージを受け取った時は、 400
応答を返して接続を閉じなければなりません >>3。
[510] Content-Length:
が無視されない場合で、
複数あったり非妥当だったりする場合は、
接続を閉じなければなりません >>3。
[511] Content-Length:
が無視されない場合で、
その長さのメッセージ本体を受け取らずに接続が閉じられたり、
タイムアウトしたりした時には、接続を閉じなければなりません >>3。
[538] 下位ネットワークの障害や接続の当事者のシステム上の障害などによって、 メッセージの途中で接続が中断されたり、 何の送受信も発生しないまま長時間経過したりすることがあります。 こうした場合の処理については、メッセージやメッセージ本体の項を参照してください。
[547] パイプライン化している場合で途中で接続が閉じられたときの処理は、 HTTPパイプラインの項を参照してください。
[40] サーバーの死活監視を行うソフトウェアの中には、 TCP レベルでの検査を行うものもあります。これは TCP接続が確立できることを確認すると、 すぐに切断するものです。この場合 HTTPメッセージを送受信することなく接続が終了しますから、 サーバーはそのような場合も適切に処理できる必要があります。
[559] 鯖は、クライアントが再試行すると期待して接続を閉じるよりは、 できれば持続的接続を維持して、一時的な過負荷はトランスポート層のフロー制御に任せるべきです (閉じて再試行させる方が輻輳を悪化させるかもしれません) >>553。
[560] クライアントはメッセージ本体の送信中に接続を監視して、 鯖が受信を望まず接続を閉じようとしていることがわかれば、 すぐに転送をやめて接続を閉じるべきです >>553。
[578] 串は上流から非妥当な応答を受け取った時、
転送するかわりに 502
応答を返すことができます。
Content-Length:
が非妥当な場合は更に接続を閉じなければならないこともあります。
詳しくは 502
を参照してください。
[74] HTTP/2 接続エラーの場合、 (GOAWAY
の後)
TCP接続を閉じなければなりません >>73。
[77] 誤り符号 ENHANCE_YOUR_CALM
(0xb
)
は、 過負荷を引き起こしかねない動作を peer が示したことを表します >>76。
[554] 鯖は普通はタイムアウトを設定しており、 活性状態でない接続をそれ以上維持しません。 >>553
[555] 串は、クライアントが同じ串により多く接続して来るであろうことから、 タイムアウトを大きめにするかもしれません。 >>553
[556] クライアントもタイムアウトを設定して、 必要のない接続をそれ以上維持しないかもしれません。
[557] タイムアウトしたいクライアントや鯖は、 当該接続を graceful close するべきです >>553。 実装は定期的に接続を閉じる信号を監視して、 適宜応答するべきです >>553。
[12] 鯖によっては、HTTP/1.0 応答を送り終えた後もしばらく接続を閉じないものがあるといわれています。
[71] nginx は、接続後何も送信しないでいると、タイムアウトにより何も返さずに接続を閉じるようです。
[264] nginx は標準状態では60s何も受信しないと、タイムアウトとするようです >>263。
[154] 応答の受信後に次の要求を送信するため保持した状態の接続について、
Chrome は約300s、 Firefox は115s >>159 未使用なら、閉じるようです。
IE は60s未使用なら、 RST
するようです >>141。
[155] IE は、要求の送信があった後 3600s サーバーから送信がなければ、
RST
するようです。 (どこから起算しているかは未調査。最後の受信?)
[156] Firefox は TCP keep alive (>>153) が無効に設定されている時は、 300s 間サーバーから送信がなければ、タイムアウトとして接続を閉じます >>142。
[160] Chrome や、Firefox で TCP keep alive が有効な場合 (既定の状態) では、要求が送信された後応答を受信するまで (応答の一部を受信しようがしまいが) タイムアウトは無いように見えます。 (少なくても20時間以上は切断されません。)
[195] クライアントライブラリーによっては、 要求の開始や応答の受信開始からの経過時間でタイムアウトを決めるものもあります。 しかし応答完了まで (正常時でも) 非常に時間がかかるサーバーもありますから、 相当に大きな値とする必要があります。それでは逆に異常時にタイムアウトエラーとなるまでかなり時間がかかってしまいますから、 あまりよい実装戦略ではなさそうです。
[196] サーバーによっては、無限に長い応答を送ることがあります。 従って対話的でないクライアントは、正常な受信中であっても、 一定時間経過後に受信を打ち切るようにする必要がありそうです。
[321] もちろん、恒久的に接続を維持してデータを受信し続けたいこともあります。 そのような用途を想定したいクライアントは、 受信を打ち切るべきタイムアウトを∞にも設定可能とする必要があります。
[260] 持続的接続等で現時点で未使用の接続を後で利用する(可能性がある)ため保持している場合で、 実装全体での、あるいは特定サーバー宛ての接続数上限に達した場合、 その未使用接続を閉じて接続枠を開ける必要があるかもしれません。
[541] 実装は、接続が閉じられた時に回復しないといけないかもしれないことを想定しておくべきです >>539。
[542] クライアントは、内向きの接続が意図せず閉じられたとき、 中断された要求群がすべて冪等なメソッドだった場合には、 新しい接続を開いてその要求を自動的に再転送して構いません。 >>539
[544] 利用者エージェントは、何らかの手段で要求が本当は冪等であると分かっている場合や元の要求が適用されなかったと分かっている場合を除き、 冪等でないメソッドの要求を自動的に再試行してはなりません。 >>539
[545] クライアントは、失敗した自動再試行を自動的に再試行するべきではありません >>539。
[543] 串は、冪等でない要求を自動的に再試行してはなりません >>539。
Expect: 100-continue
についても、
自動的な再試行に関する規定があります。[75] HTTP/2 の TCP接続が閉じられたり RST されたりした時に open や half-closed の状態だったストリームは、 自動的に再試行することはできません >>73。
[83] HTTP/2 では、次の場合、クライアントは要求が処理されていないことが保証されます >>82。
[86] これらの処理されていない要求は、失敗ではなく、 クライアントは冪等か否かに関わらず自動的に再試行して構いません >>82。
[107] 421
応答を受信したクライアントは、
冪等か否かに関わらず自動的に再試行して構いません >>90。
代替サービスから受信した場合は、当該代替サービス情報は削除しなければならず、
他の代替サービスや起源サーバーに再試行して構いません。
421
参照。[138] Chrome も Firefox も IE も、 (GET
でも
POST
でも) 持続的接続の2つ目の要求に対して応答を受信せず接続が切断された場合、
他の接続で改めて要求を送信するようです。
[322] クライアントから見てTCP接続が有効のままであっても、 実はHTTPサーバーとの接続状態は失われているケースがままあるため、 このような挙動にしなければならないようです。
[79] 誤り符号 HTTP_1_1_REQUIRED
(0xd
)
は、 HTTP/2 ではなく HTTP/1.1 が必要であることを示します >>76。
[179] その詳細な処理方法はどこでも規定されていません。いつこれを送れるのかも明確ではありません。
[183] HTTP/2 では再折衝が禁止されているため、クライアント認証が必要な時は
HTTP_1_1_REQUIRED
を送信するべきだとされています。
[174] Chrome も Firefox も、 HEADERS
より前に
RST_STREAM
や GOAWAY
で HTTP_1_1_REQUIRED
を受信すると、 HTTP/1.1 で接続し直すようです。
[176] Chrome は HEADERS
より後だと、 (RST_STREAM
であっても)
接続を閉じて、ネットワークエラーとするようです。
[177] Firefox は HEADERS
より後だと、
ネットワークエラーとするようです。
[178] Chrome も Firefox も、再接続時には ALPN で http/1.1
だけを指定します。
[180] (にも関わらず) サーバーが ALPN で h2
を指定すると、
Chrome も Firefox も HTTP/2 を使います。更に HTTP_1_1_REQUIRED
を返すと、 Firefox は何度か試して諦めますが、 Chrome は無限に(?)試し続けます。
[201] 理論上は Upgrade: h2c
によって HTTP/1 から
HTTP/2 への切り替えを指示できます (が実装されていません)。
[200] Chrome は、 Alt-Svc:
ヘッダーによって
QUIC が利用可能なことを認識できます。
Alt-Svc:
参照。[521] Connection:
ヘッダーは、接続の取り扱いを指定するものです。
[21] Expect: 100-continue
はデータの送信のタイミングについて指示するものです。
100-continue
参照。[516] HTTP のメッセージは下位の (トランスポート層やセッション層の) プロトコルに依存しておらず、信頼できる輸送路であって、 要求の順序を保存した配送と応答の順序を保存した配送のみを要求しています >>515。
[2] 実際には HTTP は、下位層プロトコルとして、
[519] HTTP の要求や応答の構造と下位層プロトコルのデータ単位との対応関係は、 HTTP の仕様書の適用範囲外とされています >>515。
[59] HTTP/2 では HTTP/1.1 よりは詳しく規定があります (が完全ではありません)。
[192] HTTP over TCP は、 HTTP が開発された平成時代初期以来、 平成時代後期頃まで標準の接続方法でした。 現在は安全ではないと考えられているため、徐々に HTTPS に置き換えられてきています。
[193] HTTP over TCP を HTTPS と区別するため、 素のHTTPと呼ぶことがあります。
[41] HTTP over TCP は、 http:
URL によって表されます。
[323]
素のHTTPは安全ではないので、使うべきではありません。
http:
から https:
にリダイレクトするのが普通です。[34] 通常は HTTP over TCP と HTTP over TLS over TCP は別のポートを使いますが、両方を同じポートで受け付けられないこともありません (両者は区別可能です)。
[163] Apache や nginx は、 HTTPS のポートに平文の HTTP要求のようなものが書き込まれると、
400
応答を返して切断するようです。
[17] three-way handshake を経て TCP 接続が確立された後に TCP によって伝送されるオクテット列が HTTP接続のオクテット列です。 なお TCP セグメントの境界は HTTP接続に反映されません。 TCP セグメントの境界と HTTP接続上のメッセージ境界と一致しているとは限りません。
[33] TCP PSH
フラグの取り扱いについて HTTP 特有の規定は特に無いと思われます。
(例えばHTTPメッセージの最後で PSH
フラグを立てなければならないというようなことは特にありません。)
[16] TCP 緊急データと HTTP の関係は明文化されていません。
[125] 応答の受信中に緊急データが含まれていた場合、次のように動作するようです
(いずれも Windows)。
[18] HTTP接続を閉じる、あるいは閉じられるとは、 TCP 接続を閉じる、あるいは閉じられることを意味します。
HTTP接続を閉じると FIN
セグメントが送信されることになります。
FIN
セグメントを受信すると HTTP接続が相手に閉じられたことを表します。
その他に RST
やタイムアウトなど TCP プロトコル上の規定や実装によって正常でない形で接続が閉じられることもあります。
[72] 応答の受信中に RST
を受信した場合、次のように動作するようです
(いずれも Windows)。
[152] Chrome と Firefox は SO_NODELAY
を真に設定
(Nagleアルゴリズムを無効化) するようです。
[186] HTTPクライアントライブラリー等で Nagleアルゴリズムを無効化しないものも少なくありません。
そのためにTCP/IPスタック内で送信待ちが発生して、応答の受信までに無駄な遅延が生じることがあります。
(気が付きにくいです。) プロトコルの仕様と用法から、 HTTP で
Nagleアルゴリズムは不要です。 (WebSocket なら利用方法によっては有効に働くかもしれませんが、一概にはいえないのでアプリケーションやWebブラウザー側で適当に扱うべきでしょう。)
[275] Nagleアルゴリズムを無効にしないのは、Web互換では無いようです >>270。
[153] Chrome と Firefox は SO_KEEPALIVE
(TCP keep alive)
を使うようです。 Chrome は最初の keep alive 送信まで (TCP_KEEPIDLE
) 45s、
二度目以降の送信まで (TCP_KEEPINTVL
) 45s とします
(TCP_KEEPCNT
は未設定で OS の既定値) >>145。
Firefox はより細かく調整します >>143。
[173] Firefox は HTTP/2 の時 TCP keepalive を無効にし、かわりに
90s ほどの間を置いて HTTP/2 PING
を送ります。返答がなければ
INTERNAL_ERROR
の GOAWAY
を送信して接続を閉じます。一方 Chrome は PING
を送っておらず、 HTTP/1 同様に TCP keepalive を使っているようです。
[189] 80
が HTTP / http:
URL scheme
の既定のポート番号です。ほとんどの HTTP over TCP
サーバーは、 80
番を使っています。
[273] 1990年代には既定のポート以外の Webサーバーもたまに見かけましたが、 次第に既定のポート以外あまり使わなくなりました。
[274] 現在でも、
など、 一般的な利用者に直接見えない形では既定のポート以外が使われる場面があります。
[191] 素のHTTPでは、 8000 や 8080 がしばしば使われます。
[190] HTTP としては任意のポートを利用可能ですが、
Webブラウザーはプロトコル交差攻撃防止のため接続可能なポートを制限しています。
Webブラウザー以外のクライアントの実装は制限していないこともありますが、
サーバーは特別理由がなければ制限されたポートを避けるのが無難です。
[331] 最初のWebブラウザーである WorldWideWeb は、 の 80 の割当以後、 80 で接続を試みて失敗したら 2784 で再試行する挙動でした。 >>330
[14] SSL や TLS でも HTTP は利用されます。
[42] HTTP over TLS over TCP は、 https:
URL
によって表されます。
[282] Opportunistic Security for HTTP/2 に対応している場合、
本来 HTTP over TCP を使う http:
URL
へのアクセスも、 HTTP over TLS を使います。
[271] HTTP over TLS over TCP では、 443 が既定のポート番号です。
[272] 素のHTTPの場合 (>>274) 同様HTTPSも既定以外のポートが使われるケースはあるものの、 やはり一般的ではありません。
[15] (同じ Unix 環境上で動作する) 逆串からアプリケーション鯖への通信などに Unixドメインソケットを使う場合があります。
[30] 鯖が予めソケットを作成しておき、クライアントがこれに接続することで、 当該ソケットを使った読み書きが HTTP接続となります。ソケットによる接続を閉じる、 または閉じられると、 HTTP接続が閉じる、あるいは閉じられることとなります。
[276] Unixドメインソケットを使った HTTP のアクセスを表す URL
はありません。主用途がアプリケーションサーバーへの接続なので、
相互運用性に関わるものでなく標準化の機運が高まらないようです。
実装依存の非標準の URL を用いるものもあれば、
コマンドラインオプションなど URL 以外の指定方法を提供するものもあります。
[277] 要求に Host:
ヘッダーが無い場合、
要求に含まれる情報だけから実効要求URLを確定できません。
Host:
ヘッダーが無い場合をエラーとして扱うか、
サーバーの設定によって自身の既定のホストとポートを決めておく必要があります。
[29] 次のような実装例があります。
CONNECT
[129] HTTP CONNECT
メソッドは任意の TCP
アプリケーションのトンネリングに使うことができますので、
HTTP の下位層としても使うことができます。
[130] しかし通常は HTTPS のトンネリングに使うので、直接
CONNECT
トンネル内が HTTP となることはありません。
[22] SOCKS proxy (SOCKS プロトコルによる TCP/IP トンネル) を介して HTTP クライアントから HTTP 鯖に接続することがあります。
[25] 多くのWebブラウザーその他の HTTP クライアントが、串の一種として SOCKS に対応しています。また socksify や tsocks のようなソフトウェアによって通常の TCP/IP 接続が SOCKS の接続に置き換えられることもあります。
[23] 他の TCP アプリケーションと同様に、SOCKS 鯖が接続するべき IPアドレスまたはホスト名と TCP ポートを指定して接続を確立します。 以後 SOCKS プロトコル上の送受信データが HTTP接続となります。 SOCKS の接続が閉じる、あるいは閉じられると、 HTTP接続が閉じる、 あるいは閉じられることとなります。
[32] SOCKS の下位層の TCP/IP ネットワークエラーその他の原因で SOCKS 接続が異常に閉じられることがあります。
[308] OS のネットワーク機能の一部として、 captive portal を表示してログインするために Webブラウザーの機能 (組み込みブラウザー) が使われる場合があります。
[309] そうした用途に使われる組み込みブラウザーは、 通常のプロキシ設定や他のネットワークインターフェイス経由で利用可能なネットワーク接続を無視し、 ログインしようとしているネットワークインターフェイスを通じて captive portal に (HTTP over TCP または HTTPS over TCP で) 接続できる必要があります。
[563] 接続そのものではありませんが、接続上の要求の列または応答の列を表す
MIME型 application/http
があります。
application/http
参照。[31] HTTP接続自体を表す URL scheme はありません。
HTTP接続を使った資源へのアクセスを表す URL
は、 http:
, https:
を参照。
- connection
- A transport layer virtual circuit established between two
{1945} applicationprograms for the purpose of communication.
[337] HTTP Persistent Connections Minutes, , https://web.archive.org/web/19961104033339/http://ugly.resnova.com/persistminutes.html
[338] Wayback Machine, https://web.archive.org/web/19961104033225/http://ugly.resnova.com/draft-ietf-http-ses-ext-01.txt
[339] Wayback Machine, https://web.archive.org/web/19961104033215/http://ugly.resnova.com/draft-ietf-http-ses-ext-00.txt
[575] Re: Fetch: HTTP authentication and CORS ( (Jonas Sicking 著, 版)) http://lists.w3.org/Archives/Public/public-webapps/2013AprJun/0502.html
[581] RFC 6202 - Known Issues and Best Practices for the Use of Long Polling and Streaming in Bidirectional HTTP ( ( 版)) http://tools.ietf.org/html/rfc6202#section-5.1
[582] draft-mogul-http-ooo-00 - Support for out-of-order responses in HTTP ( ( 版)) https://tools.ietf.org/html/draft-mogul-http-ooo-00
[13] draft-zhu-http-fullduplex-08 - Implications of Full-Duplex HTTP ( 版) https://tools.ietf.org/html/draft-zhu-http-fullduplex-08
[39] Part2 - browsersec - Browser Security Handbook, part 2 - Browser Security Handbook - Google Project Hosting ( 版) https://code.google.com/p/browsersec/wiki/Part2#Simultaneous_connection_limits
After the connection is idle for one minute, Internet Explorer resets the connection.
[140] 205140 – Prefs: remove "network.http.*.timeout" ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=205140
Internet Explorer imposes a time-out limit for the server to return data. By default, the time-out limit is as follows:
Internet Explorer 4.0 and Internet Explorer 4.01 5 minutes
Internet Explorer 5.x and Internet Explorer 6.x 60 minutes
Internet Explorer 7 and Internet Explorer 8 60 minutes
[142] 1024015 – network.http.response.timeout breaks applications with long lived http connetions ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=1024015
[143] 444328 – TCP-level keep alive timer ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=444328
Opera 11.11 – 120 seconds
Chrome 13 – at least 300 seconds (server closed after 300 second timeout)
IE 9 – 60 seconds (changeable in the registry, appears to apply to IE 8/9 as well though the page only mentions IE 5/6/7)
Firefox 4 – 115 seconds (changeable in about:config with network.http.keep-alive.timeout preference)
Interestingly one of the other things I noticed while doing this test with Wireshark is that after 45 seconds, Chrome would send a TCP keep-alive packet, and would keep doing that every 45 seconds until the 5 minute timeout. No other browser would do this.
[145] Issue 27400 - chromium - Long lived connections are being dropped by some network setups - An open-source project to help move the web forward. - Google Project Hosting ( 版) https://code.google.com/p/chromium/issues/detail?id=27400
[146] 947391 – HTTP connections (exc. XHR, SPDY) should have a response timeout ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=947391
[147] 1005808 – New response timeout is affecting request requiring significant processing time ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=1005808
[148] Bug 102079 – Disable Nagle algorithm on WebSocket implementation ( 版) https://bugs.webkit.org/show_bug.cgi?id=102079
[149] WebSocket Nagle アルゴリズム問題 ( 版) https://gist.github.com/uupaa/6281381
Windows 7 delays acks very aggressively for up to 200ms. If the server is using the Nagle algorithm, it won't send new messages until the acks arrive (or the send buffer fills).
Any decent WebSocket server should have Nagle disabled, which is why we haven't seen this until now.
Fortunately (?) pywebsocket in standalone mode does not disable the Nagle algorithm, and so I was able to reproduce quite easily. I then used Wireshark to confirm that the issue was happening at the TCP/IP level.
The best fix is to disable Nagle on the server. This will avoid other, more subtle, problems that the Nagle algorithm can cause.
[151] 542401 – set TCP_NODELAY for all SocketTransport sockets (not just SSL) ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=542401
手元の次環境で、SleepするだけのCGIにリクエストした所、ともに受信タイムアウトは60分ちょうどでした。
Win8 & IE10
Win7 & IE9
HTTPレスポンス受信に無通信のまま60分経つと、IE側から切断していました。(最初の受信データかによらず)
レジストリにタイムアウト値(ReceiveTimeout)は設定していません。
# 「切断する」とは、FINパケットを先にどちらが送出したかで確認を行いました。
上記リンク先のIE9が5分後にリクエストをリトライする事象は、
最初、私もこれに引っかかってしまいましたが、
サーバにApache2.2をデフォルト設定のままで使用していると発生すると思います。
CGIがいつまでも応答がない場合に、Apacheがコネクションを切断してしまうためでした。(Timeoutの第3項も参照)
このときIE側からは、すぐに別コネクションで接続が行われ、同一のリクエストを送信していました。
(よーするに、1TCPコネクション内の再送ではなく、アプリレベルの再送)
設定変更すると5分以上経ってもIEは受信し続けてくれました。
In the first, a thoughtful web developer or operations team reasons: “Hey, HTTPS connections are expensive to maintain on the server. Let’s be sure to tear those down as soon as possible to free up the server to accept new connections.” That, of course, completely misses the point that if the server wasn’t tearing down the connections, the server would be under significantly lighter load to begin with! Sites that were deliberately written with this bad pattern load slowly in all browsers.
We also found another root cause—ancient advice for the configuration of Apache+OpenSSL. Prior to IE6, ancient and unpatched versions of IE sometimes encountered connection failures when interacting with HTTPS servers when Keep-Alive is used. That problem was fixed nearly a decade ago, but outdated 1999-era configuration advice continues to harm performance for unaware server administrators:
[159] Network.http.keep-alive.timeout - MozillaZine Knowledge Base ( 版) http://kb.mozillazine.org/Network.http.keep-alive.timeout
[166] javascript - Max parallel http connections in a browser? - Stack Overflow ( 版) http://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser/985704
// Disable TCP Keepalives - use SPDY ping instead.
rv = DisableTCPKeepalives();
[181] 1091263 – [http/2] HTTP_1_1_REQUIRED error code ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=1091263
[182] Issue 431306 - chromium - Implement HTTP/2 error code HTTP_1_1_REQUIRED. - An open-source project to help move the web forward. - Google Project Hosting ( 版) https://code.google.com/p/chromium/issues/detail?id=431306
- do not recurse on POST requests, as per HTTP/1.[01] (this might
change as the recommendation isn't followed by anybody else).
[188] Support full-duplex HTTP streaming · Issue #229 · whatwg/fetch ( 版) https://github.com/whatwg/fetch/issues/229
[194] Allow for a request to finish after a response starts to arrive · whatwg/fetch@3a41b6f ( 版) https://github.com/whatwg/fetch/commit/3a41b6f04996d4aac13ecad5b38635827dcd0df3
[220] 1190136 – Firefox should decide whether reuse connection separately for IPv4 and IPv6 ( ()) https://bugzilla.mozilla.org/show_bug.cgi?id=1190136
--http2-prior-knowledge
(HTTP) Tells curl to issue its non-TLS HTTP requests using HTTP/2 without HTTP/1.1 Upgrade. It requires prior knowledge that the server supports HTTP/2 straight away. HTTPS requests will still do HTTP/2 the standard way with negotiated protocol version in the TLS handshake.
--keepalive-time <seconds>
This option sets the time a connection needs to remain idle before sending keepalive probes and the time between individual keepalive probes. It is currently effective on operating systems offering the TCP_KEEPIDLE and TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This option has no effect if --no-keepalive is used. (Added in 7.18.0)
--unix-socket <path>
(HTTP) Connect through this Unix domain socket, instead of using the network. (Added in 7.40.0)
[242] Issue 170165 - chromium - Websocket handshake delay when server is unavailable - Monorail ( ()) https://bugs.chromium.org/p/chromium/issues/detail?id=170165
IE8: The Performance Implications
March 7, 2008 on 1:25 am | In ajax | No Comments
Mix08 is here, and with it the first beta of IE8. John has a great roundup of the JS/Dom work, noting that “Internet Explorer 8 is our release.” He’s right.
I’ll run through a few of the items that have particular implications for performance.
This one is the most exciting for me: the IE team has finally upped the connection limit to 6 per host from the default of 2. I’ve talked before about DNS tricks to get around the 2 connection limitation, but having this support out of the box will be a great assistance in the war on round-trip latency as it’s easier to make more expensive network calls in parallel. This is especially sweet for Comet and the like where the persistent connection could previously monopolize half of the connections to your site. As you would expect, Joe Walker of DWR is happy.
One thing I haven’t seen mentioned anywhere is the total connection limit. Previous versions supported 2 per host and 6 total. Is the new version 6 per host / 6 total or 6 per host / 18 total. I really doubt it on the latter, but if no one has the answer I’ll grab the beta this weekend and test it out.
[261] Retrying HTTP Requests ( ()) https://mnot.github.io/I-D/httpbis-retry/
Firefox 46 has changed the way to handle broken connections so that it will no longer automatically retry unsafe requests such as POST. However, various Web sites do not work with the new behaviour, resulting in an error page “connection to the server was reset”, because they expect the browser to retry connections even for POST requests. KanColle, a popular Japanese Flash game is known to be affected.
[267] nginx ちょっと不思議だったリクエストリトライのお話 - Cybozu Inside Out | サイボウズエンジニアのブログ () http://blog.cybozu.io/entry/2016/05/09/080000
tcpNoDelay
If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances. This is set to true by default.
socket.tcpNoDelay
(bool)same as the standard setting tcpNoDelay. Default value is false
socket.soKeepAlive
(bool)Boolean value for the socket's keep alive setting (SO_KEEPALIVE). Default is false.
socket.ooBInline
(bool)Boolean value for the socket OOBINLINE setting. Default value is true
socket.soReuseAddress
(bool)Boolean value for the sockets reuse address option (SO_REUSEADDR). Default value is true
socket.soLingerOn
(bool)Boolean value for the sockets so linger option (SO_LINGER). Default value is true. This option is paired with the soLingerTime value.
socket.soLingerTime
(bool)Value in seconds for the sockets so linger option (SO_LINGER). Default value is 25 seconds. This option is paired with the soLinger value.
socket.soTimeout
(int)Value in milliseconds for the sockets read timeout (SO_TIMEOUT). Default value is 5000 milliseconds.
socket.soTrafficClass
(byte)Value between 0 and 255 for the traffic class on the socket, 0x04 | 0x08 | 0x010
Receivers should place limits on the amount of data and time they spend fetching unverified source URLs. For example, if a source URL doesn't respond within 5 seconds, it can treat that as a failure. Similarly, the receiver can fetch only the first 1mb of the page, since any reasonable HTML or JSON page will be smaller than that.
[279] HTTP/1.1 and Nagle's Algorithm () https://www.w3.org/Protocols/HTTP/Performance/Nagle/
[280] draft-pardue-quic-http-mcast-00 - Hypertext Transfer Protocol (HTTP) over multicast QUIC () https://tools.ietf.org/html/draft-pardue-quic-http-mcast-00
// For backup connections, we disable IPv6. That's because some users have
// broken IPv6 connectivity (leading to very long timeouts), and disabling
// IPv6 on the backup connection gives them a much better user experience
// with dual-stack hosts, though they still pay the 250ms delay for each new
// connection. This strategy is also known as "happy eyeballs".
[286] Service Name and Transport Protocol Port Number Registry () https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?&page=2
[287] Clarify rules around half-closed TCP connections · Issue #22 · httpwg/http11bis () https://github.com/httpwg/http11bis/issues/22
[288] Abortable fetch (jakearchibald著, ) https://github.com/whatwg/fetch/commit/0bcd5dfc71ef44319873887f4b83119bd6d0b71d
[293] Warp should respond with HTTP_1_1_REQUIRED for connection takeovers. · Issue #417 · yesodweb/wai () https://github.com/yesodweb/wai/issues/417
[294] 516237 - Chrom{e,ium} refuses to talk HTTP/2 to a server once it's seen HTTP_1_1_REQUIRED for any resource. - chromium - Monorail () https://bugs.chromium.org/p/chromium/issues/detail?id=516237
[295] 685741 - ERR_UNEXPECTED Displays briefly before page loads - chromium - Monorail () https://bugs.chromium.org/p/chromium/issues/detail?id=685741
[296] 1091263 - [http/2] HTTP_1_1_REQUIRED error code () https://bugzilla.mozilla.org/show_bug.cgi?id=1091263
[297] [WFLY-7662] CLIENT-CERT authentication doesn't work - JBoss Issue Tracker () https://issues.jboss.org/browse/WFLY-7662?_sscc=t
[298] errors: change timeout errors from 408 to 500 HTTP status code (andreastt著, ) https://github.com/w3c/webdriver/commit/c377c21186f672105a05383d5152e0a3b2a00374
[299] HTTP status code 408 causes clients to retry · Issue #1287 · w3c/webdriver () https://github.com/w3c/webdriver/issues/1287
[300] errors: change timeout errors from 408 to 500 HTTP status code by andreastt · Pull Request #1292 · w3c/webdriver () https://github.com/w3c/webdriver/pull/1292
[301] Microsoft Edge でローカルホストにアクセスできない問題を解決する - Browser () http://browser.hatenablog.com/entry/2016/01/29/190856
[302] Microsoft Edgeでローカルの仮想マシン上に構築したWebサイト(Webアプリケーション)にアクセスできない - YoshinoriN's Memento (YoshinoriN著, ) https://yoshinorin.net/2016/07/03/vagrant-edge/
[303] dns - Why does Microsoft Edge open some local websites, but not others, where the domain name is routed to 127.0.0.1 in hosts file - Stack Overflow () https://stackoverflow.com/questions/32384571/why-does-microsoft-edge-open-some-local-websites-but-not-others-where-the-doma/37848210
[304] #15565 (Host adapter showing zero bytes traffic) – Oracle VM VirtualBox () https://www.virtualbox.org/ticket/15565
[305] Tracking Compliance and Scope () https://www.w3.org/TR/tracking-compliance/#dfn-network-interaction
[306] Tracking Compliance and Scope () https://www.w3.org/TR/2019/NOTE-tracking-compliance-20190122/#dfn-network-interaction
[307] Tracking Preference Expression (DNT) () https://www.w3.org/TR/2019/NOTE-tracking-dnt-20190117/#dfn-network-interaction
[314] curl - How To Use (, ) https://curl.haxx.se/docs/manpage.html#--connect-timeout
[315] curl - How To Use (, ) https://curl.haxx.se/docs/manpage.html#--connect-to
[316] curl - How To Use (, ) https://curl.haxx.se/docs/manpage.html#--http2-prior-knowledge
[317] GNU Wget 1.20 Manual () https://www.gnu.org/software/wget/manual/wget.html#index-timeout
[318] GNU Wget 1.20 Manual () https://www.gnu.org/software/wget/manual/wget.html#index-Persistent-Connections_002c-disabling
[319] Command-Line Interface — Streamlink 1.6.0 documentation (, ) https://streamlink.github.io/cli.html#cmdoption-http-timeout
[320] Disabled HTTP/1.0 requests with Transfer-Encoding. (Sergey Kandaurov, , ) https://github.com/nginx/nginx/commit/7bcb50c0610a18bf43bef0062b2d2dc550823b53