Hypertext Transfer Protocol

Hypertext Transfer Protocol（ハイパーテキスト・トランスファー・プロトコル、略称 HTTP）とは、HTMLなどのコンテンツの送受信に用いられる通信プロトコルである。主としてWorld Wide Webにおいて、WebブラウザとWebサーバとの間での転送に用いられる。日本標準仕様書ではハイパテキスト転送プロトコルとも呼ばれる。 HTTP/1.1 が RFC 7230 から RFC 7235 で規定されている。かつては RFC 2616 が HTTP/1.1 を規定していたため、こちらもよく参照されている。また、HTTP/2が RFC 7540 で規定されている。 名前の通り、 HTML (HyperText Markup Language) や XML (Extensible Markup Language) によって記述されたハイパーテキストの転送を主な目的としているが、それ以外にも、バイナリ形式の画像、音声を含め、様々なデータを扱うことが可能である。その汎用性からセンサーからの定期的なデータの取得などにも用いられる。 トランスポート・プロトコルとして通常TCPを使用する。 HTTPはリクエスト-レスポンス型のプロトコルであり、クライアントがサーバにリクエストメッセージを送信する。 基本的な考え方は非常に単純で、「何を」「どうして」欲しいのかを伝える。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では複数データを効率よく転送するための持続的接続や、プロキシの利用等も想定した仕様になった。 このほかの点を箇条書きで示す。 ポート番号80をデフォルトとして使用する。 TLSで暗号化され、セキュリティを確保したHTTPは、HTTPSと呼ばれる（httpsは実際にはURIスキームの1つであり、実際のプロトコルにはHTTP over SSL/TLSが用いられる）。 HTTP は基本的にサーバが状態を保持しない (stateless) プロトコルだが、データベースなどを使用するWebアプリケーションにおいては状態保持が必要だったため、いわゆる Cookie（クッキー）とよばれる機構が Netscape Communications Corporation によって導入された。Cookie を使用することによって状態を管理し、"セッション" を維持することが可能になる。 HTTPの拡張プロトコルとしてWebDAVがある。 UPnPでは、HTTPをUDP上で使用するHTTPUや、マルチキャストで使用するHTTPMUが規定された。 行末文字はCRLFで、インターネット・プロトコル・スイートにおいてアプリケーション層に属する他の多くのプロトコルと同じである。 イギリスの物理学者ティム・バーナーズ＝リーは1990年末、ロバート・カイリューと共に初のWebブラウザとWebサーバを作成した。ブラウザには通信をするためのプロトコルが必要だったので、二人はHTTPの最初期のバージョンを設計した。 以来インターネットの大部分をHTTP通信が占めるようになり、1998年にはインターネット上の通信の75%がHTTPによるものになった。 最初期のHTTP/0.9の仕様書は紙に印刷すれば1枚で済むような非常に簡素なドキュメントであったが、2度のバージョンアップを経たHTTP/1.1の仕様書は実に176ページ近くの分量に膨れあがった。 1991年に最初にドキュメント化されたバージョン。メソッドは GET しかなかった。レスポンスは単純にドキュメントの内容を返してコネクションを切断するだけで、レスポンスコードの規定もない。下記は、HTTP/0.9 のリクエストの例。 GET /index.html 1996年5月に RFC 1945 として発表された。仕様が RFC で扱われるようになった。メソッドに POST など GET 以外のものが増えた。レスポンスはヘッダーがつくようになり、ステータスコードを含めるようになった。HTTP/0.9 と区別するため、リクエストプロトコルにバージョンを含めることになった。 HTTP/1.0のリクエスト GET /index.html HTTP/1.0 1997年1月に RFC 2068 として初版が発表された。その後、2回改訂された。 名前ベースバーチャルホストをサポートした。インターネット人気に伴い多くの企業がWebサイトを持ち始めたが、当時はまだまだ企業が自前のWebサーバを運用するのは人員、効率の問題で難しく、ISPのサーバでホスティングをしていた。また、一社ごとに専用サーバを用意するほどのことでもないため、一台のサーバで複数のWebサイトを運用していた。 しかし、IPアドレスのみで相手を特定するHTTP/1.0はこれに対応できなかった。例えば、ある1台のサーバに foo.example.com と bar.example.com という二つの仮想Webサーバがあり、クライアントは http://foo.example.com/index.html にアクセスしたいとする。この場合はDNSサーバに foo.example.com のIPアドレスを問い合わせ、次にそのIPアドレスを使って該当サーバにアクセスし、GET index.html を要求することになる。しかし同じサーバ上にある bar.example.comもIPアドレスは同じであり、もし両方の仮想サーバに index.html というファイルが存在すれば、クライアントがどちらにアクセスしようとしているのか、判別できない。 対策としてはそれぞれにIPアドレスを付与する方法もあるが、IPv4の資源を無駄にすることになる。この問題を解決するため、Hostヘッダが追加された。 HTTP/1.1のリクエスト GET /index.html HTTP/1.1 Host: foo.example.com HTTP/2の目標はHTTP/1.1のトランザクション・セマンティクスとの完全な後方互換性を維持したまま非同期な接続の多重化、ヘッダ圧縮、リクエストとレスポンスのパイプライン化を実現することである。Googleによって立ち上げられ、GoogleのブラウザーであるChromeだけではなく、他にも、Opera、Firefox、Amazon Silk等が対応しているHTTP互換のプロトコルSPDYの人気が高まっていることに対応するために開発された。 HTTP-over-QUIC（hq）としてIETFの開発していた新たなプロトコルが、HTTP/3へと改名される。このプロトコルはUDPをベースにHTTP/2の一部の機能を組み合わせたものとなっている。IETFが策定を進めているQUICはトランスポート層におけるプロトコルの名称であるが、その中のHTTP-over-QUICとして定められるものを明確に区別する為、このような名称変更に至った。 他のプロトコル同様、クライアント側とサーバ側では役割が大きく異なる。HTTP通信を開始できるのはクライアント側のみである。 クライアント側がサーバにリクエストを送り、サーバがクライアントにレスポンスを返すのが最も典型的なHTTPのやりとりである。 システム間でメッセージをやりとりするにはTCP接続を確立させる必要がある。 HTTP/0.9ではクライアントのリクエストごとにTCP接続を確立させる必要があったが、これは当時のWebサイトがシンプルなテキストベースであることが多かったためである。近年ではJavaScriptやアニメーション画像など、多数のオブジェクトが埋め込まれたWebサイトが一般的となってきており、これらのオブジェクトを取得するたびにTCP接続を確立するのはサーバやネットワークに大きな負担を強いるため、HTTP/1.1では持続的接続がサポートされることとなった。ただし、この機能が利用できるのはサーバ側がその要求を許可した場合のみである。 クライアントは前のリクエストに対するサーバの応答を待たずに別のリクエストを発行できる。 HTTPでは8つのメソッドが定義されている。ただし、実際のHTTP通信ではGETとPOSTメソッドだけで殆どを占める。 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トンネルを接続する。暗号化したメッセージをプロキシサーバを経由して転送する際に用いる。 HTTPの仕様以外で定義しているメソッドは、IANAのHypertext Transfer Protocol (HTTP) Method Registryで管理されている。WebDavで使用するものや、 RFC 5789 のPATCHメソッドなどがある。 上記参照 別のURIに対して再度のメソッド実行を要求する機能である。301 Movedや303 See Otherなどのリダイレクトを指示するステータスコードとURIを受け取り、クライアントはこのURIに再度メソッドを実行する。 リクエストとレスポンスでやり取りされるデータは、HTTPメッセージと呼ばれる。 リクエストメッセージはリクエスト行・ヘッダーフィールド・ボディで構成され、レスポンスメッセージは、ステータス行・ヘッダーフィールド・ボディで構成される。ヘッダーフィールドとボディは空となる場合もある。 下にもっとも単純なクライアントとサーバ(www.google.co.jp:80)とのやり取りの例を挙げる。 クライアントのリクエスト: GET / HTTP/1.0 この例では、リクエスト行のみで、ヘッダーフィールドとボディは空となっている。 リクエスト行はメソッド、URI、HTTPバージョンの3つの要素から構成され、それぞれスペースで区切られる。 メソッドはGET、URIは「/」、HTTPバージョンは1.0である。 GETはリソースを取得するためのメソッドであり、URIの「/」はルートリソースを対象にしたリクエストであることを示している。 サーバのレスポンス: HTTP/1.0 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行目以降にヘッダフィールドが続く。 さらに空行を挟んで、レスポンスボディとなる。 ヘッダの各要素は フィールド名: 内容 のペアで構成される。 ブラウザの情報を表すUser-Agent、使用候補言語を表すAccept-Language、他ページへのリンクを辿った場合にそのリンク元ページのURLを表すRefererなどが代表的なフィールドである。 なお、リクエスト時のHostヘッダはHTTP/1.1では必須であるが、HTTP/1.0ではなくてもよい。 ただし、サーバがバーチャルホストを利用している場合は、Hostヘッダがないとリソース取得に失敗するので、たとえHTTP/1.0を使用していてもHostヘッダを付加しなければならない。 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として管理されている。 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 Content-Encoding Content-Language リソースの表現に用いられる言語の明示に使われる。言語の指定はAccept-Languageヘッダと同じ。 Content-Length Content-Location Content-MD5 メッセージボディが変更されず宛先に届いたことの保証に用いる。MD5によるハッシュ値をヘッダー値に記載する。ただし悪意の改ざんに対しては当然MD5も改ざんされるのであまり機能はしない。どちらかといえば偶発的な変更の保証をしている。RFC 7231 で廃止された。 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ヘッダとは別である。 HTTP/1.1では次のような形式を用いる。これはRFC 7231の7.1.1.1. Date/Time Formatsで定義されている。HTTP/1.1の以前の版であるRFC 2616では、日時の形式の定義にRFC 1123を参照していた（内容は同等である）。 Date: Sun, 06, Nov 1994 08:49:37 GMT HTTP仕様ではレスポンスにDateヘッダを含めることを求めている。ただしレスポンスのステータスがサーバエラーの場合にはDateヘッダは返らない。 ETag 主にキャッシングのパフォーマンスを向上する目的で使われる。 Expect サーバに対して特定の動作の期待を知らせる。用途としてはクライアントがサーバに対して100 Continueステータスを返すことを期待する場合に使われる。 Expect: 100-continue サーバが期待に応じられない場合は417 Expectation Failedを返す。クライアントがいくつかのプロキシ経由で通信している場合、各プロキシサーバはExpectヘッダの一切の修正を許されない。 Expires オブジェクトの有効期限を示す。このヘッダで指定された日時までキャッシュはレスポンスのコピーを保持し、リクエストに対するレスポンスとして返すことができる。サーバがオブジェクトのキャッシュを望まない場合にはExpiresヘッダに過去の日時を設定することが多い。仕様では1年以上先の日時は設定できない。 Expires: Thu, 28 Aug 2010 16:00:00 GMT Cache-Controlヘッダのmax-ageディレクティブはExpiresヘッダより優先されるため注意が必要である。 From リクエストを発行したユーザを特定することが出来る。1990年代では電子メールアドレスを設定することが多かったが、迷惑メールの問題もあり現在では殆ど使われていない。 From: user@example.com Host 主にレンタルサーバのサポートを目的としてHTTP/1.1で導入された。現在ではHostヘッダを利用できない場合、レンタルサーバのWebサイトとまともな通信ができないと言ってよい（詳細はHTTP#歴史を参照）。 If-Match ETagが一致した場合のみ、メソッドを実行するようにサーバに要求する。例えばウィキペディアを編集する際、記事のソースを取得し、書き換える際の間に別のユーザが既に編集していないかを判断するときなどに用いられる。 利用者：AがHTTPの記事を取得。ETagは1234。 利用者：BがHTTPの記事を取得。ETagは1234。 利用者：AがHTTPのETagを再度取得。先ほど取得したETag: 1234と現在のETag: 1234が一致。 利用者：AがHTTPの記事を編集。ETagは1256になる。 利用者：BがHTTPのETagを再度取得。先ほど取得したETagと現在のETagはマッチせず。 サーバは利用者：Bの書き込みを拒否。 If-Modified-Since 指定日時以降にオブジェクトが変更されている場合のみ、メソッドを実行するようにサーバに要求する。通信量の削減に効果がある。 If-None-Match If-Matchの逆で、ETagが一致しない場合のみの実行を要求する。 If-Range クライアントがキャッシュにオブジェクトの一部分を持っている場合にパフォーマンスを向上できる。 If-Unmodified-Since If-Modified-Sinceの逆で、指定時刻以降に変更がない場合のみの実行を要求する。 Last-Modified レスポンスでオブジェクトの最終更新日時を示す。リクエスト時のIf-Modified-Sinceヘッダと組み合わせることで、効率的な通信が可能になる。 Location サーバがクライアントにリダイレクト先URLを知らせる際に用いられる。一般的にステータスコードが3xx代のレスポンスと共に使われるが201 Createdのレスポンスでも使うことができる。Content-Locationヘッダと名前が似ているが全く関係のない別のヘッダであるため注意。 Max-Forwards プロキシサーバ等を経由する際の最大ホップ数を指定する。二重ループなどでサーバから応答が得られない場合の問題解決の際、OPTIONメソッドやTRACEメソッドと共に用いられる。 ステータスコードはサーバからのレスポンスで、リクエストの結果を通知する。3桁の数字から成り、おおまかな分類として、1xxは「情報」、2xxは「成功」、3xxは「リダイレクト」、4xxは「クライアントエラー」、5xxは「サーバエラー」を示す。 HTTP/1.1でBasic認証が定義されており最も単純なセキュリティ技術である。しかし仕様書を読むと定義を書いた著者自身が認証技術に疎いことがよくわかる[要出典]。「基本認証を用いるくらいならなにも使わない方がまし」と主張する人もいる。通常サーバはステータスコード401で応答する。 HTTP/2 HTTPステータスコード FTP WebDAV Webサーバ ウェブブラウザ アプリケーションサーバ Representational State Transfer (REST) HTTPヘッダ・インジェクション Hyper Text Coffee Pot Control Protocol バーチャルホスト ^ The HTTP Protocol As Implemented In W3 ^ Sebastian Anthony (2012年3月28日). “S&M vs. SPDY: Microsoft and Google battle over the future of HTTP 2.0”. ExtremeTech. 2014年9月23日閲覧。 ^ Jerome Louvel (2011年10月6日). “Can the rise of SPDY threaten HTTP?”. Restlet. 2014年9月23日閲覧。 ^ “Gigazine『UDPベースの「HTTP-over-QUIC」が新HTTPバージョン「HTTP/3」に名称変更される』”. GIGAZINE (2018年11月14日). 2018年11月14日閲覧。 ^ HTTP over QUIC 第16草案 ^ IETF Meetingの資料スライド ^ Hypertext Transfer Protocol (HTTP) Method Registry ^ HTTP Content Coding Registry ^ 『HTTPプロトコル―セキュア&スケーラブルなWeb開発』 Stephen Thomas 著、葛西 重夫 訳、ソフトバンクパブリッシング[要ページ番号] RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2) RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing HTTP/1.1 — RFC 7230 〜 7235 — 日本語訳 RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests RFC 7233 - Hypertext Transfer Protocol (HTTP/1.1): Range Requests RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching RFC 7235 - Hypertext Transfer Protocol (HTTP/1.1): Authentication RFC 2818 - HTTP Over TLS RFC 2817 - Upgrading to TLS Within HTTP/1.1 RFC 2616 - HTTP/1.1（RFC 2068の改訂版，RFC 7230 から RFC 7235 によって obsolete） ハイパーテキスト転送プロトコル -- HTTP/1.1 RFC 2068 - HTTP/1.1（初版，RFC 2616 によって obsolete） TS X 0085:2004 - ハイパテキスト転送プロトコル HTTP/1.1 日本標準仕様書(TS X 0085:2004) RFC 1945 - HTTP/1.0 The HTTP Protocol As Implemented In W3 - HTTP/0.9