ncatという超便利コマンドを恥ずかしながらいままで知らなかった。HTTPプロトコルを学ぶには最適なおもちゃだ。
www.example.com の 80番ポートに、 / を GET するという HTTP リクエストを投げてみる。
fjk@x240:~$ ncat www.example.com 80 << END GET / HTTP/1.1 Host: www.example.com END
すると、以下のような HTTP レスポンスが返ってくる。200番のステータスコードが帰ってきているので、リクエストはうまいこといったようだ。いろいろヘッダーフィールドについているが、こう見ると HTTP プロトコルはテキストを送って返すだけという非常に単純なプロトコルなことが分かる。
HTTP/1.1 200 OK Accept-Ranges: bytes Cache-Control: max-age=604800 Content-Type: text/html Date: Tue, 12 Jul 2016 14:47:58 GMT Etag: "359670651" Expires: Tue, 19 Jul 2016 14:47:58 GMT Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT Server: ECS (rhv/818F) Vary: Accept-Encoding X-Cache: HIT x-ec-custom-error: 1 Content-Length: 1270 <!doctype html> <html> <head> <title>Example Domain</title> 以下略
www.google.com に GET を投げると 302 が帰ってきた。
fjk@x240:~$ ncat www.google.com 80 << END GET / HTTP/1.1 Host: www.google.com END HTTP/1.1 302 Found Cache-Control: private Content-Type: text/html; charset=UTF-8 Location: http://www.google.co.jp/?gfe_rd=cr&ei=-AKFV4uqMq7U8AeQ67-IBA Content-Length: 261 Date: Tue, 12 Jul 2016 14:47:20 GMT <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/?gfe_rd=cr&ei=-AKFV4uqMq7U8AeQ67-IBA">here</A>. </BODY></HTML>
http://www.google.co.jp/?gfe_rd=cr&ei=-AKFV4uqMq7U8AeQ67-IBA に移動しているらしい。この文字列の意味は ncat では分からない。
ncatはソケットにリクエストを投げるだけでなくて、リクエストを待つことができる。
fjk@x240:~$ sudo ncat -l -p 8000 << END HTTP/1.1 200 OK <HTML><HEAD></HEAD><BODY><H1>HELLO WORLD</H1></BODY></HTML> END
としたら、8000番ポートに接続されたときに、 HTTPレスポンスを返す。ブラウザで http://localhost:8000/ にアクセスしたら
ちゃんとWebサーバーっぽい動きをしている。
リクエスト内容は標準出力に吐かれる。
GET / HTTP/1.1 Host: localhost:8000 Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: ja,en-US;q=0.8,en;q=0.6
Google Chrome は HTTP 1.1 でリクエストを投げて、Chrome のバージョンもリクエストに乗せていることが分かる。
試してみると、HTTP はテキストベースで、すごい単純なプロトコルであることが見える。もっと良いプロトコルがあるに違いないが、現実的にはこういう単純で原始的なプロトコルを組み合わせると、今の巨大なインターネットになると思うと、なんとも感慨深いものがある。