HTTP(Hypertext Transfer Protocol、ハイパーテキスト・トランスファー・プロトコル)は、ハイパーメディアを転送する通信プロトコルであり、主にインターネット上で利用される。World Wide Webのデータ通信の基盤を支える技術であり、インターネット・プロトコル・スイートの一つである。
概要 TCPやQUICはアプリケーション間のコネクション型通信を提供する。HTTPはこのコネクション上を、リソース要望と返答が、メッセージ単位で、1往復のクライアントリクエスト&サーバーレスポンスという形で通信される、と定めたステートレスのプロトコルである"The Hypertext Transfer Protocol (HTTP) is a family of stateless, application-level, request/response protocols ... HTTP is a stateless request/response protocol for exchanging 'messages' across a connection." .。
HTTPの発明により、インターネット上でのリソース公開とアクセスが容易になった。クライアントがサーバーとコネクションを確立し1つのHTTPメッセージを書いて送るだけで、サーバー上のリソースがHTTPメッセージとして帰ってくる。ゆえにHTTPで公開されるあらゆるリソースにHTTPという単一の手法でアクセスできるようになった。
HTTPを開発した理由でありかつ現在も広く利用される用途はWorld Wide Webである。WebサーバとWebブラウザはHTTPで主に通信しており、ブラウザからのHTTPメッセージに応答してサーバーがHTMLテキストやJavaScriptコードを送り返し、これをブラウザで表示することでウェブが成立している。
またHTTPはメッセージ形式を定める。基本的な考え方は単純で「何を」「どうして」欲しいのかを伝える。例えばリクエストメッセージ GET /apple.jpg は「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 で改良された。 様々なリクエストメソッドが追加された。POSTを使って、アップロード(クライアントからサーバへのデータの転送)が可能になった。 NNTPやSMTPのような各種ヘッダが定義され、HTTP cookieなどの利用が可能になった。 HTTP/1.1 では複数データを効率よく転送するための持続的接続や、プロキシの利用なども想定した仕様になった。さらに HTTP/2やHTTP/3が策定された。現在ではHTTPセマンティクスと各バージョンの手続きが分離して定義されている(#規格を参照)。
このほかの点を箇条書きで示す。
TCPのポート番号80をデフォルトとして使用する(HTTP/0.9〜1.1とHTTP/2の場合)。 TLSで暗号化され、セキュリティを確保したHTTPは、HTTPSと呼ばれる(httpsは実際にはURIスキームの1つであり、実際のプロトコルにはHTTP over SSL/TLSまたはHTTP/3が用いられる)。 HTTP は基本的にサーバが状態を保持しない (stateless) プロトコルだが、データベースなどを使用するWebアプリケーションにおいては状態保持が必要だったため、いわゆる Cookie(クッキー)とよばれる機構が Netscape Communications Corporation によって導入された。Cookie を使用することによって状態を管理し、セッションを維持することが可能になる。 行末文字はCRLFで、インターネット・プロトコル・スイートにおいてアプリケーション層に属する他の多くのプロトコルと同じである(HTTP/0.9〜1.1の場合)。
歴史 イギリスの物理学者ティム・バーナーズ=リーは1990年末、ロバート・カイリューと共に初のWebブラウザとWebサーバを作成した。ブラウザには通信をするためのプロトコルが必要だったので、二人はHTTPの最初期のバージョンを設計した。
以来インターネットの大部分をHTTP通信が占めるようになり、1998年にはインターネット上の通信の75%がHTTPによるものになった。
最初期のHTTP/0.9の仕様書は紙に印刷すれば1枚で済むような非常に簡素なドキュメントだったが、2度のバージョンアップを経たHTTP/1.1の仕様書は実に176ページ近くの分量に膨れあがった。
HTTP/0.9 1991年に最初にドキュメント化されたバージョンThe HTTP Protocol As Implemented In W3。メソッドは GET しかなかった。レスポンスは単純にドキュメントの内容を返してコネクションを切断するだけで、レスポンスコードの規定もない。下記は、HTTP/0.9 のリクエストの例。
GET /index.html
HTTP/1.0 1996年5月に として発表された。仕様が RFC で扱われるようになった。メソッドに POST など GET 以外のものが増えた。レスポンスはヘッダーがつくようになり、ステータスコードを含めるようになった。HTTP/0.9 と区別するため、リクエストプロトコルにバージョンを含めることになった。 HTTP/1.0のリクエスト GET /index.html HTTP/1.0
HTTP/1.1 1997年1月に として初版が発表された。その後、3回改訂され、現在はセマンティクス・キャッシングを除く部分がで規定されている。
名前ベースバーチャルホストのため、Hostヘッダーフィールドの規定が追加された。
HTTP/1.1のリクエスト GET /index.html HTTP/1.1 Host: foo.example.com
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との区別を明確にするため、このような名称変更に至った。IETF Meetingの資料スライド
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メソッドが大部分を占める。2026年、QUERYメソッドが追加された。
+ HTTPメソッドの一覧メソッドHTTP/0.9HTTP/1.0HTTP/1.1GET○○○POST○○PUT△○HEAD○○DELETE△○OPTIONS○TRACE○CONNECT○QUERY○
GET 指定されたURIのリソースを取り出す。HTTPの最も基本的な動作で、HTTP/0.9では唯一のメソッド。 POST
GETとは反対にクライアントがサーバにデータを送信する。Webフォームや電子掲示板への投稿などで使用される。GETの場合と同じく、サーバはクライアントにデータを返すことができる。 PUT 指定したURIにリソースを保存する。URIが指し示すリソースが存在しない場合は、サーバはそのURIにリソースを作成する。画像のアップロードなどが代表的。 DELETE 指定したURIのリソースを削除する。 OPTIONS サーバを調査する。例えば、サーバがサポートしているHTTPバージョンなどを知ることができる。 HEAD GETと似ているが、サーバはHTTPヘッダのみ返す。クライアントはWebページを取得せずともそのWebページが存在するかどうかを知ることができる。例えばWebページのリンク先が生きているか、データを全て取得することなく検証することができる。 TRACE サーバまでのネットワーク経路をチェックする。サーバは受け取ったメッセージのそれ自体をレスポンスのデータにコピーして応答する。WindowsのTracertやUNIXのTracerouteとよく似た動作。 CONNECT TCPトンネルを接続する。暗号化したメッセージをプロキシサーバを経由して転送する際に用いる。当初、ネットスケープコミュニケーションズによって考案されたものがIETFドラフトTunneling TCP based protocols through Web proxy serversとして公開され、 に取り込まれた。その後、 で定義が更新されている。 QUERY べき等性(リトライしても結果が変わらない)のあるメソッド。GETでURIにクエリ文字列を入れたときの文字列長の問題を解決する。。本文にデータセットするのがPOSTメソッドと同じだが、POSTメソッドがクライアントからサーバにデータをセットする、SQLで言うUPDATE/INSERTに相当するが、QUERYメソッドはサーバのデータをクライアントが取得するSELECTに相当する。POSTメソッドは、サーバのデータを更新するのでべき等性は保証されない。
HTTPの仕様以外で定義しているメソッドは、IANAのHypertext Transfer Protocol (HTTP) Method RegistryHypertext Transfer Protocol (HTTP) Method Registryで管理されている。WebDavで使用するものや、 のなどがある。
サーバの連携 バーチャルホスト 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リクエストでホスト名を指定する。
HTTP/1.1: Hostヘッダーフィールドでホスト名を指定する。 HTTP/2およびHTTP/3: :authority疑似ヘッダーフィールドでホスト名を指定する。
リダイレクト
別のURIに対して再度のメソッド実行を要求する機能である。301 Movedや303 See Otherなどのリダイレクトを指示するステータスコードとURIを受け取り、クライアントはこのURIに再度メソッドを実行する。
クッキー
HTTPメッセージ リクエストとレスポンスでやり取りされるデータは、HTTPメッセージと呼ばれる。クライアントからリクエストHTTPメッセージを送り、サーバーからレスポンスHTTPメッセージを返す。
HTTPメッセージは以下で構成される, 6. Message Abstraction。 コントロールデータ ヘッダー コンテント トレイラー
なおHTTP/1.1では、コントロールデータをリクエスト行・ステータス行として表現し、コンテントを格納する部分をメッセージボディまたは単にボディと呼ぶ。
ヘッダー・コンテント・トレイラーは空となる場合もある。
下にもっとも単純なクライアントとサーバ(www.google.co.jp:80)とのやり取りの例を挙げる。
クライアントのリクエスト: GET / HTTP/1.1 Host: www.google.co.jp
この例では、リクエスト行とヘッダーにフィールドが1項目あるのみで、ボディは空でトレーラーも無い。 リクエスト行はメソッド、リクエストターゲット、HTTPバージョンの3つの要素から構成され、それぞれスペースで区切られる。 メソッドはGET、リクエストターゲットは「/」、HTTPバージョンは1.1である。
GETはリソースを取得するためのメソッドであり、リクエストターゲットの「/」は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ヘッダフィールド ヘッダの各要素はフィールド名: 内容のペアで構成される。 ブラウザの情報を表すUser-Agent、使用候補言語を表すAccept-Language、他ページへのリンクを辿った場合にそのリンク元ページのURLを表すRefererなどが代表的なフィールドである。
なお、リクエスト時のHostヘッダはHTTP/1.1では必須であるが、HTTP/1.0ではなくてもよい。 ただし、サーバがバーチャルホストを利用している場合は、Hostヘッダがないとリソース取得に失敗するので、たとえHTTP/1.0を使用していてもHostヘッダを付加しなければならない。
HTTPヘッダフィールドの一覧 + リクエストヘッダヘッダ概要HTTP/0.9HTTP/1.0HTTP/1.1Acceptクライアントの受け入れ可能コンテンツタイプを示す○○Accept-Charsetクライアントの受け入れ可能文字セットを示す○○Accept-Encodingクライアントの受け入れ可能文字エンコーディングを示す○○Accept-Languageクライアントの受け入れ可能言語を示す○○Authorizationクライアントの認証情報を示す○○Cookieクライアントの状態管理情報をサーバに返すCookie2HTTP/1.1のSet-Cookie2ヘッダの受け入れ可能をサーバに知らせるExpectクライアントがサーバに期待する動作を示す○Fromリクエスト発行者個人の情報を示す。一般的に電子メールアドレスを使用する○○Host要求しているオブジェクトがあるホストを示す○If-Matchif文を用い条件が真の場合のみリクエストを処理するようサーバに要求する○If-None-MatchIf-Matchの逆で条件が真でない場合のみリクエストを処理する要求○If-Range条件が真の場合のみ指定したオブジェクトの範囲を返すようサーバに要求する○If-Modified-Since指定日時以降にオブジェクトが変更されている場合のみリクエストを処理するよう要求する○○If-Unmodified-SinceIf-Modified-Sinceの逆で真でないときのみ実行する○Max-Forwardsリクエストの中間システム経由数を最大いくつまでかを指定する○Proxy-Authorizationクライアントがプロキシサーバに対して自身の認証を行う○Rangeオブジェクト全体でなくリソースの一部を要求する○Refererリクエストの出所を示す。一般的にはユーザの辿ったWebページのURLが用いられる○○TEレスポンスの受け入れ可能転送エンコーディングを示す○User-AgentクライアントのWebブラウザなどの情報を示す○○
+ レスポンスヘッダヘッダ概要HTTP/0.9HTTP/1.0HTTP/1.1Accept-Rangesオブジェクトの一部に対するリクエストをサーバが受け入れ可能か示す○Ageオブジェクトの経過時間を秒単位で返す○ETagオブジェクトのエンティティタグ値を示す○Locationオブジェクトの場所を示す○○Proxy-Authenticateプロキシサーバがクライアントに認証を要求するときに用いる○Retry-Afterリクエストの再試行をいつ行うかをクライアントに通知する○○Serverサーバのベンダー名、バージョン番号を示す○○Set-Cookie2サーバがクライアントにCookieを送信するときに用いるVaryサーバがレスポンス内容を決定する際にリクエストURI以外に用いたヘッダのリストを示す○WWW-Authenticateクライアントに対してリクエストの再発行を要求する。認証情報も含まれる○○
+ 一般ヘッダヘッダ概要HTTP/0.9HTTP/1.0HTTP/1.1Cache-Controlメッセージの経由する中間キャッシュの動作を指示する○Connection当該の接続に対するオプションを指示する○Dateメッセージの作成日時を示す○○Pragmaメッセージに関する追加情報を示す○○Trailerメッセージボディの後に追加のヘッダーが表れることを示す○Transfer-Encodingクライアントの転送を目的としたオブジェクトのエンコーディングを示す○Upgrade通信相手に別のプロトコルにアップデートするよう要求する○Viaプロキシサーバなど中継地点を示す。○Warningメッセージに関する追加情報を示す。通常はキャッシュの問題を警告するときに使われる○
+ エンティティヘッダヘッダ概要HTTP/0.9HTTP/1.0HTTP/1.1AllowオブジェクトがサポートするHTTPメソッドを示す○○Content-Encodingオブジェクトのエンコーディングを示す○○Content-Languageオブジェクトの言語(人間の言語)を示す○○Content-Lengthオブジェクトのサイズをバイト単位で示す○○Content-Locationオブジェクトの場所を示す○Content-MD5オブジェクトのメッセージダイジェストを運ぶ△Content-Rangeメッセージボディで運ばれるオブジェクトの範囲を示す○Content-Typeオブジェクトのタイプを示す○○Expiresオブジェクトの有効期限の日時を示す○○Last-Modifiedオブジェクトが最後に変更された日時を示す○○
Accept サーバのレスポンスに含まれるメッセージボディで受け入れることが出来るコンテンツタイプと各コンテンツタイプの相対的な優先度を指定するリクエストヘッダ。指定できるコンテンツタイプはIANAによって定義されている。 Accept: text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c
上記のようにAcceptヘッダには行をわけて複数のコンテンツタイプを指定できる。上記の例はいずれの4のコンテンツタイプのいずれも受け入れ可能であることを示す。0.5や0.8といった数字は品質係数で0〜1の範囲の数値である。数値の指定がなければ1.0となる。 text/plain; q=0.5 text/html text/x-dvi; q=0.8 text/x-c
Accept-Charset レスポンスで返されるメッセージボディの文字コードを指定するリクエストヘッダ。Acceptと同じく複数指定でき品質係数も設定できる。定義済み文字セットはIANAが管理している。
Accept-Charset: UTF-8, *; q=0.8 この例だとクライアントはUTF-8を優先的に希望しているが他の文字セットとの相対優先度0.8で受け入れている。ただしサーバからのレスポンスのHTTPヘッダそのものの文字コードは常にISO-8859-1である。
Accept-Encoding クライアントが受信できるメッセージボディのエンコーディングを指定する。
Accept-Encoding: gzip, deflate この例ではクライアントはgzip、またはzlibフォーマットに対応している。ただし必ずしもここで指定されたエンコーディングでメッセージボディが返ってくるとは限らない。 Accept-Encodingで指定可能なエンコーディングは、IANAがHTTP Content Coding Registryとして管理されているHTTP Content Coding Registry。
Accept-Language レスポンスの言語(人間の言語)に対する優先度を指定する。言語の指定にはIETF言語タグを用いる。書き方は他のAccept-群と変わらず。
Accept-Language: en-gb, en; q=0.8 上記の例はまずイギリス英語を要求し、利用できない場合はその他の英語を要求する。
Accept-Ranges Acceptで始まる他のヘッダフィールドと違いレスポンスヘッダである。現在の仕様では2つの指定方法しかない。
Age リソースの推定経過時間を表示するレスポンスヘッダ。キャッシュサーバーはAgeヘッダの値からキャッシュしたリソースが有効かどうかを判定する。
Allow
Authentication-info ユーザ認証のやりとりの最後で用いられる、成功したレスポンスのサーバが含めることの出来るレスポンスヘッダ。
Authorization サーバに対するクライアント自身の認証を行うことが出来る。
Cache-Control キャッシングの動作を指定するためのマスターヘッダ。
Connection 接続に対するオプションを指定する。その値には以下が使用される。 keep-alive 持続的接続を行う。 close 持続的接続を行わない。 upgrade 他のプロトコルへのアップグレードを希望する。
Content-Encoding
Content-Language リソースの表現に用いられる言語の明示に使われる。言語の指定はAccept-Languageヘッダと同じ。
Content-Length
Content-Location
Content-MD5 メッセージボディが変更されず宛先に届いたことの保証に用いる。MD5によるハッシュ値をヘッダー値に記載する。ただし悪意の改ざんに対しては当然MD5も改ざんされるのであまり機能はしない。どちらかといえば偶発的な変化が生じていないことの保証をしている。で廃止された。
Content-Range ダウンロードの再開に用いられる。
Content-Type
メッセージボディに含まれるオブジェクトタイプを示す。次の例はリソースがテキストファイル、文字セットはISO-8859-4を使用していることを示している。 Content-Type: text/plain; Charset=ISO-8859-4
Cookie
クライアントがHTTP状態管理を望む場合にサーバから受け取ったクッキーを以後のリクエストに次の例のようなヘッダを付加する。 Cookie: $Version="1"; NAME="VALUE"; $Path="/shopping"; $domain="www.shop.com"+ $Port="80" $VersionはHTTPのバージョン、NAMEはクッキーの名前である。$から始まるクッキー名は使用が禁止されている。
Cookie2 基本的にCookieヘッダとCookie2ヘッダは別物である。
Date サーバがメッセージを生成した日時を示す。リソースの更新日時を示すLast-Modifiedヘッダとは別である。