1

I am trying to send multiple HTTP get requests using Perl. I need to send those request using sock proxy.

If I use following code, I am able to send a request with sock proxy

#!/usr/bin/perl

use strict;

use LWP::UserAgent;

my $ua = LWP::UserAgent->new(
    agent => q{Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.2.0; .NET CLR 1.1.4322)},
);
$ua->proxy([qw/ http https /] => 'socks://localhost:9050'); # Tor proxy
#$ua->cookie_jar({});

$a = 10;
while ( $a < 20 ) {
    my $rsp = $ua->get('http://example.com/type?parameter=1&parameter=2');
    print $rsp->content;
    $a = $a + 1;
}

It works successfully but I need to use AnyEvent to send multiple GET requests in parallel

#!/usr/bin/perl

use strict;

use AnyEvent;
use AnyEvent::HTTP;
use Time::HiRes qw(time);
use LWP::Protocol::socks;
use AnyEvent::Socket;

my $cv = AnyEvent->condvar( cb => sub {
    warn "done";
});

my $urls = [
    "http://url-1-withallparameters",
    "http://url-2-withallparameters",
    "http://url-3-withallparameters",
];

my $start = time;
my $result;

$cv->begin(sub { shift->send($result) });

for my $url ( @$urls ) {

    $cv->begin;
    my $now = time;
    my $request;

    $request = http_request(
        GET => $url, 
        timeout => 2, # seconds
        sub {
            my ($body, $hdr) = @_;

            if ($hdr->{Status} =~ /^2/) {
                push (@$result,
                        join("\t",
                        ($url,
                        " has length ",
                        $hdr->{'content-length'}, 
                        " and loaded in ",
                        time - $now,
                        "ms"))
                );
            }
            else {
                push (@$result,
                        join("",
                        "Error for ",
                        $url,
                        ": (", 
                        $hdr->{Status}, 
                        ") ", 
                        $hdr->{Reason})
                );
            }

            undef $request;
            $cv->end;
        }
    );
}

$cv->end;
warn "End of loop\n";

my $foo = $cv->recv;

print join("\n", @$foo), "\n" if defined $foo;
print "Total elapsed time: ", time-$start, "ms\n";

This is working fine but I am not able to send these requests using sock proxy.

Even in the terminal, if I export proxy commands like curl and wget they work fine with sock proxy, but when I use a Perl command to execute this script as a sock proxy it does not work.

I could integrate it with LWP::UserAgent but it is not working with AnyEvent.

I have used

proxy => [ $host, $port ],

below

GET => $url, 

but it works for HTTP and HTTPS proxy only, not for sock proxy. This url is working for HTTP/HTTPS proxy but not for sock proxy.

Borodin
  • 126,100
  • 9
  • 70
  • 144
Derek
  • 9
  • 2
  • 2
    Don't use `$a`, it's a reserved variable for `sort`. – simbabque May 11 '18 at 15:41
  • That will be great help from your side or alternatively you can suggest a method where I can send multiple parallel http requests with sock proxy as fast as AnyEvent. I did not know any other module which sends request as fast as AnyEvent. – Derek May 12 '18 at 07:00
  • @Derek: There are already modules that support this. Did you read my answer? – Borodin May 12 '18 at 07:25
  • Yes already stared working on it. Someone suggested to add functionality in existing module so I was expecting a script but comment is removed. – Derek May 12 '18 at 16:34
  • Re "*I did not know any other module which sends request as fast as AnyEvent.*", LWP is slow, being completely written in Perl. [Net::Curl](http://search.cpan.org/perldoc?Net::Curl) uses the very fast libcurl library. It can even do parallel requests (using [Net::Curl::Multi](http://search.cpan.org/perldoc?Net::Curl::Multi)). – ikegami May 12 '18 at 21:48

1 Answers1

1

The documentation for AnyEvent::HTTP has this

Socks proxies are not directly supported by AnyEvent::HTTP

If you read that section it may describe a workaround that suits you

Alternatively, take a look at AnyEvent::HTTP::Socks which says

This module adds new ‘socks’ option to all http_* functions exported by AnyEvent::HTTP. So you can specify socks proxy for HTTP requests.

Or AnyEvent::HTTP::LWP::UserAgent which should allow you to use ideas from the working LWP::UserAgent code that you already have

Borodin
  • 126,100
  • 9
  • 70
  • 144