|
プログラミング言語を勉強したことがある人なら誰でも経験していることだが,雑誌や書籍の解説を読むだけでなく,実際に自分でプログラムを作ってみると理解は数段深まる。読んだときにはわかったような気になったものでも,案外わかっていないことが多く,自分で試してみることで,あやふやな理解が本物の理解に変わっていくからだ。インターネットを始めとしたネットワーク技術でもこれを同じことが当てはまる。実際に試してみることによって理解が深まるのだ。
案ずるより産むが易し,ということわざがあるが,仕様書や解説書を読んで勉強するより,実際に試してみた方が手っ取り速く理解できることも多い。また,本で得た知識は時間が経つと忘れてしまうが,自分で試してみたことはなかなか忘れない。
このように,自分で試してみることにはいろいろなメリットがある。だから,とにかくいろいろと試してみよう,というのがこの連載の趣旨だ。
初回は,まず手始めとしてHTTPというプロトコルの基本的な枠組みを実験を通して調べてみることで,WWWの仕組みを理解するところから始める。
WWWはブラウザからサーバにページ読み出しのリクエストを送り,サーバがそれに応えてページデータを返すものであり,そのリクエストやページデータを運ぶときに使うのがHTTPである。こういった概念的な説明は雑誌や書籍などに書いてあるのだが,HTTPというプロトコルがどのような考え方で作られたもので,サーバとブラウザの間で具体的にどのようなやり取りが行われるのかというところまで書いてあるものは少ない。しかし,その具体的な仕組を知らないと概念的な理解を超えることができない。
ユーザの立場であれば概念的な理解だけでもよいが,実際にシステム構築を担当する技術者がそれでは心もとない。WWWがどういった仕組みで動いているのかを正確に理解できなければ,障害が起こっても自分で原因を究明できないし,対策も立てられないからだ。ファイアウォールやプロキシサーバを使う場合のように,システムが複雑になると,それが顕著になる。
また,HTTPはWebサーバからページデータを読み出したりするときに使うものだったが,最近はそれ以外の用途にも使われるようになっている。データベースをアクセスしたり,音声や動画データを配信するものがその例だが,こうした使い方が登場してきた理由はHTTPという仕組みそのものを知らないとなかなか理解できないし,仕組みが理解できなければ応用することもできない。
こういった説明をすると難しく感じるが,そこが案ずるより産むが易しなのだ。実際のHTTPの仕組みはそれほど難しくないし,難しいことだったらこれほど普及するはずもない(*1)。だから,試せばわかる。
|
ドキュメントも重要
この連載では試すことによって基本的な枠組みを理解することに重点を置くが,それができたら,併せてRFCなどの技術文書にも目を通すことをお勧めする。実験で試せる事柄はそれほど多くはないし,例外処理などのように普通の実験では試せないこともある。だから,技術文書に一通り目を通しておかないと,断片的な知識で終わってしまうことにもなりかねないからだ。
実験を通して基本的な枠組みが理解できていれば,技術文書を読むのがずっと楽になる。内容を読まなくても目次や見出しを見れば大体察しがつくことも多いので,無駄がない。特に英語を読む効率は段違いである。
また,ドキュメントを読むときは,読むものを選ぶことも重要である。読んでも理解できないような下手な解説文書を読むのは時間の無駄だし,間違ったことが書いてあるものなら読まない方がよいからだ。そういった意味で,インターネット技術の原典であるRFCを読むことをお勧めする。
RFCは無味乾燥で難解な仕様書という先入観を持っている人もいるが,そうではない。確かに,初心者向けの基本的な技術解説は載っていないが,意外と丁寧に説明されているものが多い。細かな点まで書いてあるので,ほとんどの疑問を解決してくれる。仕様書特有の表記方法が使われている部分があり,敷居が高く感じることもあるが,そういった部分は言葉での説明を補うものとして書かれていることが多いので,飛ばして読めばよい。そう考えれば,RFCは中上級向けの解説書としても優れたものだといえる(*2)。一度もRFCを見たことがないのなら,試しに眺めてみれば,そうしたRFCの実態を垣間見ることができる。そうすれば,RFCがごく一部の専門家だけが見るための文書ではないことがわかるだろう。
1998年8月現在,2380以上のドキュメントがRFCとして登録されており,複数のサーバで閲覧およびダウンロードが可能になっている。もちろん無料だ。下記URLにその案内がある。
http://www.rfc-editor.org/rfc.html
|
Webサーバのセットアップ
では,実験を始めるが,本番で使っているシステムを使って実験するのは恐いので,実験システムを用意するところから始めることにしよう。といっても今回はWebサーバをセットアップするだけである。手元に実験用として使えるWebサーバがあれば,それを使ってもよい。
最近のOSには,Webサーバが含まれているものが多く,セットアップ時にオプションを選択しておけば,OSと一緒にWebサーバがセットアップされる。今のWindowsはそうなっているし,それ以外のOSも似たようなものである。
OSのセットアップ時にWebサーバをセットアップしていなくても大丈夫だ。後でWebサーバだけを追加してセットアップすることもできる。その場合は,最新版をインターネットからダウンロードして,セットアップした方が良いかもしれない。マイクロソフト社のWebサーバの場合は,http://www.microsoft.com/windows/downloads/から最新版が入手できる。UnixなどではApacheというWebサーバを使用することが多いが,それはhttp://www.apache.com/から最新版をダウンロードできる。
Webサーバには製品やフリーウェアなどいろいろなものがあるが,今回の実験では基本的な機能しか使わないので,どれを使っても良い。必ずしも最新版である必要もない。セットアップに手間取るようだと時間の無駄なので,簡単にセットアップできるものを選んだ方がよい。
Webサーバによって違いはあるが,ほとんどのものはセットアップ用のプログラムなどを使ってセットアップするとそのまま動いてしまう。無難な値がデフォルトの設定値として予め設定されているからだ。細かな設定項目もあるが,最初はセットアッププログラムが設定してくれるデフォルトの設定でWebサーバ動かしてみよう。設定をいじるのはその後だ。
これはWebサーバのセットアップに限ったことではなく,どんな作業にも当てははることだが,作業が終わったらそれが意図した結果に終わっているかどうかを確認することが重要だ。確認せずに先に進むと,異常に気づいたところから後戻りしなくてはならなくなる。変更した個所を正確に覚えていればまだよいが,それすらあやふやになってしまうことも多いから,そうなると,設定を変更したことが異常の原因なのか,セットアップ作業自体が異常だったのか判別できなくなる。下手をすると,セットアップ作業のやり直しが必要になることもある。だから,設定を変更する前に,セットアップが正しく終了したかどうか確認するのである。
確認方法は簡単だ。ブラウザでWebサーバのホームページを読み出してみればよい。WebサーバがDNSに登録されていなければ,IPアドレスを指定すればよい(図1)。これで,ホームページが表示できれば,Webサーバのセットップは正常に終わっている。

telnetで接続
Webサーバが動き始めたら実験開始だ。まず,telnetというプログラムを使ってWebサーバに接続してみよう。
そもそも,telnetを使ってWebサーバに接続する,ということはどういうことなのか。そこが疑問かもしれない。そういった疑問がわき起こることが本連載の狙いの一つでもある。telnetの話題は本題から外れるので囲み記事に簡単にまとめておくが,要するにtelnetを使えば相手と文字データを送受信できる。それで,Webサーバに文字データを送り,Webサーバがどういう反応を示すかを観察しようというのだ。実は,WebブラウザでWebサーバにアクセスする場合も,両者の間で交換されるデータは文字データが基本となっている。Webブラウザではその文字データのやり取りが直接見えないので,telnetでやり取りの様子を直接観察しようというのがtelnetを使う意味である。そうして,やり取りの様子を直接見れば,WWWやHTTPの仕組みがよくわかるというわけだ。
接続操作は図2のように行う。ここで指定する項目はWebサーバのIPアドレスとポート番号だ。ポート番号というのは相手のコンピュータ内で動いているプログラムを選ぶためのものだ(図3)。普通,コンピュータの内部には多数のプログラムが動いているから,IPアドレスを指定するだけでは,その中のどのプログラムと接続すればよいのかが判別できない。そこで,どのプログラムと接続したいのかを相手に知らせるための仕組みが必要となる。その仕組みがポート番号なのである。telnetは接続操作のときにポート番号を指定しないと,telnetdという端末制御プログラムのポート番号を使うようになっているので,接続時にポート番号を指定してWebサーバに接続する。それが図2の操作だ。80というポート番号はWebサーバのデフォルトのポート番号である。Webサーバの設定によって80以外のポート番号を使うこともできるので,Webサーバ側が80以外のポート番号を使うように設定されている場合は,その番号を使うようにする。
そうして接続すると,telnetのウインドウタイトルが図2の下のように変わるはずだ。ウインドウの中には何も表示されないがそれでかまわない。Webサーバはクライアントからの処理要求を受け取って,その要求に従って処理を実行するので,こちら側から要求を送らなければ何もしない。だから,telnet画面に何も出てこないのだ。
|
telnetとは
telnetというプログラムは,他のコンピュータにログインして文字型の端末装置として使うためのものだ。たとえば,Unixマシンに接続すれば,loginプロンプトが出るし,この後,ユーザ名とパスワードを入力してログインすればコマンド入力待ち状態となり,そこにコマンドを入力すれば,それを処理してくれる。(図3)。シリアルポートに接続した端末装置の動作と同じである。
しかし,こういったloginプロンプトを表示したり,ユーザ名やパスワードの入力を受け付けたりするのは端末装置の機能ではない。telnetの接続相手である端末制御用のプログラムやOSがloginプロンプトやユーザ名,パスワードなどの処理を行っているのだ。端末装置は単に相手が送ってきた文字データを画面に表示し,キーボードから入力された文字データを相手に送っているだけなのである。端末制御用プログラムがloginという文字データを送ってきているから画面に見えているだけで,telnet自身はその意味を一切関知していない。
これは,言葉を変えると,telnetの接続相手は端末制御プログラムに限定されているわけではなく,ポート番号を指定して接続できるものであれば何でもかまわないことを表している。そして,telnetはその相手と単に文字データを送受信するだけのものだともいえる。だから,端末制御用プログラム以外の相手に接続すれば,その相手と文字データを交換できることになる。
ただし,文字データ以外のデータはだめだ。文字じゃないデータはそのまま画面に表示できないし,キーボードで入力できないデータは送りようがないからだ。(*3)。
Webブラウザもtelnetと同じように相手が送ってきたデータを画面に表示するが,HTMLのタグによってデータをレイアウトしてから表示するので,相手が送ってきた生のデータを見ることはできない。ソース表示モードやページ情報表示モードにすればHTMLドキュメントのソースコードや属性情報などが見えるが,Webサーバとやり取りしているデータはそれだけではない。それはWebブラウザでは見えないのだ。その点,telnetはHTTPの制御情報やHTMLのタグといったデータの内容には一切関知せず,そのまま生のデータを見せてくれる。生データが見えないWebブラウザでは内部の仕組みを探るのは難しいが,telnetならそれが簡単にできる。
|
ホームページの読み出し
Webサーバは処理要求が来るのを待っているわけだから,それをこちらから送ってみよう。処理要求はHTTPではリクエストと呼び,書式が決められているが,細かことは後回しにして,とりあえず図4aのようにタイプしてみよう。ここでタイプしたものが処理要求となってWebサーバに送られる。
このとき,telnetのターミナル設定オプションを設定して,ローカルエコーをオンにしておく。ローカルエコーをオンにしないと,タイプした文字が画面に出てこないので,正しくタイプできているかどうかも確認できないからだ。とはいっても,タイプミスしたからといって,バックスペースで修正することはできない。HTTPの仕様ではリクエストの途中にバックスペースというデータが入ってくることを想定しておらず,フォーマットエラーになってしまうからだ。タイプミスしたら一度切断し,もう一度接続操作からやり直さないといけない。
リクエストの文字列をタイプし終わったら,改行キーを2回押す。すると,画面に何か表示され,telnetは切断されるはずだ。もし,何も表示されなかったら,一旦切断してもう一度接続からやり直さないといけない。そして,改行キーの代わりに,CTRL-Jを使ってみよう。telnetのバージョンによっては改行キーを押したときに送信する文字コードに違いがあるからだ。CTRL-Jならどんなバージョンでも同じコードを送信してくれる。それから,英文字はすべて大文字を使うこと,そして,タイプミスがないかどうかも確認しよう。
これで表示されたものがホームページのデータである。セットアップした直後のホームページのデータはWebサーバがデフォルトで用意してあったものだが,多分,データ量が多く,あっという間に最初の方が消えてしまい,データの最後の方しか画面に残らないだろう。それではよくわからないので,ホームページのファイルを図5aのようなものに置き換えてみる。
そして,もう一度,Webサーバに接続して図4aのリクエストを送ってみる。すると,今度は置き換えたファイルの内容が表示されることがはっきりとわかるだろう(図5b)。


HTTPの基本動作
最初の実験はこれで終わりだ。これで,HTTPという仕組みの骨格がわかる。
今の実験をおさらいすると,まず,telnetからWebサーバにリクエストを送り,Webサーバがその内容に従って処理し,その結果をtelnetに送り返してきたことになる。HTTPの用語ではこれをレスポンスという。簡単ではあるが,これがHTTPとWebサーバの基本動作だ(*4)。ネットワークのプロトコルというと複雑なものと思っている人もいるが,HTTPの場合の基本はこれだけである。
このように,サーバに対してリクエストを送り,サーバがそれを処理して結果を返す,という動作モデルをクライアントサーバモデル(C/Sモデル)と呼ぶ。だから,HTTPの基本的な仕組みはC/Sモデルだともいえる。telnetは端末用ソフトなのにクライアントサーバモデルというのはおかしいと感じたら,それは本質を見誤っている。telnetは端末用に作られたものではあるが,この実験のようにサーバに対してリクエストを送るという用途に使えば,その役割は端末ではなくクライアントになってしまう。使い方によって役割は変わるのだ。また,Webサーバのクライアントはブラウザだと固定して考えるのもよくない。自動巡回ソフトなどもWebサーバのクライアントとして使えるのだから,ブラウザだけがクライアントとなるわけではないのだ。
HTTPという仕組みの用途もWWWだけに固定して考えてはいけない。HTTPのベースとなっているC/Sモデルはシンプルであるにも関わらず,サーバ側で用意しておく機能次第でいろいろな用途に応用できる。この性質のため,今のネットワークシステムは何らかの形でこの動作モデルを使っているものが多い。データベースサーバを使ったいわゆるC/SシステムがC/Sモデルを使う代表格だが,それだけでなく,ファイルサーバへのアクセス,メールサーバやニュースサーバからのメッセージのメール読み出しなどにもC/Sモデルは使われている。むしろ,このモデルを使っていないものの方が少ないくらいだ。そのC/Sモデルをベースにしているのだから,HTTPの適用範囲も当然C/Sモデルと同じように広い。WWW以外にも使える理由はここにある(*5)。
実験で使ったリクエストの意味
HTTPはリクエストとレスポンスによって処理を進めるのだから,リクエストとレスポンスの内容を理解することが一番重要だ。最初は実験でサーバに送ったリクエストの意味から説明しよう。
リクエストの最初にある"GET"はページを読み出すという意味のコマンドを表している。HTTPの仕様ではコマンドのことをメソッドと呼び,それがリクエストの先頭にあるものと決められている。なお,HTTPのバージョンによって異なるが,メソッドには表1のようなものがある。
次の"/"は読み出すファイルを指定するものだ(*6)。正確にいうと,ここはURI(Uniform Resouce Identifier)という考え方に基づいてファイルを指定するのだが,URIはHTTPだけでなく他のインターネット技術とも関わってくるものなので別の機会に説明する。ここではファイルのパス名だと思えばよい。"/"というのはUnix流の表記法を用いたもので,ルートディレクトリを表している。これだけではファイルを指定したことにならないが,Webサーバにはファイル名を省略したときのためにデフォルトのファイル名が設定できるようになっており,この例のようにディレクトリだけが指定され,ファイル名が省略された場合は,そのデフォルトのファイル(デフォルトドキュメント)を読み出すようになっている。index.html,default.htmといった名前のファイルがそれだ。だから,ルートディレクトリにあるデフォルトドキュメント,すなわち,ホームページが出てきたのである。また,ここでいうルートディレクトリはコンピュータの本当のルートディレクトリではない。Webサーバに設定されている,公開用ディレクトリのことである。これはWebサーバの設定によって変わるので,"/"という指定で読み出されるファイルはサーバ側の設定次第である。
次の"HTTP/1.0"はHTTPプロトコルのバージョン番号だ。HTTPには0.9,1.0,1.1という三つのバージョンがあり,今普通に使われているのは1.0と1.1である。最新版は1.1だが,1.0の方がシンプルなので,この実験では1.0を使うことにする。
リクエストの後に空白行が一つあるが,これがリクエストの終了を表している。そして,その後に続くのが,サーバからのレスポンスである。
表1 HTTPのメソッド
|
メソッド
|
HTTPのバージョン
|
意味
|
|
1.0
|
1.1
|
|
GET
|
○
|
○
|
URIで指定した情報を取り出す。URIで指定したものがファイルの場合,そのファイルの中身を返送する。URIで指定したものがCGIによるサーバプログラムの場合は,そのプログラムの出力データをそのまま返送する。
|
|
HEAD
|
○
|
○
|
GETとほぼ同じ。ただし,HTTPヘッダは返送するが,データの中身は返送しない。ファイルの最終更新日時などの属性情報を調べるときに使用する。
|
|
POST
|
○
|
○
|
クライアントからサーバにデータを送信する。フォームに入力したデータを送信する場合などに使用する。
|
|
OPTIONS
|
|
○
|
通信オプションを通知したり調べるときに使う。
|
|
PUT
|
△
|
○
|
URIで指定したサーバ上のファイルを置き換える。URIで指定したファイルが存在しない場合は,新たにファイルを作成する。
|
|
DELETE
|
△
|
○
|
URIで指定したサーバ上のファイルを削除する。
|
|
TRACE
|
|
○
|
サーバ側で受け取ったリクエストラインとヘッダをそのままクライアントに返送する。プロキシサーバなどを使う環境で,リクエストが書き換えらる様子を調べるときに使う。
|
|
PATCH
|
|
△
|
PUTと同様にサーバ上の情報を置き換えるが,置き換える差分だけサーバに送信する。
|
|
LINK
|
|
△
|
他の情報との関連付けを行う。
|
|
UNLINK
|
|
△
|
LINKで設定した関連付けを削除する。
|
○:仕様として定義されているもの。△:正式な仕様ではなく付加機能としてAppendixに記述されているもの。
レスポンスの意味
レスポンスの最初の行はステータスラインというもので,処理結果が正常だったか何らかの異常があったか,といった結果の状況を表すものだ。そのフォーマットは,行の最初にHTTPのバージョンがあり,次にステータスコード,最後に理由を表す文字列となっている。ステータスコードは3桁と決められており,左端の桁で概要がわかるようになっている(表2)。エラーが発生すると図6のようにエラーメッセージが表示されるが,そこに出てくる番号がステータスコードである。
次の行からServer:...,Date:...,というように":"で区切られた,<フィールド名>:<フィールド値>という形式の行が6行ほど続いている。この行の一つ一つがいろいろな付加的情報を表すもので,その個々をHTTPの仕様ではヘッダフィールドと呼ぶ。このヘッダフィールドはレスポンスだけでなく,リクエストにも付加される。telnetだとタイプするのが面倒だから省略したが,ブラウザからWebサーバにリクエストを送ると,リクエストにもヘッダが付加され,ブラウザのバージョンなどの情報をサーバに通知できるようになっている。この内容はサーバやクライアントの動作にも影響する重要なものだが,ひとまずレスポンスの全体像を見るために,説明は省略する(表3)。
次に,また1行空白行がある。これがレスポンスの制御情報の終わりを表す。リクエストのときも空白行が終わりを表したが,それと同じである。
そして,その後に続く<html>から</html>までの行が読み出したファイルの中身である。HTTPではこれをエンティティと呼ぶ。ブラウザでWebサーバにアクセスすると,この部分がHTMLのタグのルールに従ってレイアウトされて画面に表示されることになる(図5c)。
実験ではファイルの中身にいわゆるHTMLドキュメントを入れておいたが,ファイルの中身はHTMLドキュメントである必要はない。テキストファイルでもよいし,画像ファイルや音声のデータファイルやプログラムの実行形式のようなバイナリデータが入っているファイルでもよい。要するに,何でもよいのだ。HTTPはファイルの中身をそのまま送るだけである。そして,ファイルの中身がどういうデータであるのかを,ヘッダのContent-Typeというフィールドに格納する。実験ではファイルの中身がHTMLドキュメントだったので,これが"text/html"となっているが,テキストファイルであれば"text/plain"となるし,画像データなら"image/gif"や"image/jpeg"となる。(*7)。
また,レスポンスに付加されるヘッダフィールドはWebサーバによって異なる。いろいろなバージョンのWebサーバで試してみると,その違いがわかる。これが結構面白い。
表2 HTTPのステータスコードの概要
|
コード
|
意味
|
|
1xx
|
処理の経過状況などを通知する。
|
|
2xx
|
正常終了。
|
|
3xx
|
何らかの別のアクションが必要であることを表す。
|
|
4xx
|
クライアント側のエラー。
|
|
5xx
|
サーバ側のエラー。
|
表3 HTTPで使われるヘッダフィールド
|
ヘッダフィールドの種類
|
HTTPのバージョン
|
意味
|
|
1.0
|
1.1
|
|
ジェネラルヘッダ(リクエストとレスポンスの両方で使われるヘッダフィールド)
|
|
Date
|
○
|
○
|
リクエストやレスポンスが作成された日時を表す。
|
|
Pragma
|
○
|
○
|
データのキャッシュを許すか否かといった,通信オプションを表す。
|
|
Cache-Control
|
|
○
|
キャッシュを制御するための情報。
|
|
Connection
|
|
○
|
レスポンス送信後にTCPの接続を継続するか切断するか,といった通信オプションの指定。
|
|
Transfer-Encoding
|
|
○
|
メッセージ本体のエンコディング方式。
|
|
Upgrade
|
|
○
|
HTTP/1.1以外のプロトコルに切り替える。
|
|
Via
|
|
○
|
途中経由したプロキシやゲートウェイが記録される。
|
|
MIME-Version
|
△
|
|
Content-Typeなどで使用するMIMEのバージョンを表す。
|
|
リクエストヘッダ(リクエストの付加情報として使われるヘッダフィールド)
|
|
Authorization
|
○
|
○
|
ユーザ認証用のデータ。
|
|
From
|
○
|
○
|
リクエスト発信者のメールアドレス。
|
|
If-Modified-Since
|
○
|
○
|
ある日時以降情報が更新されてる場合だけリクエストを実行したいときに,フィールド値としてその日時を指定する。通常,クライアント側にキャッシュした情報と比較して,それが古くなった場合に新しい情報を受け取りたい,というときに使う。
|
|
Referer
|
○
|
○
|
ハイパーリンクをたどって次のページを読み込む場合などに,リンク元となったURIを表す。
|
|
User-Agent
|
○
|
○
|
クライアントソフトウェアの名称やバージョンに関する情報。
|
|
Accept
|
△
|
○
|
クライアント側がContent-Typeとして受け取れるデータの種類。MIME仕様のデータタイプで表現したもの。
|
|
Accept-Charset
|
△
|
○
|
クライアント側が受け取れる文字コードセット。
|
|
Accept-Encoding
|
△
|
○
|
クライアント側がContent-Encodingとして受け取れるエンコーディング方式。通常データ圧縮の形式を表す。
|
|
Accept-Language
|
△
|
○
|
クライアント側が受け取れる言語の種類。日本語はja,英語はen。
|
|
Host
|
|
○
|
リクエストを受けるサーバのIPアドレスとポート番号。
|
|
If-Match
|
|
○
|
Etagを参照。
|
|
If-None-Match
|
|
○
|
Etagを参照。
|
|
If-Range
|
|
○
|
もし,情報が更新されていない場合はRangeで指定した範囲の情報を,そうでなければ情報全体をリクエストする。If-Rangeのフィールド値には,前回レスポンスの日付かEtagを指定する。
|
|
If-Unmodified-Since
|
|
○
|
指定した日時以降更新がなかった場合だけリクエストを実行する。
|
|
Max-Forwards
|
|
○
|
TRACEメソッドと一緒に使用し,途中経由するプロキシやゲートウェイの数の上限を指定する。
|
|
Proxy-Authorization
|
|
○
|
Proxy-Authenticateによってプロキシからユーザ認証を要求されたときに,ユーザ認証情報をプロキシに通知するときに使う。
|
|
Range
|
|
○
|
データの全体ではなく一部分だけ読み出すときに,その範囲を指定する。
|
|
レスポンスヘッダ(レスポンスの付加情報として使われるヘッダフィールド)
|
|
Location
|
○
|
○
|
情報の正確な場所を表す。リクエストのURIが相対名などで指定された場合などに,絶対名での情報の位置を通知するために用いる。
|
|
Server
|
○
|
○
|
サーバソフトウェアの名称やバージョンに関する情報。
|
|
WWW-Authenticate
|
○
|
○
|
リクエストされた情報へのアクセスが制限されている場合に,ユーザ認証用のデータ(チャレンジなど)を返送する。
|
|
Accept-Ranges
|
|
○
|
データの一部だけリクエストするRange指定があった場合,サーバがその機能を持っているかをクライアントに通知する。
|
|
Age
|
|
○
|
キャッシュされたデータが古くなっていないかどうかを判断するためのデータ。
|
|
Proxy-Authenticate
|
|
○
|
WWW-Authenticateと同様のものだが,プロキシがクライアントに対して送信する。
|
|
Public
|
|
○
|
サーバが受け付けられるメソッドの一覧をクライアントに通知する。
|
|
Retry-After
|
△
|
○
|
サーバがサービスできない状態にあるとき,サービス再開の予定時刻,あるいは所要時間を通知する。
|
|
Vary
|
|
○
|
言語,文字コードなどの表現形式が複数許されている場合のネゴシエーションで,サーバがその中からどれを選択したかを通知する。
|
|
Warning
|
|
○
|
レスポンスのステータスに関する付加情報。主に警告を表す。
|
|
Alternates
|
|
△
|
言語や文字コードなど,他に許されるものがないかどうか問い合わせるときに使う。
|
|
エンティティヘッダ(エンティティの付加情報として使われるヘッダフィールド)
|
|
Allow
|
○
|
○
|
指定したURIで使用可能なメソッドを表す。
|
|
Content-Encoding
|
○
|
○
|
エンティティに圧縮などのエンコーディング処理が施されている場合に,その方式を表す。
|
|
Content-Length
|
○
|
○
|
エンティティの長さを表す。
|
|
Content-Type
|
○
|
○
|
エンティティがどのようなデータであるか,その種類を表す。MIME仕様で定義されたデータタイプでデータの種類を表す。
|
|
Expires
|
○
|
○
|
エンティティの有効期限を表す。
|
|
Last-Modified
|
○
|
○
|
情報の最終更新日時。
|
|
Content-Base
|
|
○
|
Content-Locationなどが相対名によるURIで表されている場合に,その基点となる位置を表す。
|
|
Content-Language
|
|
○
|
エンティティの言語を表す。日本語の場合はja,英語の場合はen。
|
|
Content-Location
|
|
○
|
エンティティがサーバ上のどこに置かれていたか,その位置をURIで表したもの。
|
|
Content-MD5
|
|
○
|
通信エラーや途中の改ざんを検出するための情報。MD5というアルゴリズムで生成したもの。
|
|
Content-Range
|
|
○
|
データの全体ではなく一部分がリクエストされたとき,エンティティにどの範囲のデータが含まれているかを表す。
|
|
Etag
|
|
○
|
更新処理などで,前回のリクエストのレスポンスを元にした更新データを次のリクエストで送信するような場合があるが,そのとき,前回のレスポンスと次のリクエストを関連付けるために使用する情報。前回のレスポンスでサーバがEtagによってユニークな値をクライアントに渡し,次回リクエストのIf-Match,If-None-Match,If-Rangeフィールドでその値をサーバに通知すれば,サーバは前回の続きだと認識してくれる。
|
|
Content-Version
|
|
△
|
エンティティのバージョン。
|
|
Derived-From
|
|
△
|
PUTやPATCHメソッドで情報を更新するときに,更新の元となったバージョンを表す。
|
|
Link
|
|
△
|
複数の情報の間の関連を表す。
|
|
URI
|
△
|
△
|
以前,ミラーサーバなどの場所を示すために使われたが,Location,Content-Location,Vary,Alternatesなどに置き換えられるため,今後は使われない。
|
|
Title
|
△
|
|
情報のタイトル。
|
○:仕様として定義されているもの。△:正式な仕様ではなく付加機能としてAppendixに記述されているもの。
ブラウザとサーバの役割
こうして,HTTPの基本的な仕組みがわかると,Webサーバとブラウザの役割も自ずと見えてくる。
ブラウザはURLの入力欄にURLが入力されたり,HTMLドキュメント中に埋め込まれたハイパーリンクがクリックされたときに,それをHTTPのGETというメソッドを使ってサーバにリクエストを送る。すると,サーバはそのリクエストの内容を調べて指定されたファイルを読み出し,それをHTTPのレスポンスとしてブラウザに返す。レスポンスを受け取ったブラウザはHTMLドキュメントのタグを調べて,ドキュメントをレイアウトして画面に表示するのだ。
ドキュメント中に画像などが埋め込まれている場合はどうだろう。HTTPではURIは一つしか指定できないから,文章と画像を一度にリクエストすることはできない。そこで,まずHTMLで書いた文章をリクエストし,それを受け取ってから中に埋め込まれた画像を調べ,それをサーバにリクエストするのである。ブラウザはHTMLドキュメントの受信が終わる前に,受信した部分に埋め込まれた画像を調べ,それをリクエストする。これを受信動作と並行して実行する。見かけ上は文章の表示と画像の表示が同時に行われるが,その内部ではこのような仕掛けでサーバとのやり取りが行われているのだ。
こういった仕組みがわかると,個々の技術要素がどのように関連して全体のシステムができあがるのかがわかる。逆にいえば,個々の技術要素を理解しなければ,システムの具体的な動作は見えてこないのである。
WWWの使い方は単純なページの表示だけでなく,フォームによってデータをサーバに送信したり,バックエンドのデータベースと連動したり,掲示板のように定期的に表示するページを更新したり,ページプロキシサーバやファイアウォールを使ったり,自動巡回ソフトでWebサーバからページデータを一括ダウンロードしたり,といったようにいろいろなバリエーションがある。今回は単純なページ読み出しの,しかも,そのさわりの部分しか試せなかったが,そうしたバリエーションはまた別の機会に試してみたい。
次回以降も,このような形で実験を通してインターネットやネットワークの技術を紹介していく予定だ。
(*1)
過去の経験では,難しい技術は製品開発や技術サポートなどあらゆる部分でコスト高になり,結局普及しないことが多い。もちろん例外もある。
(*2)
確かに,RFCの中には分厚く難解なものもある。それは,書いてある技術の内容自身が複雑で難解なのが原因であることが多い。そういった技術は,結局,他の解説書を読んでもすぐには理解できないので,時間をかけて少しずつ理解していくしかない。
(*3)
telnetは画面スクロール,カーソル移動,文字の反転や高輝度表示といった画面制御コードを受け付けることもできるが,そうした画面表示の変化によって,相手からのデータを判読するのは難しい。また,そういった制御コードは,接続相手がその意味で使っているとは限らない。だから,端末として使う本来の用途以外では文字データ以外のデータの受信は実用性がないといえる。また,telnetからデータを送信する場合,CTRLキーと一緒にアルファベットキーを押すと,制御コードを送信することもできる。たとえば,CTRLとAを一緒に押せば,16進表記で'01'のデータを送信できるし,CTRLとBを押せば'02'を送信できる。C以降も同様だ。しかし,それで送信できるデータには限りがあるので,自由にバイナリデータを送信できるわけではない。やはり文字データ以外は限界がある。
(*4)
もちろん,プロキシサーバやファイアウォールを使うといった,バリエーションもあるから基本動作だけがすべてではない
(*5)
HTTPはプロキシサーバやファイアウォールを考慮して作られている点が特徴であり,また,プロキーサーバやファイアウォールもHTTPに対応していないものはない。だから,そうした環境でC/Sモデルを実現する際にはHTTPが便利だといえる。それがHTTPを使用する例が増えている理由といえる。
(*6)
CGIプログラムのようにプログラムを呼び出したりするものもあり,ファイルを指定するものだとは限らない。しかし,そこまで考えると複雑になるので,今回はファイル以外のものは考えないことにする。
(*7)
このデータの種類を表す方法には,メールでも使われるMIMEという仕様が使われる |