Go4Expert

Go4Expert (http://www.go4expert.com/)
-   Perl (http://www.go4expert.com/articles/perl-tutorials/)
-   -   Proxy using Perl (http://www.go4expert.com/articles/proxy-using-perl-t1130/)

pradeep 5Aug2006 15:20

Proxy using Perl
 
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: Perl

#!/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";
 }


aems 2Mar2007 15:10

Re: Proxy using Perl
 
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.

pradeep 2Mar2007 15:16

Re: Proxy using Perl
 
You need to upgrade the module named "threads", use cpan from your shell to install the latest version of the threads module.

aems 2Mar2007 16:16

Re: Proxy using Perl
 
how to use cpan.

please help me step by step.

pradeep 2Mar2007 16:23

Re: Proxy using Perl
 
Type "cpan" at the shell prompt, and then type "install threads"

It'll download the module and install it.

aems 3Mar2007 06:55

Re: Proxy using Perl
 
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.

johnny 25Jul2007 19:12

Re: Proxy using Perl
 
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?

pradeep 25Jul2007 19:18

Re: Proxy using Perl
 
Set a system level proxy!

johnny 25Jul2007 19:38

Re: Proxy using Perl
 
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...

johnny 25Jul2007 19:39

Re: Proxy using Perl
 
i'll send u the code wch i have written if u want me to..?

alfa 3Jul2009 02:58

Re: Proxy using Perl
 
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

pradeep 3Jul2009 10:01

Re: Proxy using Perl
 
Try this http://search.cpan.org/~book/HTTP-Pr.../HTTP/Proxy.pm

alfa 3Jul2009 20:17

Re: Proxy using Perl
 
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


All times are GMT +5.5. The time now is 01:37.