ncatで遊んでみる

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&amp;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/ にアクセスしたら

f:id:fjkz:20160713000501p:plain

ちゃんと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 はテキストベースで、すごい単純なプロトコルであることが見える。もっと良いプロトコルがあるに違いないが、現実的にはこういう単純で原始的なプロトコルを組み合わせると、今の巨大なインターネットになると思うと、なんとも感慨深いものがある。