I was wondering whether its possible to write a program which acts like a proxy server in Perl, so what I figured out was anything is possible with Perl. Below is the code, try it, its wonderful. I used threads to manage multiple requests, so the program can handle multiple requests concurrently. More can be done with IO::Socket in Perl. Code: #!/usr/bin/perl #use strict; use URI; use IO::Socket; use threads('yield', 'stack_size' => 64*4096); # don't want to die on 'Broken pipe' or Ctrl-C $SIG{PIPE} = 'IGNORE'; my $showOpenedSockets=1; my $server = IO::Socket::INET->new ( LocalPort => 8080, Type => SOCK_STREAM, Reuse => 1, Listen => 18); binmode $server; while (my $browsera = $server->accept()) { print "\n\n----Accepted Connection--------\n"; binmode $browsera; my $t = threads->new(\&fetch, $browsera); $t->detach; } sub fetch{ my $browser = $_[0]; my $method =""; my $content_length = 0; my $content = 0; my $accu_content_length = 0; my $host; my $hostAddr; my $httpVer; while (my $browser_line = <$browser>) { unless ($method) { ($method, $hostAddr, $httpVer) = $browser_line =~ /^(\w+) +(\S+) +(\S+)/; print "$hostAddr"; my $uri = URI->new($hostAddr) or print "Could not build URI for $hostAddr"; $host = IO::Socket::INET->new ( PeerAddr=> $uri->host, PeerPort=> $uri->port ); die "couldn't open $hostAddr" unless $host; if ($showOpenedSockets) { print "Opened ".$uri->host." , port ".$uri->port."\n"; } binmode $host; print $host "$method ".$uri->path_query." $httpVer\n"; print "$method ".$uri->path_query." $httpVer\n"; next; } $content_length = $1 if $browser_line=~/Content-length: +(\d+)/i; $accu_content_length+=length $browser_line; #print $browser_line; print $host $browser_line; last if $browser_line =~ /^\s*$/ and $method ne 'POST'; if ($browser_line =~ /^\s*$/ and $method eq "POST") { $content = 1; last unless $content_length; next; } if ($content) { $accu_content_length+=length $browser_line; last if $accu_content_length >= $content_length; } } print "\n\nThread id --> ".threads->self->tid()."\n"; print "No of. threads at present --> ".threads->list()."\n"; print "Stack size --> ".threads->get_stack_size()."\n"; $content_length = 0; $content = 0; $accu_content_length = 0; while (my $host_line = <$host>) { #print $host_line; print $browser $host_line; $content_length = $1 if $host_line=~/Content-length: +(\d+)/i; if ($host_line =~ m/^\s*$/ and not $content) { $content = 1; #last unless $content_length; next; } if ($content) { if ($content_length) { $accu_content_length+=length $host_line; #print "\nContent Length: $content_length, accu: $accu_content_length\n"; last if $accu_content_length >= $content_length; } } } $browser-> close; $host -> close; print "---- End thread ----\n"; }
i have error on linux redhat 9 this error: threads version 262144 required--this is only version 0.99 at /usr/lib/perl5/5.8.0/Exporter/Heavy.pm line 121. how to solve this problem. Thank for help.
You need to upgrade the module named "threads", use cpan from your shell to install the latest version of the threads module.
Type "cpan" at the shell prompt, and then type "install threads" It'll download the module and install it.
it work !!! Thank for help. i use this Proxy for audio streaming when i close program such as "winamp" but threads is not Terminated. Thank for help again.
Hello Pradeep! Great code.. pradeep . i have written a code using which i can send emails to a list of ids using smtp. now i wana enhance the code.. i wana send the email through a proxy server. how can i .. can u plz help me?
hello pradeep! Do u mean i want me tamper the configuration of the system? can i be done through a code? i've tried masking...
Thank you Mr.Pradeep for perl proxy.. Um using ur code for a project. We suppose to analyze the request from the browser before it reach the proxy..problem is we need to forward the web request to the Squid proxy running in the localhost in port 3128 (default)..i have tried many things, but unable to reach a perfect output.? could anyone help... Thanks in advance.. alfa
thank u very for ur quick reply Mr.Pradeep..prevsly i tried that method (HTTP::Proxy)..but i need to see the request and file types send by the browser so ur code was well suited for that purpose..then i edited ur code to achive my target.. ur code was $host = IO::Socket::INET->new ( PeerAddr=> $uri->host, PeerPort=> $uri->port); my Squid is running in localhost port 3128 so i replaced above like this $host = IO::Socket::INET->new ( PeerAddr=> "127.0.0.1", PeerPort=> 3128); i didnt changed anything then i run the code and configure the browser proxy for 0.0.0.0:8080 i got the reply from Squid but only error messages like Ileagal URL,..so i hope the request is going to Squid..but not the full URL is writen to Squid..coz some times error messages shows When trying to retrive the URL:/webhp?hl=en .. i didnt clearly understand the following part ///////////////////////////////////////// binmode host print $host "$method ".$uri->path_query." $httpVer\n"; print "$method ".$uri->path_query." $httpVer\n"; next; //////////////////////////////////////////// i think this is the portion where u writing the request to socket..if i could write the full request here then i hope i can send the full URL to SQUID.. Any suggestions.. to do that Thank u very