Studying HTTP

Help

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) は、分散・共同体ハイパーメディア情報システムのアプリケーションレベルプロトコルである。 このプロトコルは、リクエストメソッド、エラーコード、ヘッダ等の拡張を経て、ネームサーバや分散オブジェクト管理システム等、ハイパーテキストのために使う以上に多くの作業のために用いる事ができる、一般的でステートレスなプロトコルである [47]。 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通信における開始から終了までの流れ

RFC 2616のsection 1.4には、「HTTPがHTTPクライアントからのリクエストと、それに対するHTTPサーバからのレスポンスというメッセージの送受信によって成立している」ということが記述されています。

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

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

また、section 1.4には、HTTPの通信上の決まりについても書いています。

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

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

HTTPというプロトコルは、一般的にTCP/IP上で使用します。 HTTPのためのポート番号として80番が予約されていますが、それ以外の番号を使用することもできます。 たとえば、80008080などがテスト用としてしばしば利用されています。

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

HTTP アプリケーション

HTTPアプリケーションとは、HTTP通信鎖を構成するソフトウェアを指し、全てRFC 2616で定義されています。 具体的には、以下のようなものがあります。

クライアント

「クライアント」という用語についての定義は、RFC 2616 の section 1.3 にあります。

クライアント {client}
リクエストを送信する目的でコネクションを確立するプログラム。
ユーザエージェント {user agent}
リクエストを発行するクライアント。 これらはしばしば、ブラウザ、エディタ、スパイダ (web ロボット)、あるいはその他のエンドユーザツールである。

定義上は、「コネクションを確立するのがクライアント」「リクエストを送信するのがユーザエージェント」と区別されてはいるのですが、実際には区別なく使用される事も多いです。 したがって、ほとんどの場合では「クライアント」を「ユーザエージェント」と読み替えても問題はないでしょう。

ユーザエージェントには、だいたい以下のようなものがあります。

  1. 人間が Web ページを閲覧するためのブラウザ
  2. サーチエンジン等で、Web 上の HTML を集めるロボット (あるいはスパイダともクローラとも呼ばれる)
  3. インターネットに接続しているうちに、あらかじめ指定された URI からリソースを集めておき、接続を切って後にリソースを閲覧できるようになっているプリフェッチャ
  4. Web ページの変化を監視するためのアンテナ
  5. HTML 中でリンクされているリソースがまだ有効かどうかを確認するためのリンクチェッカ
  6. HTML の文法が DTD (文書型定義) に従うかを確認するためのリント

但し、サーバから HTTP レスポンスボディとして返される HTML やスタイルシート等を解析し、それをエンドユーザ(人間)が閲覧できるように描画{rendering} するものがブラウザであるのに対し、前もってセットされたプログラムに則って、サーバから HTTP レスポンスボディを半自動的に取得するものがロボットであると言えるので、下の 5 つは全てロボットであると言う事もできます。 ロボットを運用する場合は、できるだけ From ヘッダが送られるべきです。

ブラウザでは、以下のようなものが世界的に有名です。

Internet Explorer (IE)
Windows OS に標準で搭載されており、現在世界で最も利用されているWebブラウザ。
Mozilla Firefox
現在世界で2番目のシェアを持つWebブラウザ。HTMLCSSなどのWeb標準への準拠度が高い。

また、最近では「“Webブラウザ”というHTTPクライアント」の中に「別のHTTPクライアント」を確立する技術も広く利用されています。 有名な技術にJava AppletAjaxなどがあります。

RFC 2616が“MUST”という表現を用いて「HTTP/1.1クライアントが満たさなければならない要件」として定義しているのは、以下の4点です。 つまり、以下を満たさないクライアントは「HTTP/1.1クライアント」を名乗ってはいけないということになります。

  1. Host ヘッダを正しく送信できる
  2. チャンク形式転送コーディングを正しく解釈できる
  3. 持続的接続、及び Connection ヘッダを正しく解釈できる
  4. 100レスポンスを正しく解釈できる

サーバ

「サーバ」という用語の定義も RFC 2616 の section 1.3 にあります。

サーバ {server}
レスポンスを送り返す事で、リクエストを処理するためのコネクションを受け入れるようなアプリケーションプログラム。 プログラムの中にはクライアントとサーバの両方の機能を持つものがある; しかし、ここではこの用語を、一般的なプログラムの機能というよりむしろ、特定のコネクションについてプログラムによって果たされる役割のみのために使用する。 同様に、各リクエストの性質に応じてその振る舞いを、オリジンサーバ、プロクシ、ゲートウェイ、トンネルと切り換えるサーバもある。
オリジンサーバ {origin server}
指定されるリソースが存在するか、あるいは生成されるサーバ。

サーバとは、リソースを保持していて、リクエストが来た時にそれに従ってリソースを供給するものです。 RFC 2616 が“MUST”という表現を用いて「HTTP/1.1 サーバが満たさなければならない要件」として定義しているのは、以下の 8 点です。 サーバが「HTTP/1.1 サーバ」を名乗っても良いのは、以下を満たす場合に限られます。

  1. Host ヘッダがないリクエストに、正しく 400 レスポンスを返す事ができる
  2. リクエスト URI として絶対 URI を受け入れる
  3. チャンク形式転送コーディングを正しく解釈できる
  4. 持続的接続、及び Connection ヘッダを正しく解釈できる
  5. 100 レスポンスを正しく使用できる
  6. Date ヘッダを正しく付加する (特に HTTP 日付)
  7. If-Modified-Since ヘッダ及び If-Unmodified-Since ヘッダを正しく解釈できる
  8. GET メソッド及び HEAD メソッドを正しく解釈できる

代表的な HTTP サーバとして、世界中にある全サーバの半分以上で使用されている Apache があります。 Apache は、NCSA(米国立スーパーコンピュータ応用センター)が開発した NCSA HTTPd を元に開発された Web サーバですが、現在の Apache のコードは全て書き換えられており、完全なオリジナルとなっています。 現在公開されている Apache には 1.3 系、2.0 系、2.2 系があり、メインは 2.2 系となっていますが、安定したバージョン、あるいは使い慣れているバージョンを求める人は、あえて 1.3 系や 2.0 系を選択する事もあります。

プロクシ

クライアントとサーバの中間に入り処理をするプログラムには、プロクシゲートウェイトンネルがあります。

(※) “proxy”は、「プロキシ」と書かれる場合が多いですが、このサイトでは「プロクシ」で統一しています。

プロクシ {proxy}
他のクライアントの代わりとしてリクエストを行うためにサーバとクライアントの両方の役割を果たす中継プログラム。 リクエストは、可能な変換をもって、内部で処理されるか、あるいは他のサーバに渡される。 プロクシは、この仕様書が要求するクライアントとサーバの両方の機能を実装しなければならない。 "透過的プロクシ" とは、プロクシへの認証やクライアント自身の証明が要求されるようなもの以外のリクエストやレスポンスを修正しないようなプロクシである。 "透過的でないプロクシ" とは、ユーザエージェントに、ある種の翻訳、メディアタイプの変形、使用プロトコルの制限、匿名性向上のためのフィルタリング等のような、追加的サービスを提供するためにリクエストやレスポンスを修正するようなプロクシである。 その振る舞いが透過的であるか無いかが明言されている部分を除けば、それぞれのプロクシは HTTP プロクシとして必要な要素を共に持ち合わせている。
ゲートウェイ {gateway}
他のサーバを中継するサーバ。 プロクシとは違い、ゲートウェイはまるでリクエストされたリソースのオリジンサーバのように、リクエストを受ける。 リクエストしたクライアントは、それをゲートウェイと通信しているという事を気付かないかもしれない。
トンネル {tunnel}
二つの接続の間をまるで目隠しリレーを行う様に振る舞う中継プログラム。 一度起動したら、それが HTTP リクエストによるものであっても、トンネル自身は HTTP 通信における当事者とみなさない。 トンネルは中継する両端の通信が終了した時、終了する。

プロクシは、キャッシングサーバとして利用される事があります。 キャッシュについての詳しい説明は、HTTP Caching をご覧下さい。

プロクシが「HTTP/1.1 プロクシ」を名乗っても良いのは、HTTP/1.1 クライアント及び HTTP/1.1 サーバの両方の機能を満たしている場合に限られます。 HTTP/1.1 プロクシの機能を満たしていないプロクシが HTTP/1.1 を名乗ってしまうと、通信が破綻してしまう可能性があるので注意が必要です。

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/0.9

HTTPの最初のバージョンはHTTP/0.9と呼ばれますが、これには正式な仕様書がありません。 むしろ、「HTTP/1.0以前のHTTP」という意味で便宜的につけられた呼び名であると考えたほうが良いでしょう。

HTTPというプロトコルが無かった頃、ネットワークでの情報転送には主にFTP等が使われていました。 FTPとは“File Transfer Protocol”の略で、ファイルやディレクトリについての決まりを共通化し、インターネット上でファイルを転送するためのプロトコルで、その仕様はRFC 959に記述されています。

(※) 慣習として、“FTP”と大文字で書くとFTPプロトコルを意味し、“ftp”と小文字で書くとFTPを扱うためのソフトウェアを意味します。

一般に、ftp を使用するためには、ネットワーク管理者に依頼し、ホストコンピュータへのログインとアクセスの権限を与えてもらう必要があり、面倒でした。

そこで、CERN (セルン; ヨーロッパ原子核研究機関) の物理学者 Tim Berners-Lee が、「簡易版 FTP」とも言うべき、リソースの分散システムを提案します。 これこそが WWW であり、その時に HTTP や HTML の原型もできました。

(※) FTP を行うためには ftp クライアントが必要ですが、最近では Internet Explorer や Mozilla Firefox と言った Web ブラウザにもその機能が実装されています。

HTTP/0.9 では、メソッドは GET しかなく、リソースに関するメタ情報を転送するための HTTP ヘッダ等は一切ありません。

HTTP/1.0

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

一方で、この WWW というシステムを一気に世に広めた事件が起こります。 1993 年 2 月、イリノイ大学の NCSA (国立スーパーコンピュータ応用センター) にいた Marc Andreessen らが NCSA Mosaic というブラウザを発表したのです。 Mosaic は、「インラインイメージ」すなわちブラウザ内に画像を表示する機能を実装していました。 現在のブラウザには当然の機能なのですが、これはそれまでのブラウザに無い画期的なものだったのです。

翌年の 1994 年、Mosaic の権利を巡り対立した Marc Andreessen は Mosaic の開発元である NCSA を離れ、Mosaic Communications 社を興します。 同年、Netscape Communications 社と社名を変更し、Netscape Navigator という新しいブラウザをリリースしました。 Netscape Navigator は大ヒットし、WWW の利用が爆発的に広がりました。

1995 年、WWW に興味を持った Microsoft は Internet Explorer (MSIE) を市場に投入しました。 これにより、俗に「第一次ブラウザ戦争」と呼ばれる Netscape vs MSIE の闘いが繰り広げられる事になります。

これにより、WWW の基幹プロトコルである HTTP もまた拡張がますます求められていく事になります。 1993 年 3 月に HTTP/1.0 の最初のドラフトが、同年 11 月には第 2 のドラフトが作成され、それ以降も多くの議論を重ねた末に、3 年後の 1996 年 5 月、ついに RFC 1945 として HTTP 最初の正規のプロトコル仕様書が発行されたのです。

但し、RFC 1945 は Informational として発行されている点に注意して下さい。 これは、各 HTTP ベンダが HTTP/1.0 が正式な仕様として成立する前にそれぞれに機能を実装をしてしまったせいで、同じ「HTTP/1.0 対応」を標榜する各アプリケーション間に大きな差異が生じてしまったためです。

HTTP/1.1

HTTP/1.0 の仕様書である RFC 1945 は、Informational というカテゴリです。 ただ、Informational は、その名の通り「情報提供」のための RFC であり、インターネットの標準と呼べる位置にはありません。 そこで、HTTP/1.0 を更に高機能にしたプロトコルである HTTP/1.1 の初版が 1997 年 1 月に RFC 2068 として発行されました。 RFC 2068 は、Standards Track という、インターネットの標準化を目指す RFC として登録されています。

HTTP/1.0 は、シンプルで、かつ安定したプロトコルでしたが、HTTP/1.1 ではそれに加え、持続的接続仮想ホストの他、チャンク形式エンコーディング内容ネゴシエーション (コンテントネゴシエーション) 等の新しい機能が追加され、また HTTP による通信をより快適にするものにするために、HTTP/1.0 よりも厳格なものとなっています。

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

このように、HTTP/1.1 アプリケーションは、HTTP/1.0 よりも数段複雑な動作が要求されます。 従って、そのアプリケーションが従うプロトコルバージョンを厳密に宣言しておかなければなりません。 そのために必要なのが、HTTP バージョンです。 この HTTP のバージョン番号の付け方については、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/1.1 アプリケーションは、HTTP/1.1 の仕様に準拠していなければいけません。 HTTP-Version は、そのメッセージに使われている技術のバージョンではなく、「それを送信するアプリケーションが理解できる最大のバージョン」を意味するので、特に HTTP/1.1 の仕様書でその実装が必須とされているものを実装していなければなりません。 もし、HTTP/1.1 をサポートしていないアプリケーションが、HTTP-Version に 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 がこのように記述したのは、RFC 1945 や RFC 2068、及びそれに関連する文書の中で、定義はされたもののほとんど利用されずに消えていった様々なメソッドやヘッダフィールド等について、HTTP/1.1 アプリケーション (特にサーバ) がその全てをケアする必要は無いという意図が読み取れます。

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

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そのものの発展については、リソース提供の自動化やキャッシュ制御メカニズムといった個別の要素技術を、モジュール的に組み込むことができるように、新たにProtocol Extension Protocol (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とは“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は、は現在HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)として改訂されていますし、またWebDAVに関連する仕様書は現在も多数発行されています。

HTTP/1.1, 2度目の改訂へ

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

同年5月に、HTTP/1.1からTLSへのアップグレードという文書が公開されました。 この文書は、TLSによる安全な転送を、HTTP/1.1通信の最中に切り替えられるようにするという拡張を規定しています。 そのため、この文書がRFC 2616の内容の一部を更新するものとなっています。

RFC 2817は、RFC 2616の内容の一部を置き換えただけであり、現在も「最新のHTTP/1.1仕様書」という位置付けにある文書はRFC 2616のまま変わっておりません。 しかし、RFC 2616中には誤字がいくつもあったり、また仕様上の不具合などがいくつも発見されているため、それらを修正すべきとの声が日に日に高まってきました。 そこで、W3Cはそれらを修正するために、2006年10月よりHTTP Activityを再始動しました。 再始動直後の声明では、HTTP/1.1の改訂版は2008年10月にIESGに提出されると宣言していましたが、2010年1月現在はまだドラフト第8版が公開されているだけで、完成には今しばらくの時間がかかる模様です。

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 を、そして 2003 年 6 月に SOAP 1.2 をそれぞれ勧告しました。

(※) SOAPとは元々“Simple Object Access Protocol”の頭文字をとったもので、仕様書にもそう書いてありました。 しかし、オブジェクト指向的な側面は少なく、また最近は“Simple”でもなくなってきたので、1.2 からは“SOAP”とは何かの略称ではなく、プロトコルの名称そのものとなりました

SOAPでは、エンベロープ(封筒)と呼ばれる、付帯情報が付いたXMLメッセージを、HTTPなどの通信プロトコルで交換しています。 最新のSOAP仕様ではSMTPFTPなども利用できますが、一般に通信プロトコルとしてはHTTPが使用されます。 その理由としては、プロトコル自体の簡単さに加え、たとえば「HTTPを転送プロトコルとして使えば、そのセキュリティを上げるためにHTTPSを使うことができる」といった、既存のアプリケーションの流用性の高さも上げられます。

以下は、HTTPを使用したSOAPメッセージの例です。 HTTP POSTのリクエストボディ部分が、エンベロープになります。 エンベロープは“SOAPヘッダ”と“SOAPボディ”からなり、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>

XMLHttpRequest

Microsoft社は、2000年に“XMLHTTP”という名のActiveXコントロールを開発しました。 これは、HTTP越しにデータを読み出すためのもので、元々は「Outlook Web Access 2000」というWebメールのためのものでしたが、Microsoft社はこの技術をMSIE 5にも導入し、JavaScript(正確には、JScriptと呼ばれるMicrosoft社製のスクリプト言語)で操作できるように実装しました。

この技術により、Webブラウザとの非同期通信が可能となりました。 つまり、ユーザの操作を必要とせずにサーバとXML形式のデータのやり取りを行うことで処理を進めていくWebアプリケーションを開発することができるようになったわけです。

2001年には、Mozilla FirefoxがXMLHttpRequestという名前の、XMLHTTPと同等なJavaScriptオブジェクトを開発・実装しました。 今日では、それら以外のブラウザもこの動きに追随し、Google MapsをはじめとしたAjaxと呼ばれる技術の中核を担うものとして、世界中で利用されています。

しかしながら、上述の通り、XMLHttpRequestは独自仕様から始まっている技術のため、多くのWebブラウザに実装されているとはいえ、その実装はブラウザ間で微妙に異なっていました。 そこで現在、XMLHttpRequestはW3Cにて標準化が行われています。 W3C が策定しているXMLHttpRequest仕様は、機能水準により“Level 1”と“Level 2”がありますが、現在広く使用されているブラウザの多くは“Level 1”の持つ機能を実装しています。 (Internet Explorer 7以降、Mozilla Firefox 1以降、Safari 1以降、Opera 8以降、Google Chrome 1以降)

以下は、2009年11月19日に発行されたW3Cのワーキングドラフトです。 第1章には、「XMLHttpRequestとは何か?」ということが記述されています。

XMLHttpRequestオブジェクトは、たとえばフォームデータを送信したり、サーバからのデータをロードするような、スクリプトがHTTPクライアントの機能性を実行できるようにスクリプト用のエンジンによって提供されるインタフェースを実装する。 これは、ECMAScriptのHTTP APIである。

このオブジェクトの名前はXMLHttpRequestであり、名前の各部分が誤解を招く可能性があるが、Webでの互換性のためにそう名付けられている。 初めに、このオブジェクトは、XMLを含むあらゆるテキストベースのフォーマットをサポートする。 次に、これはHTTP上でもHTTPS上でも使用することができる(いくつかの実装では、HTTPとHTTPSに加えたプロトコルをサポートする、そのような機能性はこの仕様では範囲外である)。 最後に、これはHTTPに関連する際に広い意味での“要求{request}”をサポートする;すなわち、HTTPにかかわるすべての活動{activity}が定義されたHTTPメソッドのために要求もしく応答する。

ECMAScriptとは、ECMA(ヨーロッパ電子計算機工業会)によって標準化されたスクリプト言語です。 (詳細は、JavaScriptを参照) また、“XMLHttpRequest”というオブジェクトの名前についてですが、これは歴史的な経緯によるもので、XMLに限らずテキスト文書全般を扱えますし、HTTPだけでなくHTTPS上でも使用できますし、HTTPリクエストに対するレスポンスの受信にも使用します。

また、同じ第1章に「XMLHttpRequestの使用例」についても記述されています。 たとえば、以下は“text.xml”というXMLファイルをGETリクエストで取得し、そのXMLを解析して、<test>というタグの内容を取り出すためのスクリプト(の雛形)です。

 function test(data) {
  // taking care of data
 }

 function handler() {
  if(this.readyState == 4 && this.status == 200) {
   // so far so good
   if(this.responseXML != null && this.responseXML.getElementById('test').firstChild.data)
      // success!
    test(this.responseXML.getElementById('test').firstChild.data);
   else
    test(null);
  } else if (this.readyState == 4 && this.status != 200) {
   // fetched the wrong page or network error...
   test(null);
  }
 }

 var client = new XMLHttpRequest();
 client.onreadystatechange = handler;
 client.open("GET", "test.xml");
 client.send();

XMLHTTPRequest仕様では、以下のようにしてオブジェクトを作成します。

 var httpObject = new XMLHttpRequest();

HTTPリクエストはopen()でメソッドとURIを(場合によっては、HTTPヘッダも)指定した後で、send()を実行することで送信できます。 また、HTTPレスポンスは、受信状況が変化する毎に呼ばれるonreadystatechangeというイベントハンドラにメソッドを実装することによって、処理を行うことができます。

参照文献

Webリソース
Hypertext Transfer Protocol -- HTTP/1.1
HTTP - Hypertext Transfer Protocol Overview
Firefox と Mozilla 関連組織の歩み (概略)
XMLHttpRequest (W3C Working Draft 19 November 2009)
書籍
Paul S. Hethmon 著, ファサード 訳: HTTP詳説―作ってわかるHTTPプロトコルのすべて, ピアソンエデュケーション, 1998.
佐藤正博: インターネット屋根裏探検隊, オーム社, 1998.
田中伸一 著, ぐるーぷ・アレフ + ジャストシステム出版部 編: WebDAV入門―ダヴとXMLがつくる情報共有の未来, ジャストシステム, 2001.
Christopher Wells 著, 牧野 聡 訳: Ajaxアプリケーション & Webセキュリティ, オライリー・ジャパン, 2008.
ナウでヤングなレンタルサーバー!ロリポップ!

Copyright © 1999-2010 H-Hash, All Rights Reserved. Valid HTML 4.01 Strict 正当なCSSです!