Perl と生ソケットを用いて、HTTP プロキシサーバを書いてみました。接続のハンドリングを行うのみで、chunked なコンテンツなどには一切対応していません。そんな無骨なプロキシサーバのソースコードメモ。ソケットを 2 本使って、listen/connect しているだけです。ここから改造すればいいのかなぁ。
#!/usr/bin/perl
$|++;
use strict;
use Socket;
use constant SERVER_PORT => 8080;
# 待ち受け用ソケット生成
socket SOCKET, PF_INET, SOCK_STREAM, getprotobyname ('tcp')
or die;
binmode SOCKET;
# ポートにbind
bind SOCKET, sockaddr_in (SERVER_PORT, INADDR_ANY)
or die;
# ソケットをlisten
listen SOCKET, SOMAXCONN
or die;
while (1) {
# 待ち受け
accept CLIENT, SOCKET
or die;
binmode CLIENT;
### Data: Client -> Proxy Server
print "-------- REQUEST --------
";
my ($buf, $request);
do {
recv CLIENT, $buf, 1024, 0
or last;
print $buf;
$request .= $buf;
} while (1024 == length $buf);
print "
";
# Parsing/Modifing
$request =~ s!^(GET|POST) http://([^/]+)(/S*) (HTTP/d+.d+)!$1 $3 $4!;
my ($host, $port) = $2 =~ m!(.+)(?::(d+))?!;
$port ||= 80;
# サーバ問い合わせ用ソケット生成
socket SOCKET2, PF_INET, SOCK_STREAM, getprotobyname ('tcp')
or die;
binmode SOCKET2;
# サーバに接続
connect SOCKET2, sockaddr_in ($port, inet_aton ($host))
or die;
### Data: Proxy Server -> Target Server
send SOCKET2, $request, 0
or die;
### Data: Target Server -> Proxy Server
print "-------- RESPONCE --------
";
my ($responce);
do {
recv SOCKET2, $buf, 1024, 0
or last;
print length $buf, "
";
$responce .= $buf;
} while (1024 == length $buf);
print "
";
# 後始末
close SOCKET2;
### Data: Proxy Server -> Client
send CLIENT, $responce, 0
or die;
# 後始末
close CLIENT;
}
# 後始末
close SOCKET;