HTTP(Hypertext Transfer Protocol)は、WWWの主要なプロトコルであり、ブラウザ(クライアント)から送られたリクエストと、それに対するサーバーからの応答データを運ぶ時に使われます。そのデータの中には普通にブラウザで見ている時には表示されないものもあります。
telnetを使ってWebサーバーからデータを得ることで、その見えない情報を得ることが可能です。HTTPヘッダと呼ばれるそれを、telnetを使用して見てみましょう。
ここではHTTP/1.1を使用することにします。ただしHTTP/1.1アプリケーションはチャンク形式のデコードができなければならない
そうなのですが、HTTP/1.1が標準化されたのは1999年、Windows 98付属のtelnet.exeは開発が1998年以前のはずですから、サポートしていない可能性があります。そもそも、telnetのクライアントがHTTPアプリケーションのための仕様をサポートしている様なことはないと思いますが。
しかし今回のような用途(HTTPヘッダのみの取得)に限って言えば、どちらであっても関係はないはずですが。ただしメッセージボディも取得する(具体的にはGETメソッドを使用する)場合は、HTTP/1.0を使用するようにした方が無難でしょう。
基本的な設定としては、「ローカルエコー」オン、「漢字コード」不定(見るページのエンコードに合わせる。本サイトはシフトJISです)、「エミュレーション」VT-100/漢字です。エンターキーを押下したときに送信するコードを変更できるクライアントをお使いの場合は、CRLFを送るようにしておきます。設定の仕方は[クライアントの設定・基本操作]を参照して下さい。
設定できたら早速つないでみましょう。「接続」―「リモートシステム」を選んで下さい。標準ではHTTPのポート番号は80なので、それを使用します。
ここでは旧Use telnetのWebサーバーに接続してみます。
正しく接続できたらtelnetのタイトルバーに接続先のホスト名が表示されます。(この状態でも接続できていないことがあるようです。)
このように表示されない場合は接続に失敗している可能性があります。ホスト名、ポート番号を確認して再度接続し直して下さい。
HTTPはクライアントからのリクエストとサーバーからのレスポンスから成っています。リクエストはメッセージヘッダとメッセージボディから成り、ヘッダはリクエストラインと複数のヘッダフィールドから成ります。リクエストラインは、メソッド、リクエストURI、HTTPバージョンによって構成されます。メソッドは他のプロトコルでいうコマンドのようなものと考えて下さい。
リクエストラインのフォーマットは次のようになります(SPはスペースを表します)。
Method SP Request-URI SP HTTP-Version CRLF
リクエストラインの後にヘッダとメッセージボディが続きます。
以下はHTTP/1.1のメソッド一覧です。
メソッド | 機能 |
---|---|
OPTIONS | 使用できるメソッドやオプションの一覧を取得します。 |
GET | URIで指定したリソースを取得します。 |
HEAD | URIで指定したリソースのレスポンスヘッダのみを取得します。 |
POST | URIで指定したサーバーのコマンドに対してデーターを転送します。 |
PUT | URIで指定したリソースを、転送するデータで置き換えます。 |
DELETE | URIで指定したりソースを削除します。 |
TRACE | サーバーやプロクシの動作を診断するための情報を返答します。 |
CONNECT | プロクシをトンネルに切り替えます。 |
GETとHEAD以外のメソッドは実装が強制されていないので、使えないこともあります。とくにPUTやDELETEは危険なので使えることはほとんどないと思います。
またHTTP/1.1では、Hostフィールドが必須となっています。これは仮想ホストに対応するためです。
ヘッダフィールドのフォーマットは次のようになります。
field-name ":" [ field-value ]
ヘッダフィールドにどんなものがあるかの説明は省きます。
HTTPについてはRFC 2616に書かれています。また、HTTPやそれに関する技術の解説を行っているサイトにStudying HTTPがあります。HTTPについてもっと詳しく知りたい人はご覧になってみて下さい。
では実際にはどういう風になるのか、流れを示したいと思います。
まず接続します。DOSプロンプト等から[クライアントの設定・基本操作]で示した手順でtelnetを起動させ、接続して下さい。接続に成功するとtelnetのタイトルバーに接続先ホストが表示されます。
接続に成功したらリクエストを送ってみます。CRLFは空行を表しています。
HEAD /index.html HTTP/1.1
Host:use-telnet.port5.com
Connection:close
CRLF
HTTP/1.1 200 OK
Date: Mon, 28 Jan 2002 09:01:36 GMT
Server: Apache/1.3.14 (Unix) PHP/4.0.0
Last-Modified: Mon, 14 Jan 2002 10:39:24 GMT
ETag: "154651-1a2f-3c42b55c"
Accept-Ranges: bytes
Content-Length: 6703
Connection: close
Content-Type: text/html
CRLF
上のように表示された後、勝手に接続が切れたと思います。なぜならそのように指定したからです。多分ないと思いますが、もし切れなかったとしたらサーバーの実装ミスです。
1行目のリクエストラインのHEADメソッドは、「リクエスト」の項に書いてあるように、URIで指定したリソースのレスポンス(リクエストに対する応答のこと)ヘッダのみを取得するメソッドです。つまり"HTTP/1.1 200 OK"と書かれた行以降がレスポンスヘッダということです。この場合メッセージボディは空です。もしGETメソッドを使っていれば、メッセージボディにはHTMLファイルの内容が入っていたことでしょう。
メソッドの次にリクエストするリソースのURI、そしてHTTPのバージョンを指定します。HTTP/1.1の場合、プロクシ等を通していなければ、基本的にリクエストURIには絶対パスを使います。この場合、続くHostヘッダフィールド値によってリソースの取得先ホストが決定します。もしリクエストURIを絶対URIで指定すると、Hostヘッダフィールド値は無視されます。接続先サーバーはホスト決定に使用されないことに注意して下さい。
リクエストラインの下がヘッダフィールドです。ヘッダフィールドには一般ヘッダ、リクエストヘッダ、エンティティヘッダがありますが、その中で唯一必須となっているのがリクエストヘッダのHostヘッダフィールドです(理由と機能については既述)。
HTTP/1.1で採用された「持続的接続」という機能のために、それまでは1リクエスト毎にTCP接続を確立していたのが、明示的に閉じることを指定しない限り接続を維持することが可能になりました。
ただ、ここでの目的はあくまでもヘッダを取得することであり、接続を維持しても意味がないので、Connectionヘッダフィールドにclose値を与えて、レスポンス終了後に接続を閉じるよう指定しています。
普段ブラウザを使ってWebを見ているときは目にすることはありませんが、HTTPを通してこのような情報がサーバーとクライアントの間では交わされており、この情報を元にHTTPクライアントやサーバーはより適切な(=クライアント(ユーザー)が望む)リソースを選択しているのです。