Hypertext Transfer Protocol

Hypertext Transfer Protocol（ハイパーテキスト・トランスファー・プロトコル、HTTP）はアプリ間コネクション上のリクエスト/レスポンス型・ステートレス・メッセージ指向通信プロトコルである。
概要.
TCPやQUICはアプリケーション間のコネクション型通信を提供する。HTTPはこのコネクション上を、リソース要望と返答が、メッセージ単位で、1往復のクライアントリクエスト&サーバーレスポンスという形で通信される、と定めたプロトコルである。
HTTPの発明により、インターネット上でのリソース公開とアクセスが容易になった。クライアントがサーバーとコネクションを確立し1つのHTTPメッセージを書いて送るだけで、サーバー上のリソースがHTTPメッセージとして帰ってくる。ゆえにHTTPで公開されるあらゆるリソースにHTTPという単一の手法でアクセスできるようになった。
HTTPを開発した理由でありかつ現在も広く利用される用途はWorld Wide Webである。WebサーバとWebブラウザはHTTPで主に通信しており、ブラウザからのHTTPメッセージに応答してサーバーがHTMLテキストやJavaScriptコードを送り返し、これをブラウザで表示することでウェブが成立している。
またHTTPはメッセージ形式を定める。基本的な考え方は単純で「何を」「どうして」欲しいのかを伝える。例えばリクエストメッセージ codice_1 は「apple.jpg 画像を、手に入れたい」を意味する。URLが「何を」に、メソッドが「どうして」に当たる。
World Wide WebにおけるWebページなどのリソースは、Uniform Resource Identifierによって指定される。HTTP を使用してリソースにアクセスするときは、http: が先頭についた URL を使用する。下にURL の例を挙げる。
 http://www.example.co.jp/~test/samples/index.html
最初の HTTP/0.9 ではURLを指定してコンテントをダウンロードするのみの簡単なやりとりだったが、HTTP/1.0 で改良された。
HTTP/1.1 では複数データを効率よく転送するための持続的接続や、プロキシの利用なども想定した仕様になった。さらに HTTP/2やHTTP/3が策定された。現在ではHTTPセマンティクスと各バージョンの手続きが分離して定義されている（#規格を参照）。
このほかの点を箇条書きで示す。
歴史.
イギリスの物理学者ティム・バーナーズ＝リーは1990年末、ロバート・カイリューと共に初のWebブラウザとWebサーバを作成した。ブラウザには通信をするためのプロトコルが必要だったので、二人はHTTPの最初期のバージョンを設計した。
以来インターネットの大部分をHTTP通信が占めるようになり、1998年にはインターネット上の通信の75%がHTTPによるものになった。
最初期のHTTP/0.9の仕様書は紙に印刷すれば1枚で済むような非常に簡素なドキュメントだったが、2度のバージョンアップを経たHTTP/1.1の仕様書は実に176ページ近くの分量に膨れあがった。
HTTP/0.9.
1991年に最初にドキュメント化されたバージョン。メソッドは GET しかなかった。レスポンスは単純にドキュメントの内容を返してコネクションを切断するだけで、レスポンスコードの規定もない。下記は、HTTP/0.9 のリクエストの例。
 GET /index.html
HTTP/1.0.
1996年5月に RFC 1945 として発表された。仕様が RFC で扱われるようになった。メソッドに POST など GET 以外のものが増えた。レスポンスはヘッダーがつくようになり、ステータスコードを含めるようになった。HTTP/0.9 と区別するため、リクエストプロトコルにバージョンを含めることになった。
HTTP/2.
HTTP/2の目標はHTTP/1.1のトランザクション・セマンティクスとの完全な後方互換性を維持したまま非同期な接続の多重化、ヘッダ圧縮、リクエストとレスポンスのパイプライン化を実現することである。Googleによって立ち上げられ、GoogleのブラウザーであるChromeだけではなく、他にも、Opera、Firefox、Amazon Silkなどが対応しているHTTP互換のプロトコルSPDYの人気が高まっていることに対応するために開発された。
HTTP/3.
HTTP-over-QUIC（hq）としてIETFが開発していた新たな通信プロトコルが、HTTP/3へと改名される。
IETFが策定を進めているQUICはトランスポート層におけるプロトコルの名称であり、アプリケーション層プロトコルであるHTTP-over-QUICとの区別を明確にするため、このような名称変更に至った。
HTTP/2と比べ、多重化するストリームの取り扱いが下位層のQUICへ移行したこと、を回避するためのヘッダ圧縮の変更（HTTP/3用にQPACKが開発されている）などの差異がある。
動作.
通信の開始.
他のプロトコル同様、クライアント側とサーバ側では役割が大きく異なる。HTTP通信を開始できるのはクライアント側のみである。
クライアント側がサーバにリクエストを送り、サーバがクライアントにレスポンスを返すのが最も典型的なHTTPのやりとりである。
接続.
システム間でメッセージをやりとりするには接続を確立させる必要がある。HTTP/0.9～HTTP/1.1およびHTTP/2ではTCPを使用する。
HTTP/0.9ではクライアントのリクエストごとにTCP接続を確立させる必要があった。これは当時のWebサイトがシンプルなテキストベースであることが多かったためである。近年ではJavaScriptやアニメーション画像など、多数のオブジェクトが埋め込まれたWebサイトが一般的となってきており、これらのオブジェクトを取得するたびにTCP接続を確立するのはサーバやネットワークに大きな負担を強いるため、1回のTCP接続で、複数のHTTPリクエスト・レスポンスをやり取りする持続的接続がHTTP/1.0の拡張として導入された。その後、HTTP/1.1では、持続的接続がデフォルトとなった。すなわち、何も指定しなければ持続的接続となり、持続的接続を望まなければヘッダーフィールドにConnection: closeを追加する仕様となっている。
パイプライン.
クライアントは前のリクエストに対するサーバの応答を待たずに別のリクエストを発行できる。
リクエストメソッド.
HTTPでは8つのメソッドが定義されている。ただし、実際のHTTP通信ではGETとPOSTメソッドが大部分を占める。
HTTPの仕様以外で定義しているメソッドは、IANAのHypertext Transfer Protocol (HTTP) Method Registryで管理されている。WebDavで使用するものや、 RFC 5789 のなどがある。
サーバの連携.
バーチャルホスト.
1つのサーバーで複数のホスト名に対するHTTPリクエストを受け付ける機能である。
インターネット人気に伴い多くの企業がWebサイトを持ち始めたが、当時はまだまだ企業が自前のWebサーバを運用するのは人員、効率の問題で難しく、ISPのサーバでホスティングをしていた。また、1社ごとに専用サーバを用意するほどのことでもないため、1台のサーバで複数のWebサイトを運用していた。
しかし、IPアドレスのみで相手を特定するHTTP/1.0はこれに対応できなかった。例えば、ある1台のサーバに foo.example.com と bar.example.com という2つの仮想Webサーバがあり、クライアントは http://foo.example.com/index.html にアクセスしたいとする。この場合はDNSサーバに foo.example.com のIPアドレスを問い合わせ、次にそのIPアドレスを使って該当サーバにアクセスし、GET index.html を要求することになる。しかし同じサーバ上にある bar.example.comもIPアドレスは同じであり、もし両方の仮想サーバに index.html というファイルが存在すれば、クライアントがどちらにアクセスしようとしているのか、判別できない。
対策としてはそれぞれにIPアドレスを付与する方法もあるが、IPv4の資源を無駄にすることになる。この問題を解決するため、HTTP/1.1でHostヘッダーフィールドが追加され、名前ベースバーチャルホストが用いられるようになった。
名前ベースバーチャルホストのため、以下のようにHTTPリクエストでホスト名を指定する。
リダイレクト.
別のURIに対して再度のメソッド実行を要求する機能である。301 Movedや303 See Otherなどのリダイレクトを指示するステータスコードとURIを受け取り、クライアントはこのURIに再度メソッドを実行する。
HTTPメッセージ.
リクエストとレスポンスでやり取りされるデータは、HTTPメッセージと呼ばれる。クライアントからリクエストHTTPメッセージを送り、サーバーからレスポンスHTTPメッセージを返す。
HTTPメッセージは以下で構成される。
なおHTTP/1.1では、コントロールデータをリクエスト行・ステータス行として表現し、コンテントを格納する部分をメッセージボディまたは単にボディと呼ぶ。
ヘッダー・コンテント・トレイラーは空となる場合もある。
下にもっとも単純なクライアントとサーバ(www.google.co.jp:80)とのやり取りの例を挙げる。
クライアントのリクエスト:
GET / HTTP/1.1
Host: www.google.co.jp
この例では、リクエスト行とヘッダーにフィールドが1項目あるのみで、ボディは空でトレーラーも無い。
リクエスト行はメソッド、リクエストターゲット、HTTPバージョンの3つの要素から構成され、それぞれスペースで区切られる。
メソッドはcodice_2、リクエストターゲットは「/」、HTTPバージョンは1.1である。
codice_2はリソースを取得するためのメソッドであり、リクエストターゲットの「/」はURIのパス部分であってルートリソースを対象にしたリクエストであることを示している。
サーバのレスポンス:
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html
Set-Cookie: PREF=ID=72c1ca72230dea65:LD=ja:TM=1113132863:LM=1113132863:S=nNO7MIp
W2o7Cqeu_; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.co.jp
Server: GWS/2.1
Date: Sun, 10 Apr 2005 11:34:23 GMT
Connection: Close
<html><head><meta http-equiv="content-type" content="text/html; charset=Shift_JI
 S"><title>Google</title><style><!-- 
……以下省略 -->
先頭のステータス行はHTTPバージョン、ステータスコード、ステータスメッセージから構成される。
ステータスコードの「200」は処理の成功を表し、これを補足するメッセージが「OK」である。
2行目以降にヘッダフィールドが続く。
さらに空行を挟んで、レスポンスボディとなる。
このレスポンスにもトレーラーは無い。
HTTPヘッダフィールド.
ヘッダの各要素はのペアで構成される。
ブラウザの情報を表すcodice_4、使用候補言語を表すcodice_5、他ページへのリンクを辿った場合にそのリンク元ページのURLを表すcodice_6などが代表的なフィールドである。
なお、リクエスト時のcodice_7ヘッダはHTTP/1.1では必須であるが、HTTP/1.0ではなくてもよい。
ただし、サーバがバーチャルホストを利用している場合は、codice_7ヘッダがないとリソース取得に失敗するので、たとえHTTP/1.0を使用していてもcodice_7ヘッダを付加しなければならない。
HTTPヘッダフィールドの一覧.
Accept: text/plain; q=0.5, text/html,
 text/x-dvi; q=0.8, text/x-c
HTTPステータスコード.
ステータスコードはサーバからのレスポンスで、リクエストの結果を通知する。3桁の数字から成り、おおまかな分類として、1xxは「情報」、2xxは「成功」、3xxは「リダイレクト」、4xxは「クライアントエラー」、5xxは「サーバエラー」を示す。
セキュリティ技術.
いくつかの観点でセキュリティに関する追加機能が存在する。
HTTPS.
セキュアな通信路でHTTP通信を行うことを通常HTTPSと言う。
HTTP認証.
HTTPの中で認証を行う仕組みが用意されている。
Basic認証.
HTTP/1.1で定義されている最も単純なセキュリティ技術である。「基本認証を用いるくらいならなにも使わない方がまし」と主張する人もいる。平文で認証情報を送信する仕組みであるため、TLS (HTTPS)など安全を確保した通信路での利用が望ましい。通常サーバはステータスコード401で応答する。
規格.
HTTPはIETFを始めとした標準化団体により規格化されている。以下はその一部である。
歴史的には各バージョンが独立して規格化されてきた。しかし現行の3バージョン（v1.1, v2, v3）が共通のセマンティクスを維持していたことから、これを独立した規格とする活動が推進され現在の形になっている。
派生・拡張プロトコル.
HTTPSのほか、以下のようなHTTPのセマンティクスを利用するプロトコル、HTTPの構文を元とするプロトコルなどが存在する。以下はその一例である。
なお、このようなHTTPの利用に関する文書として RFC 9205 Building Protocols with HTTP (BCP 56)が存在する。
外部リンク.
以下は旧式であり非推奨となった仕様
その他