Simple HTTP Proxy in Perl.... - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Simple HTTP Proxy in Perl....

gregstergregster Posts: 7Member
Here's a very simple proxy I wrote in Perl. It works fine except when it gets pages sending it a 302 HTTP status response. The client doesn't bother to submit a new request:

#!/usr/bin/perl -w

use IO::Socket;

$SIG{PIPE} = "IGNORE";

my $proxy_port=shift(@ARGV);
$proxy_port=8080 unless $proxy_port =~ /d+/;
my $hostname=`hostname`;
chop $hostname;

# Setup socket
$sock = new IO::Socket::INET (LocalHost => $hostname,
LocalPort => $proxy_port,
Proto => 'tcp',
Listen => 5,
Reuse => 1
);
die "Listening Socket could not be created: $!" unless $sock;

while (1) {
# Accept connection request
print "Waiting for connection request....

";

##$client_sock = $sock->accept() || die "accept $!";
accept ($client_sock, $sock)) || die "accept $!";

# Create child process
if (fork) {
wait;
next;
}
$clientaddr = getpeername $client_sock ;
($port,$iaddr) = sockaddr_in($clientaddr);
$clientname = gethostbyaddr ($iaddr, AF_INET);
print "Received Connection Request from: ".inet_ntoa($iaddr)."
";
open CLOG, ">/tmp/clientlog".inet_ntoa($iaddr).".txt" || die "couldn't create client log txt";
open SLOG, ">/tmp/serverlog".inet_ntoa($iaddr).".txt" || die "couldn't create server log txt";
close CLOG; close SLOG;

# Receive first line of request which is then modified by analyze_request
$firstline = <$client_sock>;
print "*********** HTTP request ************
";
print $firstline;
open CLOG, ">/tmp/clientlog".inet_ntoa($iaddr).".txt" || die "couldn't create client log txt";
print CLOG $firstline;
close CLOG;
($modifiedfirstline,$remote_host,$remote_port,$method)=analyze_request($firstline);
$server_sock=server_connect($remote_host,$remote_port);
print $server_sock $modifiedfirstline;
print "Sent following HTTP request to server:
$modifiedfirstline";
while (<$client_sock>) {
print $_;
next if (/Proxy-Connection:/);
print $server_sock $_;
last if ($_ =~ /^[sx00]*$/);
}
if ($method eq "POST") {
$data = <$client_sock>;
print $data;
print $server_sock $data;
}
print $server_sock "
";
print "HTTP Request sent. Here's the response:

";
listen_for_response($server_sock, $client_sock);
# finished sending response to client, close sockets
close $client_sock;
close $server_sock;
exit;
}

sub analyze_request {
($request)=@_;
#print "Received this request:
$request
";
if ($request =~ m#(GET|POST|HEAD) http://([^/:]+):?(d*)#) {
$method=$1;
$remote_host=$2;
$remote_port=$3;
#print "Recognized HTTP request
";
}

print "Received $method request for remote_host $remote_host at port $remote_port...
";

# Remove remote hostname from URL
$request =~ s/http://[^/]+//;

return $request,$remote_host,$remote_port,$method;
}

sub server_connect {
($remote_host,$remote_port) = @_;
if ($remote_port !~ /^d+$/) {
$remote_port = (getservbyname($remote_port, "tcp"))[2];
$remote_port = 80;
}
$server_sock = new IO::Socket::INET (PeerAddr => $remote_host,
PeerPort => $remote_port,
Proto => 'tcp',
);
die "Server Socket could not be created: $!" unless $server_sock;
print "Connected to server $remote_host at port $remote_port";
return $server_sock;
}

sub listen_for_response {
($server_sock, $client_sock) = @_;
while ($buf = <$server_sock>) {
print $buf;
open SLOG, ">>/tmp/serverlog".inet_ntoa($iaddr).".txt" || die "couldn't create server log txt";
print SLOG $buf;
close SLOG;
print $client_sock $buf;
}
print "Finished receiving...
";
}


Sign In or Register to comment.