LWP::Simpleのソースをちょっと読んだ
この前、LWP::Simpleのソース読んだんだけど、LWPってPurePerlで実装されているということを知った。
低レイヤーな部分はCで書かれているのかと思っていたけど、ネットワーク通信の処理部分はIO::Socketとかで実装されてた。
getを呼び出すと、_getが呼ばれて、その中で分岐があるけど、おそらく_trivial_http_getが呼ばれる。
この_trival_http_getで、指定したURLからデータを取得するコアな処理が行われる。
例えば、
IO::Socket::INET->newでファイルハンドル($sock)を作成したり・・
require IO::Socket; local($^W) = 0; my $sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'tcp', Timeout => 60) || return undef;
取得したファイルハンドル($sock)にHTTPのRequestを出力したり・・
print $sock join("\015\012" => "GET $path HTTP/1.0", "Host: $netloc", "User-Agent: lwp-trivial/$VERSION", "", "");
sysreadでファイルハンドル($sock)から結果を読み取ったり・・
1 while $n = sysread($sock, $buf, 8*1024, length($buf));
しています。
あとはsysreadで読み込んだ値をreturnするんだけど、$bufの値を見て、レスポンスがLocation:〜なんて値だった場合は、_getを呼び出してリダイレクト処理もしたりする。
昔からネットワーク通信の低レイヤーな部分はどうなっているのか気になっていて(リクエストを送信してから、結果が返ってくるまでの処理はどうなってるのかとかとかとか・・)、LWPのソースを読めば何か分かるかと思いましたが、複雑な処理は抽象化されていて、まるで標準出力に読み書きしているようですね!
んー・・確か,最近の日経Linuxか何かにCでソケット通信するプログラムのこと書いた記事があったなぁ。Webサーバを連載で作っていくやつ。それ読んだほうが、ネットワーク通信の低レイヤー処理についての謎ははっきりするかも。
ソケット!ソケット!:-)