HTTP(Hyper Text Transfer Protocol)

1991年に登場して以来、「HTTP/0.9」→「HTTP/1.0」→「HTTP/1.1」→「HTTP/2」→「HTTP/3」と、4度のバージョンアップが行われている。お互いの設定や対応状況が異なる場合は、やり取りの中で適切なプロトコルバージョンを選択する。

図:HTTPバージョンの変遷

HTTPのメッセージフォーマット

HTTPでやり取りするメッセージのことをHTTPメッセージという。HTTPメッセージには、WebブラウザがWebサーバーに対して処理をお願いするリクエストメッセージと、WebサーバーからWebブラウザに対して処理結果を返すレスポンスメッセージの2種類がある。どちらのメッセージも、メッセージの主目的や概要が格納される制御データ、メッセージやコンテンツに関する付加情報(メタデータ)が格納されるヘッダーセクション、アプリケーションデータの本文(HTTPペイロード)が格納されるコンテンツで構成されている。

図:HTTPメッセージを構成する要素

HTTP/1.1のメッセージフォーマット

HTTP/1.1は、同時に複数のTCPコネクションを作って、テキスト形式のHTTPメッセージを並列にやり取りする。(※最近のWebブラウザは1つのWebサーバーに対して最大6本のTCPコネクションを作る)

図:HTTP/1.1

リクエストメッセージ

制御データにリクエストラインが、ヘッダーセクションに1つ以上のヘッダーフィールド(フィールド名+フィールド値)が格納されている。リクエストラインとすべてのヘッダーフィールドはひとつひとつ改行コード(¥r¥n)によって区切られていて、ヘッダーフィールドが終わると、改行コードで空行を入れてからコンテンツが始まる。

図:リクエストメッセージ

リクエストライン

その名の通り、WebブラウザがWebサーバーに「〇〇してください」と処理を依頼するための行。リクエストの種類を表すメソッド、リクエストの対象を表すリクエスト対象(リクエストターゲット)、HTTPバージョンを表すHTTPバージョンの3つで構成されていて、半角スペースを挟んで1行につながっている。Webブラウザは、指定されたHTTPバージョンで、指定されたWebサーバー上のリソースに対して、指定されたメソッドの処理を依頼する。

図:リクエストラインの構成要素

メソッドはWebブラウザがWebサーバーに対してお願いするリクエストの種類を表している。

表:RFC9110で定義されているメソッド

リクエスト対象は、Webブラウザがリクエストを送信するリソースを表している。WebサーバーのリソースにはURI(Uniform Resource Identifier)という名前の識別子がついている。URIはhttpやhttpsなどのプロトコルを表すスキーム名、WebサーバーのアドレスやFQDNを表すオーソリティ、Webサーバー上のファイルを表すパス、追加のパラメータを渡す任意のクエリ文字列で構成されている。図:リクエスト対象

ヘッダーセクション

1つ以上のヘッダーフィールドによって構成されている。各ヘッダーフィールドは「フィールド名」と「フィールド値」のペアで構成されていて、「Host: www.example.com」のように「:」(コロン)と半角スペースで区切られている。

図:ヘッダーフィールドの構成要素

表:代表的なヘッダーフィールド

レスポンスメッセージ

HTTP/1.1のレスポンスメッセージは、制御データにステータスラインが、ヘッダーセクションに1つ以上のヘッダーフィールドが格納されている。ステータスラインとすべてのヘッダーフィールドは一つ一つ改行コードによって区切られていて、ヘッダーフィールドが終わると改行コードで空行を入れてから、コンテンツが始まる。

図:レスポンスメッセージ

ステータスライン

ステータスラインはWebサーバーがWebブラウザに対して処理結果の概要を返す行。HTTPのバージョンを表すHTTPバージョン、処理結果の概要を3桁の数字で表すステータスコード、その理由を表すリーズンフレーズで構成されている。

図:ステータスラインの構成要素

ステータスコードとリーズンフレーズは一意に紐づいている。

図:代表的なステータスコードとリーズンフレーズ

ヘッダーセクション

構成されるフィールドは異なるものの、基本的な形式はリクエストメッセージと同じ。

HTTP/2のメッセージフォーマット

HTTP/2は1本のTCPコネクションの中にストリームという仮想的な通路を作り、フレームというバイナリ形式のHTTPメッセージを並列にやり取りする

図:HTTP/2

制御データとヘッダーセクションで構成されるヘッダーをHEADERSフレームに、コンテンツをDATAフレームにそれぞれ分割して格納し、バイナリ形式のフレーム単位でストリームに流す。その際、フレームにストリームを識別するストリームIDを付与し、どのストリームにフレームを流すかを指定する。バイナリ形式なので変換処理は不要。

表:RFC9113で定義されているフレームの種類

図:HTTP/2はバイナリ形式でやり取りする

バイナリ形式への変更に加えて、制御データやヘッダーセクションにもいくつかの変更が加えられている。中でも大きく変更されている点はリクエストラインとステータスライン。HTTP/2ではHTTP/1.1におけるリクエストラインとステータスラインの構成要素を疑似ヘッダーフィールドという名前のヘッダーフィールドの一つとして扱う。

また、よく使用するヘッダーフィールド名やフィールド値をあらかじめ静的に決められた数字に置き換えたり、一度送信したヘッダーフィールドを動的に割り当てた数字に置き換えたりすることによって、ヘッダーフィールドの転送量の削減を図っている。この機能のことをHPACKという。

図:HPACK

リクエストメッセージ

HTTP/2のリクエストメッセージは、制御データとヘッダーセクションがHEADERSフレームに、コンテンツがDATAフレームに格納されている。

制御データは、リクエストラインと同じ役割を持つ、複数の疑似ヘッダーフィールドで構成されている。疑似ヘッダーフィールドは「:method: GET」のように一般的なヘッダーフィールド形式の先頭に「:」(コロン)がくっつく。制御データにはHTTP/1.1のリクエストラインにあったメソッドが「:methodヘッダーフィールド」として、リクエスト対象が「:pathヘッダーフィールド」として格納される。またそれ以外にも、リクエストで使用されているプロトコルが「:schemeヘッダーフィールド」として、HTTP/1.1のリクエストメッセージで必須のヘッダーフィールドだった「Hostヘッダーフィールド」が「:authorityヘッダー」として格納されている。

制御データの後にはHTTP/1.1と同じように「<フィールド名>: <フィールド値>」のペアからなる複数のヘッダーフィールドが続く。各フィールドが持つ基本的な役割については大きな違いはない。

図:HTTP/2のリクエストメッセージ

レスポンスメッセージ

HTTP/2のレスポンスメッセージは制御データとヘッダーセクションがHEADERSフレームに、コンテンツがDATAフレームに格納されている。

制御データはステータスラインと同じ役割を持つ、疑似ヘッダーフィールドで構成される。HTTP/1.1のステータスラインにあったステータスコードが「:statusフィールド」に格納されている。リーズンフレーズはステータスコードから一意に導き出せるということで廃止された。

制御データのあとにはHTTP/1.1と同じように「<フィールド名>:<フィールド値>」のペアからなる複数のヘッダーフィールドが続く。各フィールドが持つ基本的な役割については大きな違いはない。

図:HTTP/2のレスポンスメッセージ


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です