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

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.

Replies are listed 'Best First'.
Re^3: Asyncron Https-Requests with HTTP::Async
by atmosfearpete (Initiate) on Oct 15, 2010 at 09:41 UTC
    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!