fzdwx

fzdwx

Hello , https://github.com/fzdwx

HTTPプロトコル

HTTP 1.1 以前の実装については触れません。なぜなら、すでに時代遅れで、私がインターネットを利用していた時には接触できなかったからです。主に HTTP/1.1 と HTTP/2 について説明します。

HTTP/1.1#

HTTP/1.1 プロトコルメッセージの概要#

CRLF: \r\n

METHOD: HTTP リクエスト,GETPOSTPUTDELETE...

URI: 統一リソース識別子,例えば/,/index.html...

HTTPVersion: HTTP プロトコルのバージョン番号,例えばHTTP/1.1,HTTP/2

HEADERS: リクエストヘッダー,例えばHost:localhost,Accept: */*.

BODY: リクエストボディ,例えば JSON データ{"name":"fzdwx"}

HTTPStatus: HTTP レスポンスステータス,一般的なものに200,404などがあります。

HTTPStatusDesc: HTTP レスポンスステータスの説明,200に対応するOK.

リクエスト#

METHOD<SPACE>URI<SPACE>HTTPVersion
HEADERS
<CRLF>
BODY

例:

GET /hello HTTP/1.1
Host: 192.168.1.107:8889
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

レスポンス#

HTTPVersion HTTPStatus HTTPStatusDesc
HEADERS
<CRLF>
BODY

例:

レスポンスでtransfer-encoding: chunkedを使用してContent-Lengthを置き換えた場合、これはサイズが不定のレスポンスであることを示し、通常は0\r\nで区切られます。

HTTP/1.1 200 OK
transfer-encoding: chunked
content-type: application/json; charset=utf-8

0/r/n

HTTP/1.1 の主な新機能#

  1. デフォルトは持続的接続 (Connection: Keep-alive)、1 つの TCP 接続で複数のリクエストを処理できます。
  2. キャッシュ戦略、リクエストヘッダーでCache-Control,Expires,Last-Modified,ETagなどを使用して制御します。
  3. レスポンスをチャンク化することが許可されており、上記で言及したtransfer-encoding: chunkedにより、サーバーが複数回レスポンスボディを返すことができます。

ただし、一定の問題も存在します。例えば、TCP 接続がブロックされた場合、新しい TCP 接続を開いてリクエストを処理します。

H2#

HTTP2 の主な概念:

  1. Connection: 1 つの TCP 接続は 1 つ以上のStreamを含み、すべての通信は1 つの TCP 接続上で行われます。
  2. Stream: 双方向通信が可能なデータストリームで、1 つまたは複数のMessageを含み、各データストリームには一意の識別子オプションの優先度情報があります。
  3. Message: HTTP/1.1 のリクエストまたはレスポンスに対応し、1 つまたは複数のFrameを含みます。
  4. Frame: 最小の伝送単位で、バイナリでエンコードされます。

HTTP 通信の簡略図

HTTP/1.1 ではStart Line + header + bodyで構成されていましたが、H2 ではHEADER Frameと複数のDATA Frameで構成されています。

Frame#

通常、いくつかの共通フィールドがあります。例えばLength,Type,FlagsおよびStream Id;また、各タイプに固有のフィールドもあります。

分類は以下の通りです:

  • DATA: HTTP メッセージボディの伝送に使用されます。
  • HEADERS: ヘッダーフィールドの伝送に使用されます。
  • PRIORITY: リソースの優先度を指定または再指定するために使用されます。
  • RST_STREAM: ストリームの異常終了を通知するために使用されます。
  • SETTINGS: クライアントとサーバーの設定データを合意するために使用されます。例えば、初期の双方向フロー制御ウィンドウサイズを設定します。
  • PUSH_PROMISE: サーバーからのプッシュ許可。
  • PING: 往復時間を計算し、「アクティブ」チェックを実行するために使用されます。
  • GOAWAY: 対向に現在の接続でストリームを作成しないよう通知するために使用されます。
  • WINDOW_UPDATE: 特定のストリームまたは接続のフローを調整するために使用されます。
  • CONTINUATION: 大きな HTTP ヘッダーを伝送する際の継続フレーム専用です。

なぜ H2 は HTTPS を使用する必要があるのか?#

これは H2 標準では規定されていませんが、主に HTTP プロトコルのアップグレード / ネゴシエーションをより便利に行うためです。Web サーバーが H2 をサポートしているかどうかを確認する方法は主に 2 つあります。

  1. リクエストヘッダーにUpgrade: HTTP/2.0およびConnection: Upgrade,HTTP2-Settingsなどを設定し、Websocketへのアップグレードに似ています。
  2. TLSALPN(Application Layer Protocol Negotiation、アプリケーション層プロトコルネゴシエーション)のALPN Next Protocolフィールドを使用し、Client HelloServer Helloの段階で確定します。

現在のブラウザは基本的に方法二を実装しており、つまりHTTPS に結びついています。ただし、ブラウザを使用せずにアクセスする場合は、もちろん HTTPS を使用しなくても構いません。

詳細は参考してください。

なぜ H2 は並行レスポンスリクエストを実現できるのか?#

HTTP/1.1 では、リクエストとレスポンスは一対一で対応しており、同じ接続内でクライアントが 2 つのリクエストを順次送信し、しばらく後にサーバーから 1 つのレスポンスを受け取ります。このレスポンスは必ず最初に送信されたリクエストに対応します。
なぜなら、どのレスポンスがどのリクエストに対応しているかを示すマークがないからです

一方、H2 ではStreamFrameの設計に基づき、FrameにはStream Idが付与され、同じStream内のデータかどうかを識別します。各Streamは互いに影響を与えず、これにより 1 つの TCP 接続内で複数のリクエスト / レスポンスを伝送できるようになります。

H2 の新機能#

H2 の HTTP/1.1 に対する最適化の核心は、可能な限り少ない接続数を使用することです。

  1. マルチプレクシング: 1 つの TCP 接続で複数のリクエスト / レスポンスを処理でき、別の TCP 接続を開く必要がありません。これはStreamFrameを通じて実現されます。
  2. バイナリ分割: Frameを最小単位として通信し、バイナリエンコーディングを使用します。
  3. ヘッダー圧縮: HPACKアルゴリズムを使用して最適化します。
    • 一般的なリクエストヘッダーの KV 組み合わせを含む静的辞書を維持します。
    • 動的辞書を持ち、動的に拡張可能です(各接続が個別に管理)。
    • ハフマンエンコーディングをサポートします(静的ハフマンコード表)。

    HTTP/1 ではメッセージボディを gzip で圧縮できますが、リクエストヘッダーは通常圧縮されていません。時にはリクエストヘッダーのデータがメッセージボディのデータよりも多くなることがあります。

  4. リクエスト優先度:通常、HEADERSフレームとPRIORITYフレームに含まれ、通常はサーバーのサポートレベルに依存します。

ツール#

テスト署名の生成#

go run $GOROOT/src/crypto/tls/generate_cert.go --host localhost

curl を使用して HTTPS をデバッグ#

curl https://zcygov.cn -vv

リンク#

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。