Introduction of HTTP

この頁では、「そもそもHTTPとは一体どういう技術なのか?」という疑問を解消するために、HTTPの概要と、その発展の歴史について、解説します。

HTTP概論

この節では、HTTPが持つ機能と、HTTP通信における開始から終了までの流れを、HTTPの仕様書を読みながら解説します。 まず、HTTPに仕様書があるということはご存知でしょうか? 仕様書はこれまで何度か改訂されていますが、最新版はRFC 2616という文書で、IETFという団体が発行しています。

(※) HTTPそのものの仕様書はRFC 2616ですが、HTTPに関連するRFCは他にも存在します。 詳しくはRFC-Translations related HTTPをご覧ください。

HTTPが持つ機能

RFC 2616の概要に記述されている「HTTPの概要」をご覧ください。

ハイパーテキスト転送プロトコル (HTTP) は、分散・共同体ハイパーメディア情報システムのアプリケーションレベルプロトコルである。 このプロトコルは、リクエストメソッド、エラーコード、ヘッダ等の拡張を経て、ネームサーバや分散オブジェクト管理システム等、ハイパーテキストのために使う以上に多くの作業のために用いる事ができる、一般的でステートレスなプロトコルである。 HTTP の特徴として、データ表現のタイプ付け、及びネゴシエーションがあり、これによって転送されるデータの独立性が確立されるようなシステムが構築できる。

HTTPとは、正確には“HyperText Transfar Protocol”と書きますが、これはその名の通りハイパーテキスト(HTMLを用いて記述されたテキスト)を転送するためのプロトコルでした。 しかし、現在ではリクエストメソッドステータスコードHTTPヘッダなどを拡張することにより、「ハイパーテキストの搬送」以外の用途にも利用できる汎用的なプロトコルとして、WWWを支える最も重要な技術の一つとなっています。

(※) しばしば、「インターネット」と「WWW」は混同して使われます。 「インターネット」とは、全世界のネットワークを相互に接続した巨大なコンピュータネットワークであるのに対し、「WWW」とは、世界中に「蜘蛛の巣(web)」のように広がるコンピュータネットワーク、すなわちインターネット上に展開される情報提供システムのことを言います。

概要の中のステートレスという単語がありますが、これは「状態{State}」を保持しない{-less}という意味です。 ここでいう「状態」とは、「それ以前にどのようなリクエスト/レスポンスが発生していたかを認知しない」という意味です。 というのも、HTTPの元々の設計方針として、多くの処理を素早く、また確実な処理を実現するために、なるべく通信量を減らしたいという狙いがあったからです。

(※) HTTPの設計には、FTPも参考にしていますが、FTPは会話形式の通信を行うため、ステートレスではありません。

しかし、HTTPが爆発的に広まっていくと、状態がないことによる不便な点が見えてきたので、当時Webブラウザを開発していたNetscape 社によってクッキー(HTTP Cookies)という新技術が提案されたのです。 クッキーはとても便利であったため、Internet Explorerなどの他社のWebブラウザにも実装され、現在では多くのWebブラウザで利用できます。

文中には、データ表現のタイプ付けという表現が登場しますが、これはリソース(※)のメディアタイプを表します。 また、ネゴシエーションとは、最適なリソースを自動判別する機能で、HTTP/1.1に含まれています。

(※) ここでいう「リソース」とは、文書や画像などのファイル、あるいは動的に生成されるデータなど、HTTPレスポンスとして返されるあらゆる情報を指しています。

HTTP通信における開始から終了までの流れ

RFC 2616のsection 1.4には、HTTP通信の概要が記述されています。

HTTP プロトコルはリクエスト/レスポンスプロトコルである。 クライアントは、サーバへの接続上で、リクエストメソッド、URI、そしてプロトコルバージョン、その後にリクエスト修飾子、クライアント情報、可能であれば内容本体を含んだ MIME-like メッセージ形式をサーバにリクエストとして送る。 サーバは、メッセージのプロトコルバージョンと成功か失敗を表すコードを含むステータス行に続き、サーバ情報、エンティティメタ情報、可能であればエンティティボディの内容を含む MIME-like メッセージで応答する。 HTTP と MIME の関係は、付録 19.4 に記述されている。

HTTP通信は、以下の図のように、HTTPクライアントからのリクエストと、それに対するHTTPサーバからのレスポンスから成ります。

図 HTTP通信(リクエストとレスポンス)

リクエストには、HTTPメソッド, リクエストURI, クライアントが対応するHTTPバージョン, さらにリクエスト用のHTTPヘッダメッセージボディが送られます。 それに対して、レスポンスでは、サーバが対応するHTTPバージョン, ステータスコードとその説明句, その後にレスポンス用のHTTPヘッダメッセージボディが送られます。

HTTP 通信は、普通 TCP/IP 接続上で行う。 既定ポートは TCP 80 であるが、他のポートを使用する事もできる [19]。 これは、インターネットや他のネットワーク上の別のプロトコルの最上部として、HTTP を実装する事を排除しない。 HTTP は確実な転送のみを前提し、そのような保証を供給するどんなプロトコルでも使用できる。 問題においてプロトコルのデータ転送ユニット上の HTTP/1.1 リクエストとレスポンス構造のマッピングはこの仕様書の範疇を超える。

HTTP/1.0 では、ほとんどの実装はそれぞれのリクエスト/レスポンスを交換するために新しい接続を使用していた。 HTTP/1.1 では、接続は一つ以上のリクエスト/レスポンス交換に使用できるが、レスポンスの種類によっては接続が切断されるかもしれない (section 8.1 参照)。

HTTPというプロトコルは、一般的にTCP/IP上で使用します。 たとえば、下の図は「Ethernet+TCP/IPという環境でHTTPを利用する」といったケースにおける、プロトコルスタックとOSI7層構造モデルの対応を表したものです。

図 HTTPアプリケーションのプロトコルスタック

HTTPのためのポート番号として80番が予約されていますが、それ以外の番号を使用することもできます。 たとえば、80008080などがテスト用としてしばしば利用されています。

HTTPにおける『接続』状態とは、一言でいうと「クライアント-サーバ間でTCP接続が確立されている状態」であり、そのようなTCP接続を確立するプログラムのことをクライアントと呼びます。 HTTP/1.0では、リクエスト毎にクライアントからサーバへTCP接続要求が出され、レスポンス完了後にその接続を終了するという手段を取っていましたが、TCPはコネクションを貼るのに時間がかかるという欠点があり、この際に費やされる時間や資源を節約するために、一つのTCP接続で複数のHTTP交信を行えるようにするための持続的接続が開発されました。 HTTP/1.1では持続的接続が既定の動作となっています。

HTTP通信におけるセキュリティリスク

昨今、Webからの個人情報の流出が問題となっていますが、Webの通信プロトコルであるHTTPを利用することによって、個人情報が流出してしまうリスク、およびその場合の被害について、RFC 2616のsection 15.1に記述されています。

HTTP クライアントはしばしば多くの量の個人情報 (例えばユーザの名前、場所、メールアドレス、パスワード、暗号キー、等々) を管理しているので、この情報を HTTP プロトコル経由で他のリソースへと知らないうちに漏洩していないように特に気をつけるべきである。 我々は、ユーザがそのような情報の公開についてを制御するための便利なインタフェースが提供される事と、設計者や実装者はこの部分を特に注意する事を特に強く推奨する。 歴史的に、この部分のエラーがしばしば深刻なセキュリティやプライバシー問題を引き起こし、その結果実装者の会社に対して不利な評判を高めている。

HTTPクライアントは、デフォルトの設定で、ユーザの入力量を削減するために、ユーザの名前、場所、メールアドレス、パスワード、暗号キーなどを保存しています。 そのため、以下のようなセキュリティリスクが常に存在します。

図. HTTP通信におけるセキュリティリスク

このようなリスクを低減するためには、HTTPアプリケーションの作者が、常にセキュリティ情報を収集し、注意すべきことはもちろんですが、そのHTTPアプリケーションを使用するユーザも同様にセキュリティに関心を持つ必要があります。

HTTPの歴史とバージョン番号

RFC 2616のsection 1.1では、HTTPの改良の歴史について述べられています。

ハイパーテキスト転送プロトコル (HTTP) は、分散・共同体ハイパーメディア情報システムのアプリケーションレベルプロトコルである。 HTTP は、World-Wide Web グローバル情報利用の先進として、1990 年から使われている。 HTTP の最初のバージョンは、HTTP/0.9 と呼ばれ、インターネットを通じて未加工のデータを転送するための単純なプロトコルであった。 HTTP/1.0 は、RFC 1945 にて定義され、転送されるデータに関する外部情報とリクエスト/レスポンス意味論の修飾子を含んだ MIME のようなメッセージ形式のメッセージを付加する事によってプロトコルを改良した。 しかし、HTTP/1.0 ではプロクシやキャッシングの階層構造、持続的接続の必要性、仮想ホストへの考慮が十分になされていなかった。 さらに、実装が不完全なのに自身を "HTTP/1.0" だと称するアプリケーションの増加で、互いの通信アプリケーションが互いに真の能力を決定するために、プロトコルバージョンを変更する必要性が出てきた。

この仕様書では、"HTTP/1.1" と呼ばれるプロトコルを定義している。 このプロトコルはそれらの特徴の確実な実装を保証するため HTTP/1.0 よりも厳格な要求を含んでいる。

それでは、HTTPの歴史を順を追って見ていきましょう。

WWWの誕生 〜 HTTP/0.9

1989年、CERN(セルン; ヨーロッパ原子核研究機関)の物理学者Tim Berners-Leeによって、WWWというシステム(※)が提案されました。

(※) 今日では、しばしば“インターネット”と“WWW”は混同して使われますが、“インターネット”とは「全世界のネットワークを相互に接続した巨大なコンピュータネットワーク」を指すのに対し、“WWW”とは「世界中に『蜘蛛の巣(web)』のように広がるコンピュータネットワーク」=「インターネットを利用した情報提供システム」のことを指します。

WWW誕生以前は、ネットワークを介した情報のやりとりにはFTPが使われていました。 FTPとは“File Transfer Protocol”の略で、ファイルやディレクトリについての決まりを共通化し、インターネット上でファイルを転送するためのプロトコルで、その仕様はRFC 0959に記述されています。 一般に、ftpを使用するためには、ネットワーク管理者に依頼し、ホストコンピュータへのログインとアクセスの権限を与えてもらう必要があり、面倒でした。

(※) 慣習として、“FTP”と大文字で書くとFTPプロトコルを意味し、“ftp”と小文字で書くとFTPを扱うためのソフトウェアを意味します。 FTPを行うためにはftpクライアントが必要ですが、最近では代表的なWebブラウザにもftpクライアント機能が実装されています。

そこで、Berners-Leeが、文書を転送するためのプロトコルとして、「簡易版FTP」とも言うべきHTTPの仕様を作り上げました。 同時に、文書同士をリンクするための記法であるHTMLや、文書の場所を表すための記法であるURLについても考えられ、それらを組み合わせたリソースの分散システムこそがWWWなのです。

この時に作られた、HTTPの最初のバージョンをHTTP/0.9と呼ぶことがありますが、これには正式な仕様書がなく、「HTTP/1.0以前のHTTP」という意味で便宜的につけられた呼び名です。 HTTP/0.9では、メソッドはGETしかなく、リソースに関するメタ情報を転送するためのHTTPヘッダは一切存在しません。

(※) 同様に、最初のバージョンのHTMLをHTML 1.0と呼ぶことがありますが、これも正式な名称ではありません。

HTTP/1.0

WWWが初めてインターネット上に登場したのは1991年のことですが、1993年になって、このWWWというシステムを一気に世に広めた事件が起こりました。 1993年2月、イリノイ大学のNCSA(国立スーパーコンピュータ応用センター)にいたMarc AndreessenらがNCSA MosaicというWebブラウザを発表したのです。 Mosaic発表以前も、Berners-Lee本人による世界最初のWebブラウザ「WorldWideWeb」などをはじめ、いくつかのWebブラウザが公開されていたのですが、どれも文字情報だけしか扱えませんでした。 しかし、Mosaicは「インラインイメージ」、すなわちブラウザ内に画像を表示するという、当時としては画期的な機能を実装していたため、世の中のWebブラウザは一気にMosaicに置き換わってしまったのです(※1)。

(※1) この当時は、「Webを閲覧する」ことを「Mosaicする」と表現するくらい、多くの人がMosaicというWebブラウザを利用していたと言われています。

翌年(1994年)、Mosaicの開発元であるNCSAと権利関係で対立したMarc Andreessenは新しく会社を興し、Netscape Navigatorという新しいWebブラウザをリリースしました。 そして、今度はこのNetscape NavigatorがWebブラウザ界を独占してしまったのです(※2)。

(※2) Netscape Navigatorは日本でも大ヒットし、「ネスケ」の愛称で親しまれました。

一方、1995年には、WWWに興味を持ったMicrosoft社が、Mosaicを元にInternet Explorer(MSIE) というWebブラウザを開発し、市場に投入しました。 この時期には、WWWの利用が爆発的に広がり、俗に「第一次ブラウザ戦争」と呼ばれる“Netscape vs MSIE”の闘いが数年にわたり繰り広げられることになります。

WWWがまさに激動の変化を迎えている一方で、WWWの根幹を支えるプロトコルであるHTTPにはまだ「正式なプロトコルの仕様書」というものがありませんでした。 また、この時点で提案されていた「暫定版のHTTP(HTTP/0.9)」は、爆発的に広まるWWWで利用するには、あまりにも非力だったのです。 そこで、正式なHTTPの最初のバージョンHTTP/1.0を作るべく、議論がなされることになりました。

一つの例を挙げると、HTTP/0.9では、そこにある「リソースそのもの」を取得することしかできません。 そのため、このリソースに関連する情報を取得したい場合、あるいはクライアント側の情報を伝えたい場合にはどうすればよいのかについて議論が起こりました。 HTTP/1.0開発初期においては、これらをHTTPメソッドを用いて取得しようとするアイデアもありましたが、議論の結果、電子メールのアイデアを借りて、HTTPヘッダというものを使って対応することになりました。

このように、あらゆる角度から多くの議論が重ねられ、1993年3月にHTTP/1.0の最初のドラフトが作成され、それから3年後の1996年5月、ついにRFC 1945として、HTTPとしては初めての「正式なプロトコル仕様書」が発行されたのです。

HTTP/1.1

やっとのことで発行されたHTTP/1.0の仕様書ですが、このRFCは“Informational(情報提供)”として発行されている点に注意して下さい。 これは、各HTTPベンダ(HTTPアプリケーションを提供する会社・団体)が、HTTP/1.0の正式な仕様が成立する前に、それぞれ機能を独自に実装をしてしまったせいで、同じ「HTTP/1.0対応」を謳うアプリケーション間で大きく動作上の差異が生じてしまい、「相互動作性を満たす」とは言えない状況になってしまったためです。

そこで、HTTP/1.0を更に発展させ、また文字通り「HTTPの標準仕様」を確立するために、1997年1月に、RFC 2068という仕様書が発行されました。 これは、Standards Trackという、インターネットの標準化を目指すRFCとして登録されています。

HTTP/1.0は、シンプルで、かつ安定したプロトコルでしたが、HTTP/1.1では仕様そのものが厳格になり、また持続的接続仮想ホスト(バーチャルホスト)チャンク形式エンコーディング内容ネゴシエーション(コンテントネゴシエーション)などの多くの新しい機能が追加されました。

特に注目すべき機能は、持続的接続です。 1990年代の通信環境は、現在のように高速回線が使えたわけではないので、通信速度を上げるためにいかに通信上の混雑を減らすかが課題でした。 Netscape社はブラウザだけでなく、サーバも開発していたので、自社のブラウザやサーバに一度確立したTCP接続を使いまわすという機能を実装しました。 この機能こそが持続的接続であり、実際に利用され始めると、大変有用であることがわかり、他社のWebブラウザや、Webサーバにも実装され、その結果HTTP/1.1では必須機能となったのです。

HTTP/1.1アプリケーションは、HTTP/1.0よりも数段複雑な動作が要求されます。 したがって、HTTPでは、そのアプリケーションが従うプロトコルバージョンを厳密に宣言しておかないと通信が成立しなくなってしまう可能性があります。 そこで必要となるのが、HTTPバージョンです。 このHTTPのバージョン番号の付け方については、RFC 2616のsection 3.1に記されています。

"HTTP/1.1" という HTTP-Version を含むリクエストやレスポンスメッセージを送るアプリケーションは、少なくとも条件付きでこの仕様書に準じていなければならない。 少なくとも条件付きでこの仕様書に準じているアプリケーションならば、送信するメッセージに "HTTP/1.1" という HTTP-Version を含めるべきであり、HTTP/1.0 と互換性の無い全てのメッセージには、必ず含めなければならない。 特定の HTTP-Version を送る時についての詳細は、RFC 2145 参照。

アプリケーションの HTTP バージョンとは、そのアプリケーションが少なくとも条件付きで準じている最も高い HTTP バージョンの事である。

プロクシやゲートウェイなどのアプリケーションは、プロトコルにおけるアプリケーションのバージョンの違うメッセージを転送する時に注意する必要がある。 プロトコルバージョンは送り手のプロトコル能力を示すので、プロクシ/ゲートウェイは、決して自身の実際のバージョンよりも大きなバージョン指標が付いたメッセージを送ってはならない。 もし、より高いバージョンのリクエストを受けたならば、プロクシ/ゲートウェイはリクエストのバージョンを下げるか、エラーを返すか、トンネル動作にスイッチするかのいずれかを行わなければならない

RFC 2068 の発行以降に HTTP/1.0 プロクシの通信上の問題が発見された事を受けて、キャッシュするプロクシは、必ずサポートする最新のバージョンにアップグレードしなければならない。 ゲートウェイは、可能であればアップグレードしてもよい。 またトンネルは、アップグレードしてはならない。 そのリクエストのプロクシ/ゲートウェイのレスポンスは、リクエストと同じメジャーバージョンでなければならない。

注: HTTP のバージョン間の変換は、含まれるバージョンによって要求される、あるいは禁止されるヘッダフィールドの修正を含んでいてもよい。

HTTP-Versionは、そのメッセージに使われている技術のバージョンではなく、「送信アプリケーションが理解できる最新のHTTPバージョン」を意味します。 もし、HTTP/1.1をサポートしていないアプリケーションが、HTTP-Versionに“HTTP/1.1”を使用して、HTTP/1.1アプリケーションと通信した場合、相手側は「HTTP/1.1の技術が使用できる」と考え、HTTP/1.1に依存した技術を使用するはずです。 しかし、その中にHTTP/1.1をサポートしていないアプリケーションが理解できない機能があると、通信に失敗を起こすことになります。 よって、安易にHTTP/1.1を名乗ってはいけないのです。

HTTP/1.1でサポートが必須とされる機能には、たとえば以下のようなものがあります。 これらの条件を満たさないアプリケーションは、「HTTP/1.1アプリケーション」を名乗ってはいけません。

特に、プロクシは、クライアントサーバの両方の性質を持つので、クライアントとサーバのそれぞれのHTTP/1.1従順性{compliance}を満たしていなければ、HTTP/1.1プロクシを名乗ってはいけません。 プロクシが、自身のプロトコルバージョンより高いHTTPメッセージを受け取った場合は、以下のいずれかの対応を取らなければいけません。

また、HTTP/1.1は、厳密にはHTTP/1.0の上位互換ではありません。 section 19.6をご覧下さい。

前のバージョンに従うように指示する事はプロトコル仕様書としての範疇を超える。 しかしながら、HTTP/1.1 は前のバージョンを簡単にサポートさせられるように慎重に設計された。 この仕様書を作った時 (1996) に、我々が HTTP/1.1 サーバに以下を期待していたであろう事に注目する価値はある。

また、我々は HTTP/1.1 クライアントには以下を期待していたであろう事に注目する価値はある。

多くの HTTP/1.0 実装では、それぞれの接続はリクエストの前にクライアントによって確立され、レスポンスを送った後にサーバによって切断される。 実装の中には RFC 2068 [33] の section 19.7.1 中に記される Keep-Alive バージョンの持続的接続を実装しているものがある。

上記の通り、HTTP/1.1アプリケーションは、厳密にHTTP/0.9やHTTP/1.0のすべてを解釈できる必要はありません。 RFC 2616がこのように記述された理由としては、過去のHTTPに関するRFCなどの中で、定義はされたもののほとんど利用されずになくなったメソッドやヘッダフィールドなどについて、HTTP/1.1アプリケーション(特にサーバ)がそのすべてをケアする必要は無いという意図が読み取れます。

(※) ただし、HTTPメッセージの基本的なフォーマットや、よく使われるメソッドやヘッダフィールドの定義などは、HTTP/0.9からほとんど変わっておりません。 その意味で、HTTPは基本的に上位互換であるということはできます。

HTTP/1.2, HTTP-NG の開発中止と HTTP/1.1 の改訂

RFC 2068 の発行以降も、HTTP の改良のための議論は続けられました。 たとえば、1996 年 6 月にカナダのモントリオールで行われた、第 36 回 IETF meeting では Extensibility for HTTP/1.2 というプレゼンテーションが行われ、その中でユーザエージェントを振り分けるための UA-* ヘッダを用いた内容ネゴシエーション (コンテントネゴシエーション)等が提案されています。

(※) UA-* ヘッダは MSIE 3 にて一時実装されていましたが、現在は利用されていません。

RFC 2068が完成した1997年以降は、HTTPの次世代バージョンをHTTP-NGと呼び、同年7月にはHTTP-NG Working GroupというワーキンググループがW3C内に設置され、HTTPの更なる発展に向けて様々な議論が行われていきました。 HTTP-NGの構想は実はW3Cの初期の頃からあって、たとえば1995年にProgress on HTTP-NGという文書が記述されています。 HTTP-NGでは、たとえばリソース提供の自動化やキャッシュ制御メカニズムといった「HTTPそのものの改善」というよりも、アプリケーション層より下位の層(TCP/IP)についても含めた「HTTPの通信全体についての議論」を行っており、たとえばTCP以外のプロトコルをサポートできるようにすることも考えられていました。

HTTPそのものの発展については、リソース提供の自動化やキャッシュ制御メカニズムといった個別の要素技術を、モジュール的に組み込むことができるように、新たにPEPというプロトコルを作り、その枠組みを利用してHTTP/1.xの開発を行おうと考えました。 しかし、既存のHTTP/1.1の仕様は、進化の過程の中であまりにも膨大かつ複雑になっていたため、それら個別の議論をモジュール的に組み合わせて仕様を完成するという目論見は、結局失敗してしまいました。 個別で議論されていた各技術は、HTTP/1.1を改訂したRFC 2616の中に組み入れられることで反映されました。

ちなみに、HTTPのメジャーバージョンとマイナーバージョン番号の付け方の決まりも、RFC 2616のsection 3.1に規定されています。

HTTP では、プロトコルのバージョンを示すために "<メジャーバージョン>.<マイナーバージョン>" と番号づける。プロトコルバージョンのつけ方の方針としては、その通信で得られたものの特徴を伝えるというよりも、送信者がメッセージのフォーマットや将来的な HTTP 通信においての理解能力を表すために使わせようとするものである。 通信の振る舞いが影響を受けないメッセージの構成要素が追加されたり、拡張可能なフィールドの値が追加されるような場合ではバージョン番号は変更されない。 <マイナー> バージョンは、その変更が、一般的なメッセージ解析アルゴリズムを変えるものではないが、メッセージ意味論を付け加え、送信者の機能に追加があった事を意図する時に、上がる。 <メジャー> バージョンは、プロトコル内のメッセージのフォーマットが変更される時に、上がる。完全なる解説を必要とする場合は RFC 2145 参照。

RFC 2068からRFC 2616への変更点は、RFC 2616のsection 19.6.3にまとめられています。 ステータスコードHTTPヘッダ内のパラメータに一部追加があるものの、送信者の機能に追加があった事を意図するとは認められなかったようで、結局HTTPのバージョンは“1.1”のまま変更されませんでした

WebDAV(HTTP/1.1の拡張)

「WebDAV」に関するお薦め書籍

WebDAVとは“Web-based Distributed Authoring and Versioning”の略です。 HTTPは、元々ファイルを簡単に「配布する」ことを目的に開発されたプロトコルですが、WebDAVは、Web上で「データの編集や管理を行う」という仕組みをHTTPに組み込もうという取り組みであり、その考え方はかなり異なっています。

しかし、HTTPの歴史を振り返ってみると、WebDAVのような考え方というのは、実はWebが誕生した当初からありました。 メソッドについても、HTTP/0.9ではGETしかありませんでしたが、1991年にTim Berners-Leeによって書かれたHyperText Transfer Protocol Design Issuesという文書では、リソースの更新時刻を尋ねるためのSINCEや、受け入れ可能なフォーマットを示すためのACCEPTというメソッドが提案されています。 現在のHTTPでは、これらのデータはメソッドではなく、HTTPヘッダによってやり取りできるようにいます。 これにより、1つのHTTPメッセージ(リクエスト/レスポンス)に複数のHTTPヘッダを付加することができ、そのリソースに関するメタ情報を一度に引き出す事ができるようになっています。

その後、1992年に設計されたHTTP/1.0の初期バージョンでは、PUTDELETEといった、HTTP/1.1で採用されたメソッドに混ざって、CHECKOUTCHECKIN, SEARCHといった、現在WebDAVで提案されているメソッドも見られます。 これらは明らかに、WWWを「サーバからクライアントへの単なるリソース配布するためのもの」から、「WWW上でリソース編集を行うためのもの」にする狙いが読み取れます

この「データ編集・管理のための仕組みを HTTP に組み込む」という考え方は、PUTDELETEという形でHTTP/1.1 (RFC 2068) に盛り込まれましたが、それ以外の機能を盛り込むためにHTTP/1.1をどのように拡張するかといった指針などがRFC 2291という文書に記述され、WebDAVそのものの仕様書もRFC 2518として発行されました。 WebDAVは、HTTP/1.1を拡張したプロトコルであり、HTTPメッセージ中のバージョン番号は“HTTP/1.1”を使用します。

WebDAVの登場は、HTTP/1.1の改訂作業と同時期であり、一時は「Web上の共同作業を実現するために、将来的にはHTTP/1.1を置き換えていくプロトコルである」として注目された時期もありましたが、結局「POSTリクエストに同封されたデータを、CGIなどを利用して外部アプリケーションに渡す事で、データの書き換えを実現する」というHTTP/1.0当時から長く使用されている手法に取って代わることはありませんでした。 とは言え、WebDAVの仕様書であるRFC 2518も、現在はRFC 4918として改訂されていますし、またWebDAVに関連する仕様書は現在も多数発行されています。

HTTP通信をセキュアにする試み

HTTPを使って様々な情報をやり取りされるにしたがって、HTTP上を流れるデータを安全に転送したいというニーズが出てきました。 というのも、HTTPは平文を転送するため、通信途中で傍受された場合、その内容が筒抜けになってしまうからです。

HTTP通信をセキュアにする仕組みとして、初期に有力視されていたものにS-HTTPがあります。(※) S-HTTPとは、Enterprise Integration Technologies社によって開発されたプロトコルで、暗号化アルゴリズムによってデータを暗号化するので、平文でデータをやり取りするHTTPに比べて、パケット盗聴などに対するセキュリティが向上します。

(※) 1992年に記されたHTTP/1.0のセキュリティに関する考察の中に、“S-HTTP”の文言を見つけることができるところからも、S-HTTPがHTTP初期から注目されていたことをわかるでしょう。

一方、1994年頃から、Webブラウザ会社であるNetscape社が、自社製の「Netscape Navigator」というWebブラウザのためにSSLというセキュアプロトコルを設計しました。 S-HTTPは「HTTP上で送信されるデータを暗号化する」のに対し、SSLは「HTTPが流れる通信経路そのものを暗号化する」という方法をとります。 そのため、SSLは、HTTPだけでなくFTPなど別のプロトコルでも使用できるのがメリットです。

S-HTTPとSSLのどちらも、1990年代後半にかけて、よりセキュリティの高いプロトコルとすべく、仕様を改善していきました。(※※) しかし、結局はNetscape社と、Internet Explorerを開発するMicrosoft社が進めたSSLがこの戦いに勝ち、いまやS-HTTPを実装するHTTPアプリケーションはありません。 一方、SSLは一私企業による暗号技術から、TLSというオープンな暗号標準に生まれ変わり、誰もがフリーにこの技術を使うことができます。

(※※) S-HTTPの最新仕様(バージョン1.4)は、RFC 2660で見ることができます。 また、SSL/TLSの仕様の変遷は、SSL/TLSの歴史を参照ください。

SSL/TLS」に関するお薦め書籍

HTTPでSSL/TLSを利用する場合には、二つの方法があります。

専用のポート番号(一般には443)を使う方法
これは元々Netscape社によって提案された方法です。 先に述べたとおり、SSL/TLSは、任意のアプリケーション層プロトコルに対して使用することができますが、HTTPに対して使うものはHTTPSと呼ばれ、RFC 2818にその使い方が記されています。
通常のポート(一般には80)で通常のHTTP通信を行った後に、SSL/TLSに切り替える方法
これは、Upgradeヘッダを使って、通信プロトコルをHTTP→HTTPSに切り替えるというもので、IETFはこの方法を推奨しています。 このやり方もRFC 2817というRFCになっており、この文書の中でステータスコード426などのHTTP/1.1の拡張を行っているため、RFC 2616を一部「更新{Update}」する文書となっています。(※※※)

(※※※) RFC 2817は、RFC 2616の内容の一部を置き換えただけなので、現在も「最新のHTTP/1.1仕様書」という位置付けの文書は、RFC 2616のまま変わっておりません。

HTTP/1.1, 2度目の改訂へ

RFC 2616が登録された後、前述の「PEPとして議論されていた枠組み」、すなわちHTTP拡張を定義するための共通の枠組みは、HTTP拡張フレームワークという名前で、2000年2月にRFC 2774という文書にまとめられました。 これにより、W3CにおけるHTTPの開発活動は一旦終了します。

しかし、RFC 2616中には誤字がいくつもあったり、また仕様上の不具合などがいくつも発見されているため、それらを修正すべきとの声が日に日に高まってきました。 そこで、W3Cはそれらを修正するために、2006年10月よりHTTP Activityを再始動しました。 再始動直後の声明では、HTTP/1.1の改訂版は2008年10月にIESGに提出されると宣言していましたが、2012年3月現在はまだドラフト第19版が公開されているだけで、完成には今しばらくの時間がかかる模様です。

その一方で、2012年になると、現状のHTTP/1.1でデファクトスタンダードになっていた運用を明文化するという意味で、RFC 6266RFC 6585が立て続けに公開されました。 今後もこのような作業は続いていくことでしょう。

HTTPを通信層として利用する技術

HTTPは、WWWの根底を成すプロトコルとして、世界中に広く知れ渡っています。 HTTPは、基本的な機能のみを利用するのであれば非常にシンプルなプロトコルであり、またすでに10年以上利用されている安定したプロトコルです。 そのため、近年ではデータ通信のためのプロトコルとしてHTTPを利用しつつ、データ処理を行うような考え方や技術がいくつも提案されてきました。 本節では、そのようなもののうち、代表的なものについて記述します。

XML-RPCとSOAP

上述のHTTP-NGが目指したものの中には、HTTPをRPCのように利用できるようにしたいという考えが含まれていました。 これについては、W3C内のShort- and Long-Term Goals for the HTTP-NG Projectという文書の中に記されています。

今日のWebでは、その利用の多くが、より一般的な分散アプリケーションの性質を持って広がってきているが、それはしばしば不必要なパフォーマンスコスト、機能的欠点、一般的結果の欠如を含む形で、HTTP上に配置されている。 Webを一般的な分散オブジェクトシステムの基盤へと変えることによって、我々はこれらのアプリケーションが一般的なオブジェクトシステムを直接使用することができるようにしたいと思っている。 特に、その一般的な分散オブジェクトシステムが CORBA, DCOM, Java RMI の意味的及び性能的必要条件を満たす程度にシンプルで、かつ過剰すぎないようにしたいと思っている。 これは、我々が (様々な性質及び欠点を持っている) CORBA, DCOM, Java RMI のオブジェクトモデルを統一するつもりであるということを意味しない。 それは、我々が類似した長所を持つ一般的な分散オブジェクトシステムをHTTP上に持ちこみたいということ、そしてそのような環境に切り替えたいと思っているプログラマ(さらにミドルウェアを所有する組織)がおよそ同じ仕事を(少なくとも)させることができるということを意味する。

RPCとは、元々Sun Microsystems社によって開発された技術で、日本語訳すると「遠隔手続呼出」となります。 文字通り「遠隔(リモート)」のマシン上にある「手続き(サブルーチン)」を「呼び出す」ための仕組みです。 RPCに相当する技術は、既にいくつも存在しており、たとえばCORBA, DCOM, Java RMIなどがありますが、HTTP-NGはそれらを完全に置き換えることを目的にしたわけではなく、あくまでWeb上から簡単にそれらと同じような使い方ができるものを開発したいという考えがありました。

1998年、Dave Winerという人が、RPCをWebで行うための技術であるXML-RPCという仕様を発表しました。 XML-RPCとは何かについて、公式ホームページの中に、その名もズバリ“What is XML-RPC?”という節がありますのでご覧ください。

XML-RPC、それは異なるOS上で動作し、あるいは異なった環境で動作しているソフトウェアが インターネット上で手続きの操作できるようにする仕様及び実装の集合である。

またそれは、転送方式としてHTTPを使用し、符号化方式としてXMLを使用しているRPCである。 XML-RPCは、複雑なデータ構造を転送し、処理し、返すことができるように、できるだけシンプルに設計されている。

XML-RPCとは、HTTPとXMLを使用した非常にシンプルなRPCで、現在でも利用されています。

その後、XML-RPCに新たな機能を追加するべく、DevelopMentor, Microsoft, Userland Software の3社が仕様をまとめあげたのがSOAPというプロトコルです。 彼らは、1999年9月にSOAP 0.9を公開するところから始まり、同年中にSOAP 1.0の仕様を公開、その後の標準化作業はW3Cに移され、2000年5月にSOAP 1.1を勧告しています。

SOAPでは、エンベロープ(封筒)と呼ばれる、付帯情報が付いたXMLメッセージを、HTTPを用いてやりとりします。 具体的には、HTTP POSTリクエストのボディ部分と、レスポンスボディ部が、エンベロープになります。 エンベロープは“SOAPヘッダ”と“SOAPボディ”からなり、SOAPボディの中身が相手に渡したいメッセージになります。 HTTPを使用したSOAPリクエストメッセージの例として、以下をご覧ください。

 POST /tmp/soapTest HTTP/1.1
 Host: www.studyinghttp.net
 Content-Type: application/soap+xml; charset="utf-8"
 Content-Length: xxxx

 <xml version="1.0 ?">
 <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
  <env:Header>
   <n:alertcontrol xmlns:n="http://example.org/alertcontrol">
    <n:priority>1</n:priority>
    <n:expires>2001-06-22T14:00:00-05:00</n:expires>
   </n:alertcontrol>
  </env:Header>
  <env:Body>
   <m:alert xmlns:m="http://example.org/alert">
    <m:msg>Pick up Mary at school at 2pm</m:msg>
   </m:alert>
  </env:Body>
 </env:Envelope>

SOAPは、元々HTTPとともに使われることを前提でプロトコルが組み立てられていましたが、SOAPの開発者は、より汎用的にSOAPを利用できるようにするため、2003年6月に勧告したSOAP 1.2にて、XMLの転送に関してはSMTPFTPなども利用できるようにしました。 これにより、HTTPというプロトコルとSOAPとの結びつきは弱くなっています。

(※) また、SOAP 1.2からは、“SOAP”を何かの略称ではなく、単なるプロトコルの名称そのものとすることにしました。 これは、「プロトコルが段々と複雑になっていき、すでに“Simple”ではなくなってきたから」と言われています。

初期のSOAPのように、「データの転送部分としてのみHTTPを使用し、その上に(XMLなどを使って)別のプロトコルを作る」という考え方は、2002年にRFC 3205としてまとめられました。

REST

HTTPの原作者の一人であるRoy Fieldingは、2000年にArchitectural Styles and the Design of Network-based Software Architecturesという自身の博士論文の中で、Representational State Transfer (REST)という概念を発表しました。

Internet Engineering Taskforceの中で、既存のハイパーテキスト転送プロトコル(HTTP/1.0)を定義し、また新たな標準となるHTTP/1.1とUniform Resource Identifier(URI)の拡張を設計するためという取り組みを始めた時、私はWorld Wide Webがどのように動作すべきかに関するモデルの必要性を認識した。 Webアプリケーション全体の中の相互作用に関する理想的なモデルは、Representational State Transfer(REST)アーキテクチャスタイルと呼ばれ、現代のWebアーキテクチャの基礎となり、それまでのアーキテクチャに存在する欠点が指し示すであろう指針となる原則と、展開される前に検証される拡張を提供する。

Roy Fieldingは、HTTPやURIといったWebの根底を成す技術について、より効率的なものになるような設計をずっと行ってきましたが、それが必ずしも今日のWebに反映されていない現状を認識しました。 そのため、RESTという新たな概念が必要だと考えたのです。

「REST」に関するお薦め書籍

Roy Fieldingは、論文の中で「RESTを導き出す(Deriving REST)」として、「以下のような条件を満たすシステムを“REST”と呼ぶ」としています。

クライアント-サーバ方式
ユーザインターフェース(クライアント)とデータストレージ(サーバ)を分けることによって、様々なプラットフォーム上へのクライアントの移植性やサーバの拡張性を高め、さらに各実装を独立にすることで、インターネット規模での広大な領域で使用することが可能になります。
ステートレス(内部状態を持たない)
クライアントからサーバへの一つ一つのリクエストは、サーバ側が処理するために必要なすべての情報が含まれている必要があります。 これにより、単一のリクエストがレスポンスの性質を完全に決定できるため可視性や信頼性が向上し、また状態に関する情報はすべてクライアントが持っており、サーバは一切持っていないため、サーバの拡張性を高めることができます。
キャッシュ可能
HTTPレスポンスは、キャッシュ可能か否かが明示されている必要があります。 これにより、ネットワークの効率性や規模が向上し、またアクセスまでの時間が減少するユーザへの表示上のパフォーマンスが向上します。
統一されたインターフェース
RESTを他のネットワークシステムと区別する最大の特徴が、この「統一されたインターフェース」です。 インターフェイスを統一することによって、システムアークテクチャ全体をシンプルにでき、相互動作の可視性を高めます。
コンポーネントの階層構造
上記のようなシステムをプロクシなどの中継物を利用して階層化することによって、システム全体の規模拡大を容易にします。 また、レガシーシステム(既に時代遅れとなった古い技術を利用しているシステム)はカプセル化によって、利用者から「見えなくする」ことができます
ユーザの要求に応じたコード(Code-On-Demand)
RESTでは、必須ではありませんが、リソースそのものだけでなく、リソースを実行するためのコード(たとえばJavaScriptやJavaアプレットなど)をダウンロードして、リソースの処理をクライアント側で実行させることができます。 たとえば、すべてのクライアントがJavaアプレットをサポートしていることがわかっている場合、Javaクラスをダウンロードさせることによって処理を実行させることができます。 これにより、サーバの負荷を下げ、またシステムの拡張性を高めます。

RESTでは、リソースの生成方法がたとえばCGIによって生成されているのか、Javaサーブレットによって生成されているのかといった具体的な技術論には一切触れておりません。 また、上述のリストでも明らかなように、まったく新しいプロトコルを提案しているものでもありません。 あくまで、既存のWebで利用されている技術をどのように構築すれば、Web全体が最適化できるかということを意図して作られた概念です。

統一されたインターフェースとは、具体的には「リソースを指し示すためのURI」と「リソースを操作するためのHTTPメソッド」がそれぞれ該当します。 リソースの取得、生成、修正、削除に対応するHTTPメソッドは、HTTP/1.1としてそれぞれGETPOSTPUTDELETEが既に定義されているため、それらをそのまま利用します。

参照文献

Webリソース

書籍