HTTP メッセージ
==========

HTTP メッセージは、サーバーとクライアントがデータを交換する手段です。クライアントが送信してサーバーにアクションを起こさせる*リクエスト*と、サーバーの回答である*レスポンス*の、2 種類のメッセージがあります。

HTTP メッセージは ASCII でエンコードされたテキスト情報で構成されており、複数の行にまたがります。HTTP/1.1 およびそれより前のバージョンのプロトコルでは、メッセージがコネクション内でそのまま送信されます。HTTP/2 では、人間が読める形式のメッセージを HTTP フレームに分割して、最適化やパフォーマンスの向上を実現します。

ウェブ開発者やウェブ管理者がこれらテキスト形式の HTTP メッセージを作成することはめったにありません。ウェブブラウザー、プロキシー、ウェブサーバーといったソフトウェアが行います。それらは HTTP メッセージを設定ファイル（プロキシーやサーバー）、API （ブラウザー）、あるいは他のインターフェイスによって提供します。

![ユーザーやスクリプトやサーバーが生成したイベントから、 HTTP/1.x メッセージが生成され、 HTTP/2 を使用している場合は、 HTTP/2 ストリームにバイナリーフレーム化され、送信されます。](/ja/docs/Web/HTTP/Messages/httpmsg2.png)

HTTP/2 のバイナリーフレーム化方式は、適用される API や設定ファイルの変更を必要としないように設計されています。これはユーザーに対して透過的です。

HTTP のリクエストやレスポンスは似た構造を共用しており、以下の要素で構成されます。

1. 実行するリクエスト、または成功か失敗かの状態を表す*開始行*。開始行は常に 1 行です。
2. リクエストの詳細を示す、またはメッセージに含まれる本体を説明する、省略可能な *HTTP ヘッダー*一式。
3. リクエストのメタ情報がすべて送信されたことを示す空行。
4. リクエストに関連付けられたデータ (HTML フォームの内容など)、あるいはレスポンスに関連付けられたドキュメントを含む、省略可能な*本体*。本体が存在することやそのサイズは、開始行や HTTP ヘッダーで指定します。

HTTP メッセージの開始行と HTTP ヘッダーは、まとめてリクエストの*ヘッド*として知られています。一方、ペイロードは*本体*として知られています。

![リクエストとレスポンスは HTTP で共通の構造を持っています。](/ja/docs/Web/HTTP/Messages/httpmsgstructure2.png)

HTTP リクエスト
----------

### リクエスト行

*メモ: HTTP リクエストにおいて、開始行は『リクエスト行』と呼ばれます。*

HTTP リクエストは、アクションを始めるためにクラアントからサーバーへ送られます。そのリクエスト行には、3 つの要素が含まれています。

1. *HTTP メソッド*。実行するアクションを表わす動詞 (`GET`、`PUT`、`POST` など) または名詞 (`HEAD`、`OPTIONS`)。例えば `GET` はリソースを取り込むこと、`POST` はデータをサーバーへ送信すること (リソースを作成または変更する、あるいは返送する一時的なドキュメントを生成する) ことを示します。
2. *リクエスト対象*。通常は URL ですが、プロトコル、ポート番号、ドメインの絶対パスは通常、リクエストの状況から明らかにされます。リクエスト対象の形式は、HTTP メソッドにより異なります。以下のような形式があります。
    * 最後に `'?'` とクエリー文字列がある絶対パス。これは*オリジン形式*とも呼ばれているもっとも一般的な形式であり、`GET`、`POST`、`HEAD`、`OPTIONS` メソッドで使用します。
        + `POST / HTTP/1.1`
        + `GET /background.png HTTP/1.0`
        + `HEAD /test.html?query=alibaba HTTP/1.1`
        + `OPTIONS /anypage.html HTTP/1.0`
    * 完全な URL は*絶対形式*とも呼ばれ、主にプロキシーへ接続する際に `GET` で使用します。
     `GET https://developer.mozilla.org/ja/docs/Web/HTTP/Messages HTTP/1.1`
    * ドメイン名とポート（省略可能。`':'` を前につける）で構成される、URL の authority の部分は*認証形式*と呼ばれます。これは `CONNECT` で HTTP トンネルを設定するときに限り使用されます。
     `CONNECT developer.mozilla.org:80 HTTP/1.1`
    * 単純なアスタリスク (`'*'`) である*アスタリスク形式*は `OPTIONS` で使用され、サーバー全体を表します。
     `OPTIONS * HTTP/1.1`
3. *HTTP バージョン*。これはメッセージの残りの部分の構造を定義しており、レスポンスで使用することを想定しているバージョンを示す役割もあります。
### ヘッダー

リクエストの HTTP ヘッダー は、HTTP ヘッダーの一定の基本構造に従います。大文字・小文字を区別しない文字列の後にコロン (`':'`) と、ヘッダーに応じた構造の値が続きます。値を含むヘッダー全体は 1 行で構成されており、とても長くなる場合もあります。

様々なヘッダーがリクエストに現れることがあります。これらはいくつかのグループに分類されます。

* 一般ヘッダーは、 `Via` など、メッセージ全体に適用されるものです。
* リクエストヘッダーは、 `User-Agent`, `Accept` などで、指定するとリクエストを変更するもの（`Accept-Language` など）、状況を示すもの（`Referer` など）、条件を制約するもの（`If-None` など）があります。
* 表現ヘッダーは `Content-Type` など、メッセージデータの下の形式や適用されているエンコーディングを説明します（メッセージの本体がある場合のみ存在します）。

![HTTP リクエストのヘッダーの例](/ja/docs/Web/HTTP/Messages/http_request_headers3.png)

### 本体

リクエストの最後の部分が本体 (body) です。本体が存在しないリクエストもあります。リソースを取り込むリクエストである `GET`, `HEAD`, `DELETE`, `OPTIONS` は通常、本体は不要です。サーバー内のデータを更新するためにデータを送信するリクエストもあり、 `POST` リクエストでよくあります（HTML フォームのデータを持つ）。

本体は、大きく 2 種類に分類されます。

* 単一リソースの本体。1 個のファイルで構成され、`Content-Type` と `Content-Length` の 2 つのヘッダーで定義されます。
* 複数リソースの本体。マルチパートの本体で構成され、それぞれが異なる情報を持ちます。これは主に、 HTML フォームと関連付けられます。
HTTP レスポンス
----------

### ステータス行

HTTP レスポンスの開始行は*ステータス行*と呼ばれ、以下の情報を持ちます。

1. *プロトコルバージョン*。通常 `HTTP/1.1` です。
2. *ステータスコード*。リクエストが成功したか失敗したかを示します。一般的なステータスコードは `200`, `404`, `302` です。
3. *ステータステキスト*。手短な単なる情報ですが、人間が HTTP メッセージを理解するのを助けるために、ステータスコードをテキストで説明します。

一般的に、ステータス行は `HTTP/1.1 404 Not Found.` のようになります。

### ヘッダー

レスポンスの HTTP ヘッダーは、他のヘッダーと同様に一定の基本構造に従います。大文字・小文字を区別しない文字列の後にコロン (`':'`) と、ヘッダーの種類に応じた構造の値が続きます。値を含むヘッダー全体は 1 行で構成されます。

使用できるレスポンスヘッダーは多数あります。これらはいくつかのグループに分類されます。

* 一般ヘッダーは `Via` など、メッセージ全体に適用されるものです。
* レスポンスヘッダーは `Vary` や `Accept-Ranges` など、ステータス行で伝えられないサーバーの追加情報を与えます。
* 表現ヘッダーは `Content-Type` など、レスポンスの本体に適用されます。通常、レスポンス内に本体がない場合はこのようなヘッダーは送信されません。

![HTTP レスポンスヘッダーの例](/ja/docs/Web/HTTP/Messages/http_response_headers2.png)

### 本体

レスポンスの最後の部分が本体です。本体を持たないレスポンスもあります。 `201` **`Created`** や `204` **`No Content`** といったステータスコードのレスポンスは通常、本体がありません。

本体は、大きく 3 種類に分類されます。

* 大きさが判明している 1 個のファイルで構成される、単一リソースの本体。 `Content-Type` と `Content-Length` の 2 つのヘッダーで定義されます。
* 大きさが不明な 1 個のファイルで構成される、単一リソースの本体。 `Transfer-Encoding` を `chunked` に設定して、 chunked 形式でエンコードされます。
* 複数リソースの本体。マルチパートの本体で構成され、それぞれが異なる情報のセクションを持ちます。これは比較的まれです。
HTTP/2 フレーム
-----------

HTTP/1.x のメッセージには、パフォーマンスの欠点があります。

* ヘッダーは本体と異なり、圧縮されません。
* あるメッセージと次のメッセージでヘッダーが酷似していることがよくありますが、それでも複数のコネクションにわたって繰り返されます。
* 多重化することができません。同じサーバーに対して複数のコネクションを開かなければなりません。また、ウォーム状態の TCP コネクションはコールド状態のコネクションより効率的です。

HTTP/2 は次の段階に進みました。 HTTP/1.x のメッセージを、ストリーム内に埋め込まれるフレームに分割します。データのフレームとヘッダーのフレームは区別され、ヘッダーの圧縮が可能になります。*多重化*と呼ばれる処理によって複数のストリームがまとめられ、下層の TCP コネクションの効率を向上させることができます。

![HTTP/2 は HTTP メッセージをフレーム（単一のストリームの一部）に分割するように変更し、より最適化できるようにします。](/ja/docs/Web/HTTP/Messages/binary_framing2.png)

HTTP フレームは、ウェブ開発者に対しては透過的になります。これは HTTP/2 において、 HTTP/1.1 メッセージと基盤となるトランスポート層との間のさらなるステップです。 HTTP フレームを利用するためにウェブ開発者が使用する API を変更する必要はありません。ブラウザーとサーバーの両方で利用可能になれば、 HTTP/2 が有効になり使用されます。

まとめ
---

HTTP メッセージは、 HTTP を使用する際に重要なものです。その構造はシンプルであり、拡張性が高くなっています。 HTTP/2 のフレーム化機能は、 HTTP/1.x の構文と基盤となるトランスポートプロトコルの間の新たな中間層であり、根底は変わりません。実証された仕組みの上に構築されました。