達人が語る,インフラエンジニアの心得

第18回 プロトコルを覚えよう[その2:HTTP編]

この記事を読むのに必要な時間:およそ 4 分

手で打って覚えるHTTP

ではさっそく,HTTPの実例を見てみましょう。

$ telnet www.google.com 80
Trying 64.233.183.103...
Connected to www.google.com (64.233.183.103).
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.0 302 Found
Location: http://www.google.co.jp/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=dcd5652deaacf010:FF=0:TM=1303887216:LM=1303887216:S=cUNIWkuapqmEMcb3; expires=Fri, 26-Apr-2013 06:53:36 GMT; path=/; domain=.google.com
Date: Wed, 27 Apr 2011 06:53:36 GMT
Server: gws
Content-Length: 221
X-XSS-Protection: 1; mode=block

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.jp/">here</A>.
</BODY></HTML>
Connection closed by foreign host.

上記は,www.google.comに対してHTTP/1.0でHOSTヘッダもコンテントネゴシエーションもなしで接続した例です。

  GET / HTTP/1.0
  (空行)

というのが,クライアントが送信している(telnetで入力している)部分になります。あくまで,空行の入力があって,リクエストと解釈されるので注意が必要です。

それに対して,

  HTTP/1.0 302 Found

というレスポンスが返ってきています。これはかいつまんで言うと,LocationヘッダにあるURLにリダイレクトしなさい,という意味になります。

Locationヘッダを見てみると,

  Location: http://www.google.co.jp/

とありますので,通常ブラウザであればこのURLに接続し直すことになります。

HTTP/1.1での接続(1)

次に,www.google.comに対してHTTP/1.1でHOSTヘッダも付けて接続してみましょう。

$ telnet www.google.com 80
Trying 64.233.183.99...
Connected to www.google.com (64.233.183.99).
Escape character is '^]'.
GET / HTTP/1.1
HOST: www.google.com

HTTP/1.1 302 Found
Location: http://www.google.co.jp/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=7eab6b7eed7f7842:FF=0:TM=1303887994:LM=1303887994:S=4XH2bEZxD6t-DcEL; expires=Fri, 26-Apr-2013 07:06:34 GMT; path=/; domain=.google.com
Date: Wed, 27 Apr 2011 07:06:34 GMT
Server: gws
Content-Length: 221
X-XSS-Protection: 1; mode=block

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.jp/">here</A>.
</BODY></HTML>

ほとんど同じ内容になっていますが微妙に違います。

  GET / HTTP/1.1
  HOST: www.google.com
  (空行)

が,クライアントから送信している(手入力した)部分です。空行を送るまではヘッダ扱いされます。

レスポンスもほとんど一緒ですが,違いとしては,HTTP/1.0の時はコネクションが切断されていた(Connection closed by foreign host.とtelnetがいっている)のに対し,今回はされていないということです(Connection closed by foreign host.はあくまでtelnetの出力でHTTPメッセージではありません⁠⁠。

ちなみにこういう場合,どうやって切断するかですが,telnetクライアントはたいてい CTRL-] というシーケンスを送ると接続を切断して

  telnet>

というプロンプトになるので,そこでquitと入れて終了するか,もしくは適当にHTTPで解釈されない送信(a 一文字など)を送ればBad Requestとして切断されます。

HTTP/1.1での接続(2)

さらに続いて,Keep-Aliveでないことを宣言してHTTP/1.1にて接続してみましょう。

$ telnet www.google.com 80
Trying 64.233.183.105...
Connected to www.google.com (64.233.183.105).
Escape character is '^]'.
GET / HTTP/1.1
HOST: www.google.com
Connection: close

HTTP/1.1 302 Found
Location: http://www.google.co.jp/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=a967b73bc9b997b2:FF=0:TM=1303888386:LM=1303888386:S=xpUUMjtShIblnhJM; expires=Fri, 26-Apr-2013 07:13:06 GMT; path=/; domain=.google.com
Date: Wed, 27 Apr 2011 07:13:06 GMT
Server: gws
Content-Length: 221
X-XSS-Protection: 1; mode=block
Connection: close

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.jp/">here</A>.
</BODY></HTML>
Connection closed by foreign host.

今回の例では,

  GET / HTTP/1.1
  HOST: www.google.com
  Connection: close
 (空行)

という内容をリクエストとして送っています。すると,レスポンスが返ったあとに接続が切断されていることがわかります。

この例で重要なのは,telnetの引数に入れているホスト名と,HOSTヘッダで指定しているホスト名は「別にすることが可能」ということです。やろうと思えば,googleでないサーバに接続してgoogleのホスト名を指定することもできます。検証においてはこの「別にすることが可能」というのはとても重宝します(とはいっても自分に関係ないホストでやるのは良くないことですが⁠⁠。

今回は非常にざっくりですが,HTTPについて解説してみました。実際には他にもさまざまなヘッダやリクエスト,そしてレスポンスがあるので,ぜひいろいろと勉強してみてください。

著者プロフィール

山崎徳之(やまざきのりゆき)

青山学院大学卒業後,アスキー,So-netなどでネットワーク,サーバエンジニアを経験。オン・ザ・エッヂ(現ライブドア)のデータセンターである「データホテル」を構築,運営。2003年にベイエリアにおいてVoIPベンチャーであるRedSIP Inc.を創業。2006年6月に株式会社ゼロスタートコミュニケーションズ(現 ZETA株式会社)を設立,代表取締役就任(現任)。ECソリューションの「ZETA CX」シリーズとして検索エンジンやレコメンドエンジンを開発,販売している。

blog:http://blog.zaki.jp/
社長コラム:https://zetacx.com/column