CPANPLUS
view release on metacpan or search on metacpan
inc/bundle/HTTP/Tiny.pm view on Meta::CPAN
# behavior if someone is unable to boostrap CPAN from a new perl install; it is
# not intended for general, per-client use and may be removed in the future
my $SOCKET_CLASS =
$ENV{PERL_HTTP_TINY_IPV4_ONLY} ? 'IO::Socket::INET' :
eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.32) } ? 'IO::Socket::IP' :
'IO::Socket::INET';
sub BUFSIZE () { 32768 } ## no critic
my $Printable = sub {
local $_ = shift;
s/\r/\\r/g;
s/\n/\\n/g;
s/\t/\\t/g;
s/([^\x20-\x7E])/sprintf('\\x%.2X', ord($1))/ge;
$_;
};
my $Token = qr/[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]/;
my $Field_Content = qr/[[:print:]]+ (?: [\x20\x09]+ [[:print:]]+ )*/x;
sub new {
my ($class, %args) = @_;
return bless {
rbuf => '',
timeout => 60,
max_line_size => 16384,
max_header_lines => 64,
verify_SSL => HTTP::Tiny::_verify_SSL_default(),
SSL_options => {},
%args
}, $class;
}
sub timeout {
my ($self, $timeout) = @_;
if ( @_ > 1 ) {
$self->{timeout} = $timeout;
if ( $self->{fh} && $self->{fh}->can('timeout') ) {
$self->{fh}->timeout($timeout);
}
}
return $self->{timeout};
}
sub connect {
@_ == 5 || die(q/Usage: $handle->connect(scheme, host, port, peer)/ . "\n");
my ($self, $scheme, $host, $port, $peer) = @_;
if ( $scheme eq 'https' ) {
$self->_assert_ssl;
}
$self->{fh} = $SOCKET_CLASS->new(
PeerHost => $peer,
PeerPort => $port,
$self->{local_address} ?
( LocalAddr => $self->{local_address} ) : (),
Proto => 'tcp',
Type => SOCK_STREAM,
Timeout => $self->{timeout},
) or die(qq/Could not connect to '$host:$port': $@\n/);
binmode($self->{fh})
or die(qq/Could not binmode() socket: '$!'\n/);
if ( $self->{keep_alive} ) {
unless ( defined( $self->{fh}->setsockopt( SOL_SOCKET, SO_KEEPALIVE, 1 ) ) ) {
CORE::close($self->{fh});
die(qq/Could not set SO_KEEPALIVE on socket: '$!'\n/);
}
}
$self->start_ssl($host) if $scheme eq 'https';
$self->{scheme} = $scheme;
$self->{host} = $host;
$self->{peer} = $peer;
$self->{port} = $port;
$self->{pid} = $$;
$self->{tid} = _get_tid();
return $self;
}
sub connected {
my ($self) = @_;
if ( $self->{fh} && $self->{fh}->connected ) {
return wantarray
? ( $self->{fh}->peerhost, $self->{fh}->peerport )
: join( ':', $self->{fh}->peerhost, $self->{fh}->peerport );
}
return;
}
sub start_ssl {
my ($self, $host) = @_;
# As this might be used via CONNECT after an SSL session
# to a proxy, we shut down any existing SSL before attempting
# the handshake
if ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
unless ( $self->{fh}->stop_SSL ) {
my $ssl_err = IO::Socket::SSL->errstr;
die(qq/Error halting prior SSL connection: $ssl_err/);
}
}
my $ssl_args = $self->_ssl_args($host);
IO::Socket::SSL->start_SSL(
$self->{fh},
%$ssl_args,
SSL_create_ctx_callback => sub {
my $ctx = shift;
Net::SSLeay::CTX_set_mode($ctx, Net::SSLeay::MODE_AUTO_RETRY());
},
);
unless ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
my $ssl_err = IO::Socket::SSL->errstr;
die(qq/SSL connection failed for $host: $ssl_err\n/);
( run in 2.454 seconds using v1.01-cache-2.11-cpan-437f7b0c052 )