App-cpanminus
view release on metacpan or search on metacpan
lib/App/cpanminus/fatscript.pm view on Meta::CPAN
=head1 AUTHOR
David Golden <dagolden@cpan.org>
=head1 CONTRIBUTORS
=over 4
=item *
Diab Jerius <djerius@cfa.harvard.edu>
=item *
Graham Ollis <plicease@cpan.org>
=back
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2014 by David A Golden.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004
=cut
__END__
# vim: ts=4 sts=4 sw=4 et:
FILE_PUSHD
$fatpacked{"HTTP/Tiny.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'HTTP_TINY';
# vim: ts=4 sts=4 sw=4 et:
package HTTP::Tiny;
use strict;
use warnings;
# ABSTRACT: A small, simple, correct HTTP/1.1 client
our $VERSION = '0.056';
use Carp ();
#pod =method new
#pod
#pod $http = HTTP::Tiny->new( %attributes );
#pod
#pod This constructor returns a new HTTP::Tiny object. Valid attributes include:
#pod
#pod =for :list
#pod * C<agent> â
#pod A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If C<agent> â ends in a space character, the default user-agent string is appended.
#pod * C<cookie_jar> â
#pod An instance of L<HTTP::CookieJar> â or equivalent class that supports the C<add> and C<cookie_header> methods
#pod * C<default_headers> â
#pod A hashref of default headers to apply to requests
#pod * C<local_address> â
#pod The local IP address to bind to
#pod * C<keep_alive> â
#pod Whether to reuse the last connection (if for the same scheme, host and port) (defaults to 1)
#pod * C<max_redirect> â
#pod Maximum number of redirects allowed (defaults to 5)
#pod * C<max_size> â
#pod Maximum response size in bytes (only when not using a data callback). If defined, responses larger than this will return an exception.
#pod * C<http_proxy> â
#pod URL of a proxy server to use for HTTP connections (default is C<$ENV{http_proxy}> â if set)
#pod * C<https_proxy> â
#pod URL of a proxy server to use for HTTPS connections (default is C<$ENV{https_proxy}> â if set)
#pod * C<proxy> â
#pod URL of a generic proxy server for both HTTP and HTTPS connections (default is C<$ENV{all_proxy}> â if set)
#pod * C<no_proxy> â
#pod List of domain suffixes that should not be proxied. Must be a comma-separated string or an array reference. (default is C<$ENV{no_proxy}> â)
#pod * C<timeout> â
#pod Request timeout in seconds (default is 60)
#pod * C<verify_SSL> â
#pod A boolean that indicates whether to validate the SSL certificate of an C<https> â
#pod connection (default is false)
#pod * C<SSL_options> â
#pod A hashref of C<SSL_*> â options to pass through to L<IO::Socket::SSL>
#pod
#pod Passing an explicit C<undef> for C<proxy>, C<http_proxy> or C<https_proxy> will
#pod prevent getting the corresponding proxies from the environment.
#pod
#pod Exceptions from C<max_size>, C<timeout> or other errors will result in a
#pod pseudo-HTTP status code of 599 and a reason of "Internal Exception". The
#pod content field in the response will contain the text of the exception.
#pod
#pod The C<keep_alive> parameter enables a persistent connection, but only to a
#pod single destination scheme, host and port. Also, if any connection-relevant
#pod attributes are modified, or if the process ID or thread ID change, the
#pod persistent connection will be dropped. If you want persistent connections
#pod across multiple destinations, use multiple HTTP::Tiny objects.
#pod
#pod See L</SSL SUPPORT> for more on the C<verify_SSL> and C<SSL_options> attributes.
#pod
#pod =cut
my @attributes;
BEGIN {
@attributes = qw(
cookie_jar default_headers http_proxy https_proxy keep_alive
local_address max_redirect max_size proxy no_proxy timeout
SSL_options verify_SSL
);
my %persist_ok = map {; $_ => 1 } qw(
cookie_jar default_headers max_redirect max_size
);
no strict 'refs';
no warnings 'uninitialized';
for my $accessor ( @attributes ) {
*{$accessor} = sub {
@_ > 1
? do {
delete $_[0]->{handle} if !$persist_ok{$accessor} && $_[1] ne $_[0]->{$accessor};
$_[0]->{$accessor} = $_[1]
}
: $_[0]->{$accessor};
};
}
}
sub agent {
my($self, $agent) = @_;
if( @_ > 1 ){
$self->{agent} =
(defined $agent && $agent =~ / $/) ? $agent . $self->_agent : $agent;
}
return $self->{agent};
}
sub new {
my($class, %args) = @_;
my $self = {
max_redirect => 5,
timeout => 60,
keep_alive => 1,
verify_SSL => $args{verify_SSL} || $args{verify_ssl} || 0, # no verification by default
no_proxy => $ENV{no_proxy},
};
bless $self, $class;
$class->_validate_cookie_jar( $args{cookie_jar} ) if $args{cookie_jar};
for my $key ( @attributes ) {
$self->{$key} = $args{$key} if exists $args{$key}
}
$self->agent( exists $args{agent} ? $args{agent} : $class->_agent );
$self->_set_proxies;
return $self;
}
sub _set_proxies {
my ($self) = @_;
# get proxies from %ENV only if not provided; explicit undef will disable
# getting proxies from the environment
# generic proxy
if (! exists $self->{proxy} ) {
$self->{proxy} = $ENV{all_proxy} || $ENV{ALL_PROXY};
}
if ( defined $self->{proxy} ) {
$self->_split_proxy( 'generic proxy' => $self->{proxy} ); # validate
}
else {
delete $self->{proxy};
}
# http proxy
if (! exists $self->{http_proxy} ) {
# under CGI, bypass HTTP_PROXY as request sets it from Proxy header
local $ENV{HTTP_PROXY} if $ENV{REQUEST_METHOD};
$self->{http_proxy} = $ENV{http_proxy} || $ENV{HTTP_PROXY} || $self->{proxy};
}
if ( defined $self->{http_proxy} ) {
$self->_split_proxy( http_proxy => $self->{http_proxy} ); # validate
$self->{_has_proxy}{http} = 1;
}
else {
delete $self->{http_proxy};
}
# https proxy
if (! exists $self->{https_proxy} ) {
$self->{https_proxy} = $ENV{https_proxy} || $ENV{HTTPS_PROXY} || $self->{proxy};
}
if ( $self->{https_proxy} ) {
$self->_split_proxy( https_proxy => $self->{https_proxy} ); # validate
$self->{_has_proxy}{https} = 1;
lib/App/cpanminus/fatscript.pm view on Meta::CPAN
https => 443,
);
sub _agent {
my $class = ref($_[0]) || $_[0];
(my $default_agent = $class) =~ s{::}{-}g;
return $default_agent . "/" . $class->VERSION;
}
sub _request {
my ($self, $method, $url, $args) = @_;
my ($scheme, $host, $port, $path_query, $auth) = $self->_split_url($url);
my $request = {
method => $method,
scheme => $scheme,
host => $host,
port => $port,
host_port => ($port == $DefaultPort{$scheme} ? $host : "$host:$port"),
uri => $path_query,
headers => {},
};
# We remove the cached handle so it is not reused in the case of redirect.
# If all is well, it will be recached at the end of _request. We only
# reuse for the same scheme, host and port
my $handle = delete $self->{handle};
if ( $handle ) {
unless ( $handle->can_reuse( $scheme, $host, $port ) ) {
$handle->close;
undef $handle;
}
}
$handle ||= $self->_open_handle( $request, $scheme, $host, $port );
$self->_prepare_headers_and_cb($request, $args, $url, $auth);
$handle->write_request($request);
my $response;
do { $response = $handle->read_response_header }
until (substr($response->{status},0,1) ne '1');
$self->_update_cookie_jar( $url, $response ) if $self->{cookie_jar};
if ( my @redir_args = $self->_maybe_redirect($request, $response, $args) ) {
$handle->close;
return $self->_request(@redir_args, $args);
}
my $known_message_length;
if ($method eq 'HEAD' || $response->{status} =~ /^[23]04/) {
# response has no message body
$known_message_length = 1;
}
else {
my $data_cb = $self->_prepare_data_cb($response, $args);
$known_message_length = $handle->read_body($data_cb, $response);
}
if ( $self->{keep_alive}
&& $known_message_length
&& $response->{protocol} eq 'HTTP/1.1'
&& ($response->{headers}{connection} || '') ne 'close'
) {
$self->{handle} = $handle;
}
else {
$handle->close;
}
$response->{success} = substr( $response->{status}, 0, 1 ) eq '2';
$response->{url} = $url;
return $response;
}
sub _open_handle {
my ($self, $request, $scheme, $host, $port) = @_;
my $handle = HTTP::Tiny::Handle->new(
timeout => $self->{timeout},
SSL_options => $self->{SSL_options},
verify_SSL => $self->{verify_SSL},
local_address => $self->{local_address},
keep_alive => $self->{keep_alive}
);
if ($self->{_has_proxy}{$scheme} && ! grep { $host =~ /\Q$_\E$/ } @{$self->{no_proxy}}) {
return $self->_proxy_connect( $request, $handle );
}
else {
return $handle->connect($scheme, $host, $port);
}
}
sub _proxy_connect {
my ($self, $request, $handle) = @_;
my @proxy_vars;
if ( $request->{scheme} eq 'https' ) {
Carp::croak(qq{No https_proxy defined}) unless $self->{https_proxy};
@proxy_vars = $self->_split_proxy( https_proxy => $self->{https_proxy} );
if ( $proxy_vars[0] eq 'https' ) {
Carp::croak(qq{Can't proxy https over https: $request->{uri} via $self->{https_proxy}});
}
}
else {
Carp::croak(qq{No http_proxy defined}) unless $self->{http_proxy};
@proxy_vars = $self->_split_proxy( http_proxy => $self->{http_proxy} );
}
my ($p_scheme, $p_host, $p_port, $p_auth) = @proxy_vars;
if ( length $p_auth && ! defined $request->{headers}{'proxy-authorization'} ) {
$self->_add_basic_auth_header( $request, 'proxy-authorization' => $p_auth );
}
$handle->connect($p_scheme, $p_host, $p_port);
if ($request->{scheme} eq 'https') {
$self->_create_proxy_tunnel( $request, $handle );
}
else {
# non-tunneled proxy requires absolute URI
$request->{uri} = "$request->{scheme}://$request->{host_port}$request->{uri}";
}
return $handle;
}
sub _split_proxy {
my ($self, $type, $proxy) = @_;
my ($scheme, $host, $port, $path_query, $auth) = eval { $self->_split_url($proxy) };
unless(
defined($scheme) && length($scheme) && length($host) && length($port)
&& $path_query eq '/'
) {
Carp::croak(qq{$type URL must be in format http[s]://[auth@]<host>:<port>/\n});
}
return ($scheme, $host, $port, $auth);
}
sub _create_proxy_tunnel {
my ($self, $request, $handle) = @_;
$handle->_assert_ssl;
my $agent = exists($request->{headers}{'user-agent'})
? $request->{headers}{'user-agent'} : $self->{agent};
my $connect_request = {
method => 'CONNECT',
uri => "$request->{host}:$request->{port}",
headers => {
host => "$request->{host}:$request->{port}",
'user-agent' => $agent,
}
};
if ( $request->{headers}{'proxy-authorization'} ) {
$connect_request->{headers}{'proxy-authorization'} =
delete $request->{headers}{'proxy-authorization'};
}
$handle->write_request($connect_request);
my $response;
do { $response = $handle->read_response_header }
until (substr($response->{status},0,1) ne '1');
# if CONNECT failed, throw the response so it will be
# returned from the original request() method;
unless (substr($response->{status},0,1) eq '2') {
die $response;
}
# tunnel established, so start SSL handshake
$handle->start_ssl( $request->{host} );
return;
}
sub _prepare_headers_and_cb {
my ($self, $request, $args, $url, $auth) = @_;
for ($self->{default_headers}, $args->{headers}) {
next unless defined;
while (my ($k, $v) = each %$_) {
$request->{headers}{lc $k} = $v;
}
}
if (exists $request->{headers}{'host'}) {
die(qq/The 'Host' header must not be provided as header option\n/);
}
$request->{headers}{'host'} = $request->{host_port};
$request->{headers}{'user-agent'} ||= $self->{agent};
$request->{headers}{'connection'} = "close"
unless $self->{keep_alive};
if ( defined $args->{content} ) {
if (ref $args->{content} eq 'CODE') {
$request->{headers}{'content-type'} ||= "application/octet-stream";
$request->{headers}{'transfer-encoding'} = 'chunked'
unless $request->{headers}{'content-length'}
|| $request->{headers}{'transfer-encoding'};
$request->{cb} = $args->{content};
}
elsif ( length $args->{content} ) {
my $content = $args->{content};
if ( $] ge '5.008' ) {
utf8::downgrade($content, 1)
or die(qq/Wide character in request message body\n/);
}
$request->{headers}{'content-type'} ||= "application/octet-stream";
$request->{headers}{'content-length'} = length $content
unless $request->{headers}{'content-length'}
|| $request->{headers}{'transfer-encoding'};
$request->{cb} = sub { substr $content, 0, length $content, '' };
}
$request->{trailer_cb} = $args->{trailer_callback}
if ref $args->{trailer_callback} eq 'CODE';
}
### If we have a cookie jar, then maybe add relevant cookies
if ( $self->{cookie_jar} ) {
my $cookies = $self->cookie_jar->cookie_header( $url );
$request->{headers}{cookie} = $cookies if length $cookies;
}
# if we have Basic auth parameters, add them
if ( length $auth && ! defined $request->{headers}{authorization} ) {
$self->_add_basic_auth_header( $request, 'authorization' => $auth );
}
return;
}
sub _add_basic_auth_header {
my ($self, $request, $header, $auth) = @_;
require MIME::Base64;
$request->{headers}{$header} =
"Basic " . MIME::Base64::encode_base64($auth, "");
return;
}
sub _prepare_data_cb {
my ($self, $response, $args) = @_;
my $data_cb = $args->{data_callback};
$response->{content} = '';
if (!$data_cb || $response->{status} !~ /^2/) {
if (defined $self->{max_size}) {
$data_cb = sub {
$_[1]->{content} .= $_[0];
die(qq/Size of response body exceeds the maximum allowed of $self->{max_size}\n/)
if length $_[1]->{content} > $self->{max_size};
};
}
lib/App/cpanminus/fatscript.pm view on Meta::CPAN
package
HTTP::Tiny::Handle; # hide from PAUSE/indexers
use strict;
use warnings;
use Errno qw[EINTR EPIPE];
use IO::Socket qw[SOCK_STREAM];
# PERL_HTTP_TINY_IPV4_ONLY is a private environment variable to force old
# 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.25) } ? '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]/;
sub new {
my ($class, %args) = @_;
return bless {
rbuf => '',
timeout => 60,
max_line_size => 16384,
max_header_lines => 64,
verify_SSL => 0,
SSL_options => {},
%args
}, $class;
}
sub connect {
@_ == 4 || die(q/Usage: $handle->connect(scheme, host, port)/ . "\n");
my ($self, $scheme, $host, $port) = @_;
if ( $scheme eq 'https' ) {
$self->_assert_ssl;
}
elsif ( $scheme ne 'http' ) {
die(qq/Unsupported URL scheme '$scheme'\n/);
}
$self->{fh} = $SOCKET_CLASS->new(
PeerHost => $host,
PeerPort => $port,
$self->{local_address} ?
( LocalAddr => $self->{local_address} ) : (),
Proto => 'tcp',
Type => SOCK_STREAM,
Timeout => $self->{timeout},
KeepAlive => !!$self->{keep_alive}
) or die(qq/Could not connect to '$host:$port': $@\n/);
binmode($self->{fh})
or die(qq/Could not binmode() socket: '$!'\n/);
$self->start_ssl($host) if $scheme eq 'https';
$self->{scheme} = $scheme;
$self->{host} = $host;
$self->{port} = $port;
$self->{pid} = $$;
$self->{tid} = _get_tid();
return $self;
}
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/);
}
}
sub close {
@_ == 1 || die(q/Usage: $handle->close()/ . "\n");
my ($self) = @_;
CORE::close($self->{fh})
or die(qq/Could not close socket: '$!'\n/);
}
sub write {
@_ == 2 || die(q/Usage: $handle->write(buf)/ . "\n");
my ($self, $buf) = @_;
if ( $] ge '5.008' ) {
utf8::downgrade($buf, 1)
or die(qq/Wide character in write()\n/);
}
lib/App/cpanminus/fatscript.pm view on Meta::CPAN
=head1 SYNOPSIS
use HTTP::Tiny;
my $response = HTTP::Tiny->new->get('http://example.com/');
die "Failed!\n" unless $response->{success};
print "$response->{status} $response->{reason}\n";
while (my ($k, $v) = each %{$response->{headers}}) {
for (ref $v eq 'ARRAY' ? @$v : $v) {
print "$k: $_\n";
}
}
print $response->{content} if length $response->{content};
=head1 DESCRIPTION
This is a very simple HTTP/1.1 client, designed for doing simple
requests without the overhead of a large framework like L<LWP::UserAgent>.
It is more correct and more complete than L<HTTP::Lite>. It supports
proxies and redirection. It also correctly resumes after EINTR.
If L<IO::Socket::IP> 0.25 or later is installed, HTTP::Tiny will use it instead
of L<IO::Socket::INET> for transparent support for both IPv4 and IPv6.
Cookie support requires L<HTTP::CookieJar> or an equivalent class.
=head1 METHODS
=head2 new
$http = HTTP::Tiny->new( %attributes );
This constructor returns a new HTTP::Tiny object. Valid attributes include:
=over 4
=item *
C<agent> â A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If C<agent> â ends in a space character, the default user-agent string is appended.
=item *
C<cookie_jar> â An instance of L<HTTP::CookieJar> â or equivalent class that supports the C<add> and C<cookie_header> methods
=item *
C<default_headers> â A hashref of default headers to apply to requests
=item *
C<local_address> â The local IP address to bind to
=item *
C<keep_alive> â Whether to reuse the last connection (if for the same scheme, host and port) (defaults to 1)
=item *
C<max_redirect> â Maximum number of redirects allowed (defaults to 5)
=item *
C<max_size> â Maximum response size in bytes (only when not using a data callback). If defined, responses larger than this will return an exception.
=item *
C<http_proxy> â URL of a proxy server to use for HTTP connections (default is C<$ENV{http_proxy}> â if set)
=item *
C<https_proxy> â URL of a proxy server to use for HTTPS connections (default is C<$ENV{https_proxy}> â if set)
=item *
C<proxy> â URL of a generic proxy server for both HTTP and HTTPS connections (default is C<$ENV{all_proxy}> â if set)
=item *
C<no_proxy> â List of domain suffixes that should not be proxied. Must be a comma-separated string or an array reference. (default is C<$ENV{no_proxy}> â)
=item *
C<timeout> â Request timeout in seconds (default is 60)
=item *
C<verify_SSL> â A boolean that indicates whether to validate the SSL certificate of an C<https> â connection (default is false)
=item *
C<SSL_options> â A hashref of C<SSL_*> â options to pass through to L<IO::Socket::SSL>
=back
Passing an explicit C<undef> for C<proxy>, C<http_proxy> or C<https_proxy> will
prevent getting the corresponding proxies from the environment.
Exceptions from C<max_size>, C<timeout> or other errors will result in a
pseudo-HTTP status code of 599 and a reason of "Internal Exception". The
content field in the response will contain the text of the exception.
The C<keep_alive> parameter enables a persistent connection, but only to a
single destination scheme, host and port. Also, if any connection-relevant
attributes are modified, or if the process ID or thread ID change, the
persistent connection will be dropped. If you want persistent connections
across multiple destinations, use multiple HTTP::Tiny objects.
See L</SSL SUPPORT> for more on the C<verify_SSL> and C<SSL_options> attributes.
=head2 get|head|put|post|delete
$response = $http->get($url);
$response = $http->get($url, \%options);
$response = $http->head($url);
These methods are shorthand for calling C<request()> for the given method. The
URL must have unsafe characters escaped and international domain names encoded.
See C<request()> for valid options and a description of the response.
The C<success> field of the response will be true if the status code is 2XX.
=head2 post_form
$response = $http->post_form($url, $form_data);
$response = $http->post_form($url, $form_data, \%options);
This method executes a C<POST> request and sends the key/value pairs from a
form data hash or array reference to the given URL with a C<content-type> of
C<application/x-www-form-urlencoded>. If data is provided as an array
reference, the order is preserved; if provided as a hash reference, the terms
are sorted on key and value for consistency. See documentation for the
C<www_form_urlencode> method for details on the encoding.
The URL must have unsafe characters escaped and international domain names
encoded. See C<request()> for valid options and a description of the response.
Any C<content-type> header or content in the options hashref will be ignored.
The C<success> field of the response will be true if the status code is 2XX.
=head2 mirror
$response = $http->mirror($url, $file, \%options)
if ( $response->{success} ) {
print "$file is up to date\n";
}
Executes a C<GET> request for the URL and saves the response body to the file
name provided. The URL must have unsafe characters escaped and international
domain names encoded. If the file already exists, the request will include an
C<If-Modified-Since> header with the modification timestamp of the file. You
may specify a different C<If-Modified-Since> header yourself in the C<<
$options->{headers} >> hash.
The C<success> field of the response will be true if the status code is 2XX
or if the status code is 304 (unmodified).
If the file was modified and the server response includes a properly
formatted C<Last-Modified> header, the file modification time will
be updated accordingly.
=head2 request
lib/App/cpanminus/fatscript.pm view on Meta::CPAN
C<success> â Boolean indicating whether the operation returned a 2XX status code
=item *
C<url> â URL that provided the response. This is the URL of the request unless there were redirections, in which case it is the last URL queried in a redirection chain
=item *
C<status> â The HTTP status code of the response
=item *
C<reason> â The response phrase returned by the server
=item *
C<content> â The body of the response. If the response does not have any content or if a data callback is provided to consume the response body, this will be the empty string
=item *
C<headers> â A hashref of header fields. All header field names will be normalized to be lower case. If a header is repeated, the value will be an arrayref; it will otherwise be a scalar string containing the value
=back
On an exception during the execution of the request, the C<status> field will
contain 599, and the C<content> field will contain the text of the exception.
=head2 www_form_urlencode
$params = $http->www_form_urlencode( $data );
$response = $http->get("http://example.com/query?$params");
This method converts the key/value pairs from a data hash or array reference
into a C<x-www-form-urlencoded> string. The keys and values from the data
reference will be UTF-8 encoded and escaped per RFC 3986. If a value is an
array reference, the key will be repeated with each of the values of the array
reference. If data is provided as a hash reference, the key/value pairs in the
resulting string will be sorted by key and value for consistent ordering.
=head2 can_ssl
$ok = HTTP::Tiny->can_ssl;
($ok, $why) = HTTP::Tiny->can_ssl;
($ok, $why) = $http->can_ssl;
Indicates if SSL support is available. When called as a class object, it
checks for the correct version of L<Net::SSLeay> and L<IO::Socket::SSL>.
When called as an object methods, if C<SSL_verify> is true or if C<SSL_verify_mode>
is set in C<SSL_options>, it checks that a CA file is available.
In scalar context, returns a boolean indicating if SSL is available.
In list context, returns the boolean and a (possibly multi-line) string of
errors indicating why SSL isn't available.
=for Pod::Coverage SSL_options
agent
cookie_jar
default_headers
http_proxy
https_proxy
keep_alive
local_address
max_redirect
max_size
no_proxy
proxy
timeout
verify_SSL
=head1 SSL SUPPORT
Direct C<https> connections are supported only if L<IO::Socket::SSL> 1.56 or
greater and L<Net::SSLeay> 1.49 or greater are installed. An exception will be
thrown if new enough versions of these modules are not installed or if the SSL
encryption fails. You can also use C<HTTP::Tiny::can_ssl()> utility function
that returns boolean to see if the required modules are installed.
An C<https> connection may be made via an C<http> proxy that supports the CONNECT
command (i.e. RFC 2817). You may not proxy C<https> via a proxy that itself
requires C<https> to communicate.
SSL provides two distinct capabilities:
=over 4
=item *
Encrypted communication channel
=item *
Verification of server identity
=back
B<By default, HTTP::Tiny does not verify server identity>.
Server identity verification is controversial and potentially tricky because it
depends on a (usually paid) third-party Certificate Authority (CA) trust model
to validate a certificate as legitimate. This discriminates against servers
with self-signed certificates or certificates signed by free, community-driven
CA's such as L<CAcert.org|http://cacert.org>.
By default, HTTP::Tiny does not make any assumptions about your trust model,
threat level or risk tolerance. It just aims to give you an encrypted channel
when you need one.
Setting the C<verify_SSL> attribute to a true value will make HTTP::Tiny verify
that an SSL connection has a valid SSL certificate corresponding to the host
name of the connection and that the SSL certificate has been verified by a CA.
Assuming you trust the CA, this will protect against a L<man-in-the-middle
attack|http://en.wikipedia.org/wiki/Man-in-the-middle_attack>. If you are
concerned about security, you should enable this option.
Certificate verification requires a file containing trusted CA certificates.
If the L<Mozilla::CA> module is installed, HTTP::Tiny will use the CA file
included with it as a source of trusted CA's. (This means you trust Mozilla,
the author of Mozilla::CA, the CPAN mirror where you got Mozilla::CA, the
toolchain used to install it, and your operating system security, right?)
If that module is not available, then HTTP::Tiny will search several
( run in 1.222 second using v1.01-cache-2.11-cpan-df04353d9ac )