in reply to Asyncron Https-Requests with HTTP::Async

If you read the description of Crypt::SSLeay modules, then you'll see that it is written for LWP. So it won't work with other modules. As far as I can see, the HTTP::Async does not support the use of SSL. In general, there's module Net::SSLeay::Handle that provides a wrapper for connections with SSL, but the use of it has to be added to HTTP::Async. I don't know if there are other modules that support async handling of http over SSL.

  • Comment on Re: Asyncron Https-Requests with HTTP::Async

Replies are listed 'Best First'.
Re^2: Asyncron Https-Requests with HTTP::Async
by andal (Hermit) on Oct 14, 2010 at 15:42 UTC

    I've done some hacking and looks like I've found a way to fool the HTTP::Async into using IO::Socket::SSL. Below you'll find my module MyHacks.pm and an example how to use it.

    package MyHacks; use Errno; use Net::HTTP::Methods; use IO::Socket::SSL; my $old_read_entity = \&Net::HTTP::Methods::read_entity_body; my $old_read_response = \&Net::HTTP::Methods::read_response_headers; *Net::HTTP::Methods::my_readline = \&my_readline; *Net::HTTP::Methods::my_read = \&my_read; *Net::HTTP::Methods::read_entity_body = \&my_read_entity; *Net::HTTP::Methods::read_response_headers = \&my_read_response; sub my_read_response { my @vals = eval {$old_read_response->(@_);}; if($@) { return if($@ =~ /^Non-blocking/); die $@; } return @vals; } sub my_read_entity { my $val = eval {$old_read_entity->(@_);}; if($@) { return if($@ =~ /^Non-blocking/); die $@; } return $val; } sub my_read { die if @_ > 3; my $self = shift; my $len = $_[1]; for (${*$self}{'http_buf'}) { if (length) { $_[0] = substr($_, 0, $len, ""); return length($_[0]); } else { my $n = $self->sysread($_[0], $len); die "Non-blocking\n" if (!defined $n && $!{EAGAIN}); return $n; } } } sub my_readline { my $self = shift; my $what = shift; for (${*$self}{'http_buf'}) { my $max_line_length = ${*$self}{'http_max_line_length'}; my $pos; while (1) { # find line ending $pos = index($_, "\012"); last if $pos >= 0; die "$what line too long (limit is $max_line_length)" if $max_line_length && length($_) > $max_line_length; # need to read more data to find a line ending READ: { my $n = $self->sysread($_, 1024, length); unless (defined $n) { redo READ if $!{EINTR}; die "Non-blocking\n" if ($!{EAGAIN}); # if we have already accumulated some data let's a +t least # return that as a line die "$what read failed: $!" unless length; } unless ($n) { return undef unless length; return substr($_, 0, length, ""); } } } die "$what line too long ($pos; limit is $max_line_length)" if $max_line_length && $pos > $max_line_length; my $line = substr($_, 0, $pos+1, ""); $line =~ s/(\015?\012)\z// || die "Assert"; return wantarray ? ($line, $1) : $line; } } package Net::HTTP::NB; use vars qw(@ISA); @ISA = qw(Net::HTTP); sub new { my $class = shift; my %args = @_; return Net::HTTPS->new(@_) if($args{PeerPort} == 443); return $class->SUPER::new(@_); } package Net::HTTPS; use vars qw(@ISA); @ISA = qw(IO::Socket::SSL Net::HTTP::Methods); sub configure { my($self, $cnf) = @_; $self->http_configure($cnf); } sub http_connect { my($self, $cnf) = @_; $self->SUPER::configure($cnf); } 1;

    And the example

    #!/usr/bin/perl # important, the MyHacks must be the first! use MyHacks; use HTTP::Async; use HTTP::Request; my $async = HTTP::Async->new; $async->add( HTTP::Request->new( GET => 'https://mail.google.com/') ); while( my $resp = $async->wait_for_next_response ) { print "Got: ", $resp->code, " ", $resp->message, "\n"; }

    As usually. Try at your own risk. No warranties.

      Hello andal,
      thank you very much for your help. :-)
      I'm going to try out your hacking. I'm going to inform you how it works on my server.

        I don't know if you still need it. Anyway, I've created small HTTP parser module that can be used to parse HTTP protocol (either requests or responses). This module does not care where the data comes from, so you can open either regular connection or use IO::Socket::SSL to open secure connection and then simply pass the obtained chunks of data to the parser and get from it the pieces of parsed information.

        The module is available at http://vandal.sdf-eu.org/HttpProto.pm Just save it into file. The perldoc on that file shall give you detailed usage information.

        I feel, it is cleaner to use this module than the hack I've provided in previous message :)

        Hi andal,
        after a few month in action I can say that your skript works well for my requirement.
        Thanks!