今回はHTTP(Hyper Text Transport Protocol)についてのおはなしです。もはや「誰もが使っている」と言っても過言ではないHTTPですが、Digest AuthenticationだとかChunked Encodingだとかの盲腸的な裏話や、2015年5月に制定された新規格のHTTP/2についても言及します。

HTTP/0.9:Dawn of Internet era

 HTTPは今日「インターネット」の代名詞のようになったプロトコルですが、もともとは1990年代に欧州の原子核物理研究所(CERN)で「必要に迫られて」「場当たり的」に開発されたものです。各国の研究者が集うCERNには各国・各組織にバラバラな機種・ソフトウエアが持ち込まれ、簡単な図入りドキュメントの共有すら困難でした。いちいち紙に印刷してコピーを配らなければならないようでは、何のためにコンピューターネットワークを使っているのやらわかりません。HTTPはこの不便を解決すべく、英国の計算機学者ティム・バーナーズ・リー(Sir Tim Bnerners Lee)によってハイパーテキスト言語(Hyper Text Markup Language, HTML)とセットで開発されたものです(※注1)。その目的はなるべく簡易な文法で画像入りの書類を既述し、それをできるかぎり多くの機種・OS からオンライン閲覧することでした。

※注1:このときプロトタイプ開発に使われたワークステーションが、当時Apple社を離れていたスティーブ・ジョブス氏が創業したNeXTであったことは有名です。またHTMLは当時国際標準フォーマットとして普及が推進されつつあったSGMLからタグ文法を拝借し大幅に簡略化したものですが、HTMLの文法はSGMLと「似ている」ものの厳密には SGML準拠ではありません。後でSGML下位互換の汎用マークアップ言語XMLが開発され、XMLの仕様に基づいてHTMLを再定義したXHTMLが開発されました。

出所:CERN
出所:CERN
[画像のクリックで拡大表示]

 かくして1991年に発表された「暫定版」のHTTP/0.9は、ものすごく単純なプロトコルでした。要求元(クライアント)は TCPで要求先(サーバー)の80番ポートを接続し、たった1行のリクエストを送ります。リクエストは「GET/index.html」のように、コマンド「GET」に必要なドキュメント(コンテント)のパス名が引数で渡されるだけです(これを「Simple-Request」と呼びます)。サーバーはこれに対し、コンテント本体をガバッと送信してコネクションを切ります。エラーメッセージも何もありません(これを「Simple-Response」と呼びます)。

 HTTP/0.9はエラーの判断もできず、送られてきたコンテントの日付やフォーマットの情報もなく(ファイルの中身や拡張子から察するしかない)、コンテントのサイズも分からない(コネクションが切断されてはじめてファイル終端が分かる)など問題もありました。しかし何よりも「アホみたいに単純」という特徴があり、ソケットプログラミングに慣れた人なら30分くらいでHTTP/0.9のサーバーを書けるでしょう。「雑多なアーキテクチャー間でのファイル交換」というCERNの問題解決に特化した設計であり、この単純さゆえにHTTPはあっという間に実装が広まり「似たような」プロトコルを次々と駆逐してゆくことになります(※注2)

※注2:HTTPに駆逐された犠牲者の一つが、分散連携ドキュメント管理の先駆者だったGopherプロトコルでした。GopherとHTTPの明暗を分けた要因には様々なものがありますが、Gopher開発元のミネソタ大学が1993~2000年にかけてライセンス有償化をほのめかしていたという事情もあります。

HTTP/1.0:The birth of WWW

 HTTPが世界をつなぐWWW(World Wide Web)として本格的に成功したのは、1996年に発表されたHTTP/1.0(RFC1945)からでした。HTTP/1.0 ではリクエスト・レスポンスともに文法が拡張され、エラー情報やドキュメントの付随情報が交換できるようになました。今では常識のような「存在しないコンテントにアクセスしたとき返されるエラーは404」などのエラーコードは、HTTP/1.0になってから定義されたものです。

 「アホみたいに単純」だったHTTP/0.9に対してHTTP/1.0はだいぶ複雑になり、仕様書RFC1945は138Kバイト/3068行になりました。しかし「クライアントからの接続・要求送信」「サーバーからの返答返送・切断」という基本動作は HTTP/0.9と大きく変わっていません。

 HTTP/1.0では「GET」の他に「HEAD」と「POST」のコマンドが拡張されました(※注3)。「HEAD」はGETとほとんど同じで、しかしコンテントに関わるヘッダー情報(フォーマット、サイズ、最終更新日付など)だけを返し、コンテント本体の返送を伴わないというコマンドです。まだ低速のダイヤルアップ回線が主流だった時代、ブラウザーが更新日付を比較して更新があったファイルのみをダウンロードするような目的で作られたようですが、結局あまり活用されることはなく、現在ではほとんど使われていないと思います。

※注3:他にも「PUT」「DELETE」「LINK」「UNLINK」がオプションコマンドとして定義されていますが、実際にはほとんど使われていないので割愛します。

 「POST」はもっと重要で、HTTP/0.9 が「クライアント(ブラウザー)がサーバーからコンテントを取得するだけ」の片方向プロトコルだったのに対し、POST は「クライアント(ブラウザー)からサーバーにデータを送る」ことを可能にしたものです(※注4)。これによって HTTP は双方向のプロトコルとなり、当時流行した「個人ホームページ」には「掲示板」「足跡帳」「連続小説」のようなCGI機能を使った投稿型コンテンツが備わってゆくことになります。ちなみにCGIとはCommon Gateway Interface の略で、プロトコル名ではなくHTTPサーバーと拡張プログラムの通信方式(の中の一つ)を指すものですが、現在では「動的コンテンツを提供するHTTPサーバー」程度の意味で使われることも多いです。

※注4:ただしPOSTもGETもリクエスト~リプライの基本動作はほとんど同じで、異なるのはPOSTの場合リクエストヘッダーの後に任意長のコンテントが追加される点だけです。「クライアントからデータを送る」というだけなら、GETコマンドでも URL引数を用いてある程度(1Kバイト以内くらい)のデータを送ることはできます。これは SX-580電気スタンドの記事でも解説しました。