優れたソフトウェアと実用的なチュートリアル
httpのさまざまなバージョンの違いについて詳しくは
httpプロトコルとは何ですか?なぜhttp1.x、http2.0、http3.0これら3つの違いは何でしょうか?以下では、httpプロトコルの各バージョンの違いについて詳しく紹介します。これにより、httpプロトコルをより深く理解できるようになります。
HTTPとは何ですか?
ハイパーテキスト転送プロトコルハイパーテキスト転送プロトコル(HTTP)は、インターネットで最も広く使用されているネットワークプロトコルです。HTTPは、HTMLページの公開と受信のための手段を提供することを当初の目的としていました。HTTPまたはHTTPSプロトコルを介して要求されるリソースは、Uniform Resource Identifier(URI)によって識別されます。
HTTPは、リクエストとレスポンスで構成されるアプリケーション層プロトコルであり、標準的なクライアントサーバーモデルです。HTTPはTCP/IPをベースとしたコネクションレスかつステートレスなプロトコルです(各HTTPメッセージは前のメッセージの状態に依存しません)。HTTPは、下位層プロトコルが信頼性の高い伝送を提供することを前提としています。そのため、TCP/IPプロトコルスイートのトランスポート層としてTCPを使用しています。
HTTP プロトコルの主な機能は次のようにまとめられます。
- シンプル:クライアントがサーバーにサービスを要求する際は、リクエストメソッドとパスを送信するだけで済みます。一般的なリクエストメソッドはGET、HEAD、POSTです。各メソッドは、クライアントとサーバー間の通信の種類をそれぞれ指定します。
- 柔軟性:HTTPはあらゆる種類のデータオブジェクトの送信を可能にします。送信されるデータオブジェクトの種類はContent-Typeによって示されます。
- 要求応答モード: クライアントがサーバーに要求するたびに接続が確立され、サーバーはクライアントの要求を処理した後に切断されます。
- ステートレス:HTTPはステートレスなプロトコルです。ステートレスとは、プロトコルがトランザクション処理のためのメモリを持たないことを意味します。ステートが存在しないということは、後続の処理で以前の情報が必要になった場合、それを再送信する必要があることを意味します。
HTTP作業プロセス
HTTPはリクエストとレスポンスで構成され、標準的なクライアントサーバーモデル(B/S)です。HTTPプロトコルは常に、クライアントがリクエストを送信し、サーバーがレスポンスを返すことから始まります。
1. クライアント (ブラウザ) がサーバー (Web サーバー) に積極的に接続要求を送信します (この手順では、サーバーの IP アドレスを取得するために DNS 解決プロトコルが必要になる場合があります)。
2. サーバーは接続要求を受け入れ、接続を確立します。(ステップ1と2は、私たちがよく知っているTCPの3ウェイハンドシェイクです)
3. クライアントはこの接続を介して GET などの HTTP コマンドをサーバーに送信します (「HTTP 要求メッセージ」)。
4. サーバーはコマンドを受信し、コマンドに従って対応するデータをクライアントに送信します(「HTTP 応答メッセージ」)。
5. クライアントはサーバーから送信されたデータを受信します。
6. データ送信後、サーバーは積極的に接続を閉じます (「TCP 4 方向の分割」)。
要約すると、クライアント/サーバー転送プロセスは次の 4 つの基本的なステップに分けられます。
1) ブラウザがサーバーとの接続を確立する(TCP 3ウェイハンドシェイク)
2) ブラウザは HTTP リクエスト メッセージをサーバーに送信します。
3) サーバーはブラウザの要求に応答します。
4) 切断します。(「TCP 4 方向の分割」)
HTTP1.Xの原則
http1.0の動作プロセスでは、データのhttp送信には3回のハンドシェイクと4回のウェーブが必要となり、遅延が増加します。
TCP接続を維持し、遅延を減らすために、http1.1にキープアライブが追加されました。
HTTP 1.x の問題
- 接続は再利用できません。接続は再利用できないため、各リクエストは3ウェイハンドシェイクとスロースタートを経由します。3ウェイハンドシェイクはレイテンシの高いシナリオでより顕著な影響を与え、スロースタートは小さなファイルリクエストを多数送信する場合により大きな影響を与えます。
- ヘッドオブライン ブロッキング (HOLB) により、帯域幅が十分に利用されず、後続のヘルス要求がブロックされます。ホルブこれは、最初のパッケージがブロックされたために一連のパッケージがブロックされることを意味します。ページが多くのリソースをリクエストする必要がある場合、HOLB(ヘッドオブラインブロッキング)により、リクエスト数が最大数に達した時点で、残りのリソースは他のリソースリクエストが完了するまで待機し、その後リクエストを開始します。ヘッドオブラインブロッキングに対して、次のような解決策が試みられています。
- HTTP 1.0: 前のリクエストが返された後に次のリクエストを送信する必要があります。
リクエストレスポンス
当然ですが、リクエストが長時間返されない場合、後続のリクエストはすべてブロックされます。 - HTTP 1.1:パイプライン化によって問題を解決してみてください。つまり、ブラウザは複数のリクエスト(同じドメイン名、同じTCPリンク)を同時に送信できます。ただし、パイプライン化では、レスポンスが順番に返される必要があります。前のリクエストに時間がかかる場合(大きな画像の処理など)、サーバーが後続のリクエストを既に処理していても、前のリクエストが処理されるまで待って順番にレスポンスを返します。したがって、パイプライン化ではHOLBの問題は部分的にしか解決されません。
- スプライト画像、インラインの小さな画像などをインポートします。
- リクエストヘッダーには大きなオーバーヘッドがあります。メッセージヘッダーには通常、「User Agent」、「Cookie」、「Accept」、「Server」(下図参照)といった、数百バイト、場合によっては数千バイトにも及ぶ固定ヘッダーフィールドが多数含まれますが、ボディは数十バイト程度にとどまる場合が多くあります。ヘッダーのコンテンツが大きいと、ある程度の転送コストが増加します。
- セキュリティ要因 HTTP 1.x では、データを送信する際、送信されるコンテンツはすべて平文で送信されます。クライアントもサーバーも相手側の身元を確認できないため、データのセキュリティをある程度保証することはできません。
- HTTP/1.xにはプッシュメカニズムがないため、サーバープッシュメッセージはサポートされていません。そのため、通常は2つの方法があります。1つはクライアントが定期的にポーリングするポーリング、もう1つはWebSocketです。
2.0 仕組み
2015年にHTTP/2がリリースされました。HTTP/2は現在のHTTPプロトコル(HTTP/1.x)の代替ですが、書き換えられたものではありません。HTTPメソッド、ステータスコード、セマンティクスはHTTP/1.xと同じです。HTTP/2はSPDYをベースにしており、パフォーマンスに重点を置いています。最大の目標の一つは、ユーザーとウェブサイト間の接続を1つだけに限定することです。。
HTTP2が解決する問題
http1.x に存在する問題に対して、http2 には次の解決策があります。
- バイナリ伝送 HTTP/2は、HTTP 1.xのテキスト形式ではなく、バイナリ形式でデータを伝送します。バイナリプロトコルは解析効率に優れています。HTTP/1のリクエストメッセージとレスポンスメッセージは、開始行、ヘッダー、エンティティボディ(オプション)で構成され、各部分はテキスト改行で区切られます。HTTP/2は、リクエストデータとレスポンスデータを小さなフレームに分割し、バイナリ形式でエンコードします。
HTTP/2 を理解する前に、いくつかの一般的な用語を知っておく必要があります。
- ストリーム: 双方向ストリーム。接続には複数のストリームを設定できます。
- メッセージ: 論理的な要求と応答です。
- フレーム: データ転送の最小単位。各フレームは特定のストリームまたは接続全体に属します。メッセージは複数のフレームで構成される場合があります。フレームはHTTP/2におけるデータ転送の最小単位です。フレームは以下のように定義されます。
長さ: フレームの長さ。デフォルトの最大長は16KBです。これより大きなフレームを送信する場合は、最大フレームサイズを明示的に設定する必要があります。
タイプ: DATA、HEADERS、PRIORITY などのフレーム タイプ。
フラグと R: 予約ビット。
ストリーム識別子:フレームが属するストリームを識別します。0の場合、このフレームは接続全体に属していることを意味します。
フレーム ペイロード: タイプに応じて異なる形式があります。
Stream には多くの重要な機能があります:
- 接続には複数のストリームを含めることができ、複数のストリームによって送信されたデータは互いに影響しません。
- ストリームは一方的に使用することも、クライアントとサーバーで共有することもできます。
- ストリームはどちらのセグメントでも閉じることができます。
- ストリームはフレームの送信順序を決定し、もう一方の端ではフレームを受信した順序で処理します。
- ストリームは一意のIDで識別されます。ストリームがクライアントによって作成された場合、IDは奇数、サーバーによって作成された場合、IDは偶数になります。
バイナリ伝送では、TCPプロトコルの一部の機能がアプリケーション層に移行し、元の「ヘッダー+ボディ」メッセージを複数の小さなバイナリ「フレーム」に分割します。「HEADERS」フレームにはヘッダーデータを、「DATA」フレームにはエンティティデータを格納します。HTP/2データがフレーム化された後、「ヘッダー+ボディ」メッセージ構造は完全に消滅し、プロトコルは「フラグメント」のみを認識します。
HTTP/2では、同一ドメイン名でのすべての通信が単一の接続で完了し、任意の数の双方向データストリームを伝送できます。各データストリームはメッセージの形式で送信され、メッセージは1つ以上のフレームで構成されます。複数のフレームは順序に関係なく送信され、フレームヘッダー内のストリーム識別子に基づいて再構成されます。
ヘッダー圧縮
HTTP/1では、ヘッダーがテキスト形式で送信されるため、ヘッダーにCookieやユーザーエージェントが含まれる場合、数百から数千バイトのデータを毎回繰り返し送信する必要がある場合があります。HTTP/2では、従来の圧縮アルゴリズムを使用せず、特別な「HPACK」アルゴリズムを開発し、クライアントとサーバーの両方に「辞書」を作成し、インデックス番号を使用して繰り返し文字列を表し、ハフマン符号化を使用して整数と文字列を圧縮することで、50%〜90%の高い圧縮率を実現できます。
詳細は以下の通りです。
- HTTP/2は、クライアントとサーバー上で「ヘッダーテーブル」を使用し、以前に送信されたキーと値のペアを追跡・保存します。これにより、リクエストとレスポンスごとに同じデータが送信されることはなくなります。
- ヘッダー テーブルは HTTP/2 接続中は常に存在し、クライアントとサーバーによって徐々に更新されます。
- 各新しいヘッダーのキーと値のペアは、現在のテーブルの末尾に追加されるか、テーブル内の前の値を置き換えます。
- 多重化(リクエストとレスポンスの多重化) 同じドメイン名は1つのTCP接続を占有するだけで済みます。1つのTCP接続で、相手側にフレームを連続的に送信できます。各フレームのストリーム識別子は、フレームがどのストリームに属しているかを示します。相手側がフレームを受信すると、各ストリームのすべてのフレームがストリーム識別子に基づいて結合され、完全なデータブロックが形成されます。
上記のプロトコル分析で言及したストリームIDは、コネクション共有メカニズムとして使用されます。1つのリクエストは1つのストリームに対応し、IDが割り当てられます。そのため、1つのコネクション上に複数のストリームが存在する可能性があり、各ストリームのフレームがランダムに混在する可能性があります。受信側は、ストリームIDに基づいてフレームを異なるリクエストに関連付けることができます。リクエストとレスポンスは互いに影響しません。
多重化(MultiPlexing)機能は、長距離接続の拡張に相当します。各リクエストはランダムに混合され、受信者はリクエストIDに基づいてリクエストを異なるサーバーリクエストに関連付けることができます。
多重化では、ストリームの優先順位 (ストリームの依存関係) がサポートされており、クライアントはどのコンテンツが優先度の高いリソースであり、最初に送信できるかをサーバーに伝えることができます。
- サーバープッシュ HTTP/2 によって追加されたもう一つの強力な新機能は、サーバーがクライアントのリクエストに対して複数のレスポンスを送信できることです。つまり、最初のリクエストへのレスポンスに加えて、サーバーはクライアントが明示的にリクエストしなくても、追加のリソースをクライアントにプッシュすることができます。
サーバーは能動的にプッシュすることができ、クライアントは受信するかどうかを選択する権利も持ちます。サーバーがプッシュしたリソースがブラウザにキャッシュされている場合、ブラウザはRST_STREAMフレームを送信することでそれを拒否できます。
アクティブプッシュは同一オリジンポリシーに準拠しています。サーバーはサードパーティのリソースをクライアントに任意にプッシュすることはできず、双方の確認が必要です。
- セキュリティ強化 HTTP/2はHTTP/1の「プレーンテキスト」機能を継承し、従来通りプレーンテキストでデータを送信できます。暗号化通信の使用を強制するものではありません。ただし、形式は依然としてバイナリであり、復号化は不要です。
HTTPSが一般的なトレンドであり、ChromeやFirefoxなどの主流ブラウザは暗号化されたHTTP/2のみをサポートすると公表しているため、「実際」HTTP/2は暗号化されています。つまり、インターネットで一般的に見られるHTTP/2は「https」というプロトコル名を使用し、TLS上で動作します。HTTP/2プロトコルでは、暗号化されたHTTP/2を表す「h2」と、プレーンテキストのHTTP/2を表す「h2c」という2つの文字列識別子が定義されています。
HTTP2の問題
- http1.x と http2 はどちらも TCP をベースにしています。TCP は安全で信頼性の高い伝送プロトコルですが、接続確立時の遅延は依然としてやや大きいです。これは主に、TCP と TCP+TLS 間の接続確立時の遅延に起因しています。
- TCPのヘッドオブライン輻輳問題は解決不可能です。HTTP2は多重化によってHTTP層のヘッドオブライン輻輳を解決しますが、TCPの失敗再送問題は依然として解決できません。
HTTP 3.0 の原則
TCP は古くから存在し、さまざまなデバイスで使用されており、このプロトコルはオペレーティング システムによって実装されているため、更新することは現実的ではありません。
このため、Google は UDP プロトコルをベースにした QUIC プロトコルを作成し、HTTP/3 で使用しました。HTTP/3は以前はHTTP-over-QUICと呼ばれていました。この名称からも、HTTP/3の最大の変革はQUICの採用にあることがわかります。QUIC(Quick UDP Internet Connections)はUDPをベースとしており、UDPの速度と効率性に基づいています。同時に、QUICはTCP、TLS、HTTP/2の利点を統合し、最適化しています。
QUICの二次的な目標には、接続および伝送遅延の削減、輻輳回避のための各方向の帯域幅推定の実行などがあります。また、輻輳制御アルゴリズムをカーネル空間ではなくユーザー空間に移行し、前方誤り訂正(FEC)機能を追加することで、エラー発生時のパフォーマンスをさらに向上させます。
HTTP3で実装された機能
- 高速ハンドシェイク機能を実現するには、HTTP/2接続に3RTTが必要です。セッション再利用、つまり最初のハンドシェイクで計算された対称鍵をキャッシュすることを考慮すると、2RTTも必要になります。さらに、TLSが1.3にアップグレードされると、HTTP/2接続には2RTT、セッション再利用には1RTTが必要になります。しかし、HTTP/3では最初の接続に1RTTのみが必要で、それ以降の接続では0RTTとなります。
QUICプロトコルを使用するクライアントとサーバーは1RTTを使用する必要があります鍵交換使用される交換アルゴリズムはDH(Diffie-Hellman)である。ディフィー・ヘルマンアルゴリズム。
初めて接続する場合クライアントとサーバー間の鍵ネゴシエーションとデータ転送プロセスDHアルゴリズムの基本的なプロセスが含まれます。
- まず、クライアントは初めて接続するサーバーにクライアント ハロー要求を送信します。
- サーバーは素数pと整数gを生成し、さらに乱数を秘密鍵aとして生成します。そして、公開鍵A = mod pを計算します。サーバーは3つの要素A、p、gをconfigにパッケージ化し、クライアントに送信します。
- クライアントは自身の秘密鍵bをランダムに生成し、設定ファイルからgとpを読み取り、クライアント公開鍵B = mod pを計算します。次に、クライアントはA、p、bに基づいて初期鍵Kを計算します。BとKが計算された後、クライアントはKを使用してHTTPデータを暗号化し、Bと共にサーバーに送信します。
- クライアントは自身の秘密鍵 b と、サーバーから送信された構成から読み取ったサーバーの公開鍵を使用して、後続のデータ暗号化用の鍵 K = mod p を生成します。
- クライアントはキー K を使用してビジネス データを暗号化し、独自の公開キーを追加してサーバーに渡します。
- サーバーは、自身の秘密鍵 a とクライアントの公開鍵 B に基づいて、クライアント暗号化鍵 K = mod p を生成します。
- データのセキュリティを確保するため、上記で生成された鍵Kは一度だけ使用されます。サーバーはその後、同じルールに従って新しい公開鍵と秘密鍵のセットを生成し、この公開鍵と秘密鍵のセットを用いて新しい鍵Mを生成します。
- サーバーは、新しい公開鍵と新しい鍵Mで暗号化したデータをクライアントに送信します。クライアントは、新しいサーバーの公開鍵と元の秘密鍵に基づいて鍵Mを計算し、それを復号します。
- クライアントとサーバー間のその後のすべてのデータやり取りはキー M を使用して完了し、キー K は 1 回だけ使用されます。
クライアントとサーバーが初めて接続すると、サーバーは設定パッケージサーバーの公開鍵と2つの乱数を含むクライアントは設定を保存します、後で再接続するときに直接使用できるため、1RTT をスキップして 0RTT のビジネス データのやり取りを実現できます。
クライアントは設定を一定期間保存しますが、設定の有効期限が切れた後も最初の接続時にキー交換が必要になります。
- 統合されたTLS暗号化機能
- 安全なフォワードフォワードセキュリティとは、たとえ鍵が漏洩したとしても、以前に暗号化されたデータは漏洩しないことを意味します。これは現在のデータにのみ影響し、以前のデータには影響を与えません。。
QUIC は構成の有効期間を使用して、その後新しいキーを生成します。このキーは暗号化と復号化に使用され、やり取りが完了すると破棄されるため、前方セキュリティが実現されます。
- 前方誤り訂正(FEC)は、前方誤り訂正符号とも呼ばれ、データ通信の信頼性を高める手法です。一方向通信チャネルでは、エラーが発見されると、受信者は送信を要求する権利を失います。
FEC は、データとともに冗長情報を送信する方法であり、送信中にエラーが発生した場合に受信側がデータを再構築できます。
QUICはデータのグループを送信するたびに、そのデータを処理する。XOR演算結果はFECパケットとして送信されます。このデータセットを受信した受信側は、データパケットとFECパケットに基づいて検証とエラー訂正を実行できます。1つのデータが10個のパケットに分割された後、各パケットは順番にXOR演算され、演算結果はデータパケットとともにFECパケットとして送信されます。送信中にデータパケットが失われた場合、残りの9個のパケットとFECパケットに基づいて失われたパケットのデータを推測できるため、プロトコルのフォールトトレランスが大幅に向上します。
- 安全なフォワードフォワードセキュリティとは、たとえ鍵が漏洩したとしても、以前に暗号化されたデータは漏洩しないことを意味します。これは現在のデータにのみ影響し、以前のデータには影響を与えません。。
- 多重化により、TCP HTTP2.0プロトコルのヘッドオブラインブロッキング問題を解決多重化メカニズムこれはHTTP層でのヘッドオブラインブロッキングの問題を解決しますが、TCP層には依然としてヘッドオブラインブロッキングの問題がある。。
TCP プロトコルがデータ パケットを受信した後、この部分のデータは順序どおりに到着しない場合がありますが、TCP は上位層で使用するためにすべてのデータを収集、分類、統合する必要があります。パケットの 1 つが失われた場合、再送信を待つ必要があり、その結果、接続全体のデータ使用がブロックされるパケット損失が発生します。。
QUIC プロトコルは UDP プロトコルに基づいて実装されています。複数のストリーム流れの間には相互影響なしフローでパケット損失が発生した場合、その影響は非常に小さいため、ヘッドオブライン ブロッキングの問題が解決されます。
- TCPのようなフロー制御を実装する(…この部分は長いので、参考文献を参照してください)