ソケット通信の勉強として、HTTPでHTMLを取得するコンソールブラウザみたいなものを、perlで作ってみました。
アプリケーション層のみの実装でいいので、かなり簡単にできてしまうんです。
次回はこれを利用して、動的IPのチェックスクリプトみたいなものを作ろうと思います。
実行は以下のように、URLを第一引数にとって実行します。
./browser.pl http://www.google.cp.jp/
実行するとHTMLのソースが標準出力されます。
ソースは以下。
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
use FileHandle;
my ($host, $port, $path, $sockaddr, $http_ver, $uri);
my @URI_data;
$uri = $ARGV[0];
$http_ver = '1.1';
$host = 'localhost';
$port = getservbyname('http', 'tcp');
$path = '/';
############################
###### メインルーチン ######
############################
### URIを解析 ###
@URI_data = &URI_analy($#ARGV,$uri);
$host = @URI_data[0];
$port = @URI_data[1];
$path = @URI_data[2];
### ソケット生成 ###
$sockaddr = &socket_create($host,$port);
### ソケット通信開始 ###
&socket_connect($sockaddr);
### HTTPと通信 ###
&http_request_get($http_ver,$host.$path);
### ソケット通信終了###
close(SOCKET);
##########################
###### サブルーチン ######
##########################
### URIを解析 ###
sub URI_analy
{
my $host, $port, $path;
if($_[0] == 0)
{
die "Usage:$0 URI\n";
}
else
{
$_[1] =~ m!(http:)?(//)?([^:/]*)?(:([0-9]+)?)?(/.*)?!;
if($3)
{
$host = $3;
}
if($5)
{
$port = $5;
}
if($6)
{
$path = $6;
}
}
@URI_data = ($host,$port,$path);
return @URI_data;
}
### ソケット生成 ###
sub socket_create
{
my $ip, $sockaddr;
local(*host, *port) = $_;
$ip = inet_aton($host) || die "host($host) not found.\n";
$sockaddr = pack_sockaddr_in($port, $ip);
return $sockaddr;
}
### ソケット通信開始 ###
sub socket_connect
{
local(*sockaddr) = $_;
socket(SOCKET, PF_INET, SOCK_STREAM, 0) || die "Error(socket).\n";
connect(SOCKET, $sockaddr) || die "Error(connect).\n";
autoflush SOCKET (1);
}
### HTTPと通信 ###
sub http_request_get
{
local(*http_ver, *host, *path) = $_;
if($http_ver eq '1.1')
{
print SOCKET "GET $path HTTP/1.1\n";
print SOCKET "Host: $host\n";
print SOCKET "Connection: close\n\n";
}
else
{
print SOCKET "GET $path HTTP/1.0\n\n";
}
while(chomp($_=<SOCKET>))
{
print "$_\n";
}
}