Proxy using Perl

Discussion in 'Perl' started by pradeep, Aug 5, 2006.

  1. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in
    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";
     }
     
     
  2. aems

    aems New Member

    Joined:
    Mar 2, 2007
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    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.
     
  3. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in
    You need to upgrade the module named "threads", use cpan from your shell to install the latest version of the threads module.
     
  4. aems

    aems New Member

    Joined:
    Mar 2, 2007
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    how to use cpan.

    please help me step by step.
     
  5. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in
    Type "cpan" at the shell prompt, and then type "install threads"

    It'll download the module and install it.
     
  6. aems

    aems New Member

    Joined:
    Mar 2, 2007
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    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.
     
  7. johnny

    johnny New Member

    Joined:
    Jul 25, 2007
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    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?
     
  8. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in
    Set a system level proxy!
     
  9. johnny

    johnny New Member

    Joined:
    Jul 25, 2007
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    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...
     
  10. johnny

    johnny New Member

    Joined:
    Jul 25, 2007
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    i'll send u the code wch i have written if u want me to..?
     
  11. alfa

    alfa New Member

    Joined:
    Jun 29, 2009
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    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
     
  12. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in
  13. alfa

    alfa New Member

    Joined:
    Jun 29, 2009
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    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
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice