use Net::SSLeay qw( die_now die_if_ssl_error ); Net::SSLeay::load_error_strings(); eval 'no warnings "redefine"; sub Net::SSLeay::load_error_strings () {} '; die $@ if $@; Net::SSLeay::SSLeay_add_ssl_algorithms(); eval 'no warnings "redefine"; sub Net::SSLeay::SSLeay_add_ssl_algorithms () {} '; die $@ if $@; Net::SSLeay::ENGINE_load_builtin_engines(); eval 'no warnings "redefine"; sub Net::SSLeay::ENGINE_load_builtin_engines () {} '; die $@ if $@; Net::SSLeay::ENGINE_register_all_complete(); eval 'no warnings "redefine"; sub Net::SSLeay::ENGINE_register_all_complete () {} '; die $@ if $@; Net::SSLeay::randomize(); eval 'no warnings "redefine"; sub Net::SSLeay::randomize (;$$) {} '; die $@ if $@; #### my $socket = IO::Socket::INET->new( PeerAddr => $host, PeerPort => 'https(443)', AutoFlush => 1, Blocking => 0, Proto => 'tcp' ) or die "can't connect to https server"; #### my $ctx = Net::SSLeay::CTX_new() or die("Failed to create SSL_CTX $!"); Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL) and ssl_check_die("ssl ctx set options"); my $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!"); #### sub ssl_get_error { my $errors = ""; my $errnos = []; while(my $errno = Net::SSLeay::ERR_get_error()) { push @$errnos, $errno; $errors .= Net::SSLeay::ERR_error_string($errno) . "\n"; } return $errors, $errnos if wantarray; return $errors; } sub ssl_check_die { my ($message) = @_; my ($errors, $errnos) = ssl_get_error(); die "${message}: ${errors}" if @$errnos; return; } #### Net::SSLeay::set_fd($ssl, fileno($socket)); my $res = Net::SSLeay::connect($ssl) and Net::SSLeay::die_if_ssl_error("ssl connect"); if($res < 0){ # Here the connect failed because the exchange is not complete; # continue to select on this socket and retry every time the # socket selects true until it succeeds. return; } else { # Here the connect is complete. This is where to but the code # that changes the "select" handler for the socket for the next # phase (writing the data). } #### my $written = $ssl->write(substr($cur_buff, $cur_count)); if($written <= 0){ unless($! eq "Resource temporarily unavailable"){ ## An error has occurred - recovery code goes here } return; } $cur_count += $written; if($cur_count == length($cur_buff)){ $cur_count = 0; $cur_buff = undef; ### We have emptied the current buffer ### Here is where code specific to select dispatcher ### must determine whether we have written all the data... } #### my $res = CORE::shutdown $socket, 1; #### my $rb = $ssl->read(16384); ssl_check_die("SSL read"); if(undefined($rb) or length($rb) <= 0){ unless($! eq "Resource temporarily unavailable"){ ## Here we are done - do whatever is necessary to ## shutdown select dispatcher and close sockets, release ## ssl and context } if($rb){ ## you have read some data in $rb -- do something with it } } #### Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); $socket->close();