view release on metacpan or search on metacpan
Release notes for HTTP-Tiny
0.090 2024-11-12 11:51:32+01:00 Europe/Brussels
- No changes from 0.089-TRIAL
0.089 2024-10-21 09:35:48+02:00 Europe/Brussels (TRIAL RELEASE)
[CHANGED]
- Find the certificate bundle via IO::Socket::SSL rather than implementing
it in HTTP::Tiny.
- When encoding form data, given a hashref with an arrayref value,
preserve the order of the values in the arrayref rather than sorting.
[DOCS]
- Fixed internal link to "TLS/SSL SUPPORT" section
0.088 2023-07-11 08:52:54-04:00 America/New_York
[FIXED]
- Unsupported scheme errors early without giving an uninitialized value
warning first.
- Sends Content-Length: 0 on empty body PUT/POST. This is not in the spec,
but some servers require this.
- Allows optional status line reason, as clarified in RFC 7230.
- Ignore SIGPIPE on reads as well as writes, as IO::Socket::SSL says that
SSL reads can also send writes as a side effect.
- Check if a server has closed a connection before preserving it for reuse.
[DOCS]
- Clarified that exceptions/errors result in 599 status codes.
[PREREQS]
[FIXED]
- Requests with the empty string as body content no longer generate
'content-type' and 'content-length' headers.
0.029 2013-04-17 13:49:07 America/New_York
[FIXED]
- Checks for new enough OpenSSL library before using SNI (otherwise
IO::Socket::SSL throws warnings)
0.028 2013-03-05 14:11:57 America/New_York
[SUPPORT]
- Fix repository/issue links to reflect proper repo name
0.027 2013-03-05 12:02:58 America/New_York
[SUPPORT]
[FIXED]
- User-specified CA bundles take precedence over Mozilla::CA [Alan
Gardner]
[PREREQS]
- SSL support now requires Net::SSLeay 1.49 or greater to support
auto-retry [Mike Doherty]
- Downgraded IO::Socket::SSL and related prereqs to 'suggests' again
0.023 2012-09-19 09:55:46 America/New_York
[PREREQS]
- IO::Socket::SSL and related prereqs changed to 'required' for dev
release to get better failure diagnostics from CPAN Testers
[TESTING]
- Skip live SSL testing unless IO::Socket::SSL 1.56+ installed
0.022 2012-06-01 23:31:40 America/New_York
[ADDED]
- Supports local_address option to set local socket interface
[Chris Nehren, David Golden]
0.021 2012-05-15 22:38:57 America/New_York
[TESTING]
- Capture prerequisite versions under AUTOMATED_TESTING to help
chase down some failures from CPAN Testers
0.019 2012-05-14 07:14:00 America/New_York
[ADDED]
- Require IO::Socket::SSL 1.56 (which added SSL_hostname support) when
doing HTTPS. [Mike Doherty]
[TESTING]
- Provide better diagnostic output in t/210_live_ssl.t [Mike
Doherty]
0.018 2012-04-18 09:39:50 America/New_York
[ADDED]
- Add verify_SSL option to do more secure SSL operations, incl.
attempting to validate against a CA bundle (Mozilla::CA
recommended, but will attempt to find some OS bundles). Also
add SSL_opts, which passes through IO::Socket::SSL's SSL_*
options to control SSL verification. (GH #6, #9) [Mike Doherty]
- Reponse hashref includes final URL (including any redirections)
[Lukas Eklund]
0.017 2012-02-22 21:57:37 EST5EDT
[DOCUMENTATION]
indexed by PAUSE, which might confuse some installers)
0.010 2011-02-04 02:45:31 EST5EDT
[BUG FIXES]
- Fixed test errors on VMS (RT#65430) [Craig Berry]
0.009 2011-01-17 16:29:22 EST5EDT
- Added workaround for IO::Socket::SSL certificate verification bug
- Minor documentation improvements
- POST example added to the eg/ directory in the distribution tarball
0.008 2011-01-14 06:34:55 EST5EDT
- Added support for direct 'https' connections if IO::Socket::SSL
is installed
- Added support for a callback to provide trailing headers for
chunked transfer encoding
- Data callbacks receive the response hashref as a second argument
for greater flexibility
- Additional limitations documented
"Test::Portability::Files" : "0",
"Test::Spelling" : "0.17",
"Test::Version" : "1",
"perl" : "5.006"
}
},
"runtime" : {
"recommends" : {
"HTTP::CookieJar" : "0.001",
"IO::Socket::IP" : "0.32",
"IO::Socket::SSL" : "1.968",
"Net::SSLeay" : "1.49"
},
"requires" : {
"Carp" : "0",
"Fcntl" : "0",
"IO::Socket" : "0",
"MIME::Base64" : "0",
"Socket" : "0",
"Time::Local" : "0",
"bytes" : "0",
- xt
package:
- DB
provides:
HTTP::Tiny:
file: lib/HTTP/Tiny.pm
version: '0.090'
recommends:
HTTP::CookieJar: '0.001'
IO::Socket::IP: '0.32'
IO::Socket::SSL: '1.968'
Net::SSLeay: '1.49'
requires:
Carp: '0'
Fcntl: '0'
IO::Socket: '0'
MIME::Base64: '0'
Socket: '0'
Time::Local: '0'
bytes: '0'
perl: '5.006'
* "timeout" â Request timeout in seconds (default is 60) If a socket
open, read or write takes longer than the timeout, the request
response status code will be 599.
* "verify_SSL" â A boolean that indicates whether to validate the
TLS/SSL certificate of an "https" â connection (default is true).
Changed from false to true in version 0.083.
* "SSL_options" â A hashref of "SSL_*" â options to pass through to
IO::Socket::SSL
* $ENV{PERL_HTTP_TINY_SSL_INSECURE_BY_DEFAULT} - Changes the default
certificate verification behavior to not check server identity if
set to 1. Only effective if "verify_SSL" is not set. Added in
version 0.083.
An accessor/mutator method exists for each attribute.
Passing an explicit "undef" for "proxy", "http_proxy" or "https_proxy"
will prevent getting the corresponding proxies from the environment.
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.
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 Net::SSLeay and IO::Socket::SSL. When
called as an object methods, if "SSL_verify" is true or if
"SSL_verify_mode" is set in "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.
connected
$host = $http->connected;
"keep_alive" option.
In scalar context, returns the peer host and port, joined with a colon,
or "undef" (if no peer is connected). In list context, returns the peer
host and port or an empty list (if no peer is connected).
Note: This method cannot reliably be used to discover whether the remote
host has closed its end of the socket.
TLS/SSL SUPPORT
Direct "https" connections are supported only if IO::Socket::SSL 1.56 or
greater and Net::SSLeay 1.49 or greater are installed. An error will
occur if new enough versions of these modules are not installed or if
the TLS encryption fails. You can also use HTTP::Tiny::can_ssl() utility
function that returns boolean to see if the required modules are
installed.
An "https" connection may be made via an "http" proxy that supports the
CONNECT command (i.e. RFC 2817). You may not proxy "https" via a proxy
that itself requires "https" to communicate.
Verification is done by checking that that the TLS/SSL connection has a
valid certificate corresponding to the host name of the connection and
that the certificate has been verified by a CA. Assuming you trust the
CA, this will protect against machine-in-the-middle attacks
<http://en.wikipedia.org/wiki/Machine-in-the-middle_attack>.
Certificate verification requires a file or directory containing trusted
CA certificates.
IO::Socket::SSL::default_ca() is called to detect the default location
of your CA certificates. This also supports the environment variables
"SSL_CERT_FILE" and "SSL_CERT_DIR", and will fail over to Mozilla::CA if
no certs are found.
If IO::Socket::SSL::default_ca() is not able to find usable CA
certificates, HTTP::Tiny will search several well-known system-specific
default locations for a CA certificate file as a last resort:
* /etc/ssl/certs/ca-certificates.crt
* /etc/pki/tls/certs/ca-bundle.crt
* /etc/ssl/ca-bundle.pem
* /etc/openssl/certs/ca-certificates.crt
* /etc/pki/tls/cacert.pem
* /etc/certs/ca-certificates.crt
An error will be occur if "verify_SSL" is true and no CA certificate
file is available.
If you desire complete control over TLS/SSL connections, the
"SSL_options" attribute lets you provide a hash reference that will be
passed through to IO::Socket::SSL::start_SSL(), overriding any options
set by HTTP::Tiny. For example, to provide your own trusted CA file:
SSL_options => {
SSL_ca_file => $file_path,
}
The "SSL_options" attribute could also be used for such things as
providing a client certificate for authentication to a server or
controlling the choice of cipher used for the TLS/SSL connection. See
IO::Socket::SSL documentation for details.
PROXY SUPPORT
HTTP::Tiny can proxy both "http" and "https" requests. Only Basic proxy
authorization is supported and it must be provided as part of the proxy
URL: "http://user:pass@proxy.example.com/".
HTTP::Tiny supports the following proxy environment variables:
* http_proxy or HTTP_PROXY
* HTTP::Tiny::UA - Higher level UA features for HTTP::Tiny
* HTTP::Thin - HTTP::Tiny wrapper with HTTP::Request/HTTP::Response
compatibility
* HTTP::Tiny::Mech - Wrap WWW::Mechanize instance in HTTP::Tiny
compatible interface
* IO::Socket::IP - Required for IPv6 support
* IO::Socket::SSL - Required for SSL support
* LWP::UserAgent - If HTTP::Tiny isn't enough for you, this is the
"standard" way to do things
* Net::SSLeay - Required for SSL support
SUPPORT
Bugs / Feature Requests
Please report any bugs or feature requests through the issue tracker at
<https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/issues>. You will be
requires "IO::Socket" => "0";
requires "MIME::Base64" => "0";
requires "Socket" => "0";
requires "Time::Local" => "0";
requires "bytes" => "0";
requires "perl" => "5.006";
requires "strict" => "0";
requires "warnings" => "0";
recommends "HTTP::CookieJar" => "0.001";
recommends "IO::Socket::IP" => "0.32";
recommends "IO::Socket::SSL" => "1.968";
recommends "Net::SSLeay" => "1.49";
on 'test' => sub {
requires "Data::Dumper" => "0";
requires "Exporter" => "0";
requires "ExtUtils::MakeMaker" => "0";
requires "File::Basename" => "0";
requires "File::Spec" => "0";
requires "File::Temp" => "0";
requires "IO::Dir" => "0";
stopwords = RFC7234
stopwords = RFC7235
[ReleaseStatus::FromVersion]
testing = third_decimal_odd
[RemovePrereqs]
remove = Errno
remove = HTTP::CookieJar
remove = IO::Socket::IP
remove = IO::Socket::SSL
remove = Net::SSLeay
remove = threads
[Prereqs / Recommends]
HTTP::CookieJar = 0.001
IO::Socket::IP = 0.32
IO::Socket::SSL = 1.968
Net::SSLeay = 1.49
[Prereqs / DevelopRequires]
; Non core Perl::Critic policy used in perlcritic.rc
Perl::Critic::Policy::Lax::ProhibitStringyEval::ExceptForRequire = 0
lib/HTTP/Tiny.pm view on Meta::CPAN
#pod * C<no_proxy> â List of domain suffixes that should not be proxied. Must
#pod be a comma-separated string or an array reference. (default is
#pod C<$ENV{no_proxy}> â)
#pod * C<timeout> â Request timeout in seconds (default is 60) If a socket open,
#pod read or write takes longer than the timeout, the request response status code
#pod will be 599.
#pod * C<verify_SSL> â A boolean that indicates whether to validate the TLS/SSL
#pod certificate of an C<https> â connection (default is true). Changed from false
#pod to true in version 0.083.
#pod * C<SSL_options> â A hashref of C<SSL_*> â options to pass through to
#pod L<IO::Socket::SSL>
#pod * C<$ENV{PERL_HTTP_TINY_SSL_INSECURE_BY_DEFAULT}> - Changes the default
#pod certificate verification behavior to not check server identity if set to 1.
#pod Only effective if C<verify_SSL> is not set. Added in version 0.083.
#pod
#pod
#pod An accessor/mutator method exists for each attribute.
#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
lib/HTTP/Tiny.pm view on Meta::CPAN
return join("&", @terms);
}
#pod =method can_ssl
#pod
#pod $ok = HTTP::Tiny->can_ssl;
#pod ($ok, $why) = HTTP::Tiny->can_ssl;
#pod ($ok, $why) = $http->can_ssl;
#pod
#pod Indicates if SSL support is available. When called as a class object, it
#pod checks for the correct version of L<Net::SSLeay> and L<IO::Socket::SSL>.
#pod When called as an object methods, if C<SSL_verify> is true or if C<SSL_verify_mode>
#pod is set in C<SSL_options>, it checks that a CA file is available.
#pod
#pod In scalar context, returns a boolean indicating if SSL is available.
#pod In list context, returns the boolean and a (possibly multi-line) string of
#pod errors indicating why SSL isn't available.
#pod
#pod =cut
sub can_ssl {
my ($self) = @_;
my($ok, $reason) = (1, '');
# Need IO::Socket::SSL 1.968 for default_ca()
local @INC = @INC;
pop @INC if $INC[-1] eq '.';
unless (eval {require IO::Socket::SSL; IO::Socket::SSL->VERSION(1.968)}) {
$ok = 0;
$reason .= qq/IO::Socket::SSL 1.968 or later must be installed for https support\n/;
}
# Need Net::SSLeay 1.49 for MODE_AUTO_RETRY
unless (eval {require Net::SSLeay; Net::SSLeay->VERSION(1.49)}) {
$ok = 0;
$reason .= qq/Net::SSLeay 1.49 or later must be installed for https support\n/;
}
# If an object, check that SSL config lets us get a CA if necessary
if ( ref($self) && ( $self->{verify_SSL} || $self->{SSL_options}{SSL_verify_mode} ) ) {
lib/HTTP/Tiny.pm view on Meta::CPAN
}
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/);
}
}
sub close {
@_ == 1 || die(q/Usage: $handle->close()/ . "\n");
my ($self) = @_;
CORE::close($self->{fh})
or die(qq/Could not close socket: '$!'\n/);
}
lib/HTTP/Tiny.pm view on Meta::CPAN
}
last;
}
$! = 0;
return $nfound;
}
sub can_read {
@_ == 1 || @_ == 2 || die(q/Usage: $handle->can_read([timeout])/ . "\n");
my $self = shift;
if ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
return 1 if $self->{fh}->pending;
}
return $self->_do_timeout('read', @_)
}
sub can_write {
@_ == 1 || @_ == 2 || die(q/Usage: $handle->can_write([timeout])/ . "\n");
my $self = shift;
return $self->_do_timeout('write', @_)
}
lib/HTTP/Tiny.pm view on Meta::CPAN
my $ca_file = $self->{SSL_options}->{SSL_ca_file};
if ( defined $ca_file ) {
unless ( -r $ca_file ) {
die qq/SSL_ca_file '$ca_file' not found or not readable\n/;
}
return ( SSL_ca_file => $ca_file );
}
# Return default_ca() parameters from IO::Socket::SSL. It looks for the
# default bundle and directory from Net::SSLeay, handles $ENV{SSL_CERT_FILE}
# and $ENV{SSL_CERT_DIR}, and finally fails over to Mozilla::CA
#
my %default_ca = IO::Socket::SSL::default_ca();
return %default_ca if %default_ca;
# If IO::Socket::SSL::default_ca() was unable to find a CA bundle, look for
# one in well known locations as a last resort. Cert list copied from golang
# src/crypto/x509/root_unix.go
#
foreach my $ca_bundle (
"/etc/ssl/certs/ca-certificates.crt", # Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", # Fedora/RHEL
"/etc/ssl/ca-bundle.pem", # OpenSUSE
"/etc/openssl/certs/ca-certificates.crt", # NetBSD
"/etc/ssl/cert.pem", # OpenBSD
"/usr/local/share/certs/ca-root-nss.crt", # FreeBSD/DragonFly
lib/HTTP/Tiny.pm view on Meta::CPAN
sub _get_tid {
no warnings 'reserved'; # for 'threads'
return threads->can("tid") ? threads->tid : 0;
}
sub _ssl_args {
my ($self, $host) = @_;
my %ssl_args;
# This test reimplements IO::Socket::SSL::can_client_sni(), which wasn't
# added until IO::Socket::SSL 1.84
if ( Net::SSLeay::OPENSSL_VERSION_NUMBER() >= 0x01000000 ) {
$ssl_args{SSL_hostname} = $host, # Sane SNI support
}
if ($self->{verify_SSL}) {
$ssl_args{SSL_verifycn_scheme} = 'http'; # enable CN validation
$ssl_args{SSL_verifycn_name} = $host; # set validation hostname
$ssl_args{SSL_verify_mode} = 0x01; # enable cert validation
%ssl_args = ( %ssl_args, $self->_find_CA );
lib/HTTP/Tiny.pm view on Meta::CPAN
=item *
C<timeout> â Request timeout in seconds (default is 60) If a socket open, read or write takes longer than the timeout, the request response status code will be 599.
=item *
C<verify_SSL> â A boolean that indicates whether to validate the TLS/SSL certificate of an C<https> â connection (default is true). Changed from false to true in version 0.083.
=item *
C<SSL_options> â A hashref of C<SSL_*> â options to pass through to L<IO::Socket::SSL>
=item *
C<$ENV{PERL_HTTP_TINY_SSL_INSECURE_BY_DEFAULT}> - Changes the default certificate verification behavior to not check server identity if set to 1. Only effective if C<verify_SSL> is not set. Added in version 0.083.
=back
An accessor/mutator method exists for each attribute.
Passing an explicit C<undef> for C<proxy>, C<http_proxy> or C<https_proxy> will
lib/HTTP/Tiny.pm view on Meta::CPAN
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.
=head2 connected
$host = $http->connected;
lib/HTTP/Tiny.pm view on Meta::CPAN
local_address
max_redirect
max_size
no_proxy
proxy
timeout
verify_SSL
=head1 TLS/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 error will occur
if new enough versions of these modules are not installed or if the TLS
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.
TLS/SSL provides two distinct capabilities:
lib/HTTP/Tiny.pm view on Meta::CPAN
Verification is done by checking that that the TLS/SSL connection has a valid
certificate corresponding to the host name of the connection and that the
certificate has been verified by a CA. Assuming you trust the CA, this will
protect against L<machine-in-the-middle
attacks|http://en.wikipedia.org/wiki/Machine-in-the-middle_attack>.
Certificate verification requires a file or directory containing trusted CA
certificates.
C<IO::Socket::SSL::default_ca()> is called to detect the default location of
your CA certificates. This also supports the environment variables
C<SSL_CERT_FILE> and C<SSL_CERT_DIR>, and will fail over to L<Mozilla::CA> if no
certs are found.
If C<IO::Socket::SSL::default_ca()> is not able to find usable CA certificates,
HTTP::Tiny will search several well-known system-specific default locations for
a CA certificate file as a last resort:
=over 4
=item *
/etc/ssl/certs/ca-certificates.crt
=item *
lib/HTTP/Tiny.pm view on Meta::CPAN
/etc/certs/ca-certificates.crt
=back
An error will be occur if C<verify_SSL> is true and no CA certificate file
is available.
If you desire complete control over TLS/SSL connections, the C<SSL_options>
attribute lets you provide a hash reference that will be passed through to
C<IO::Socket::SSL::start_SSL()>, overriding any options set by HTTP::Tiny. For
example, to provide your own trusted CA file:
SSL_options => {
SSL_ca_file => $file_path,
}
The C<SSL_options> attribute could also be used for such things as providing a
client certificate for authentication to a server or controlling the choice of
cipher used for the TLS/SSL connection. See L<IO::Socket::SSL> documentation for
details.
=head1 PROXY SUPPORT
HTTP::Tiny can proxy both C<http> and C<https> requests. Only Basic proxy
authorization is supported and it must be provided as part of the proxy URL:
C<http://user:pass@proxy.example.com/>.
HTTP::Tiny supports the following proxy environment variables:
lib/HTTP/Tiny.pm view on Meta::CPAN
=item *
L<HTTP::Tiny::Mech> - Wrap L<WWW::Mechanize> instance in HTTP::Tiny compatible interface
=item *
L<IO::Socket::IP> - Required for IPv6 support
=item *
L<IO::Socket::SSL> - Required for SSL support
=item *
L<LWP::UserAgent> - If HTTP::Tiny isn't enough for you, this is the "standard" way to do things
=item *
L<Net::SSLeay> - Required for SSL support
=back
t/00-report-prereqs.dd view on Meta::CPAN
'Test::Portability::Files' => '0',
'Test::Spelling' => '0.17',
'Test::Version' => '1',
'perl' => '5.006'
}
},
'runtime' => {
'recommends' => {
'HTTP::CookieJar' => '0.001',
'IO::Socket::IP' => '0.32',
'IO::Socket::SSL' => '1.968',
'Net::SSLeay' => '1.49'
},
'requires' => {
'Carp' => '0',
'Fcntl' => '0',
'IO::Socket' => '0',
'MIME::Base64' => '0',
'Socket' => '0',
'Time::Local' => '0',
'bytes' => '0',
t/210_live_ssl.t view on Meta::CPAN
Proto => 'tcp',
Timeout => 10,
);
# the default verification
my $response = HTTP::Tiny->new()->get($url);
is $response->{success}, $data->{default_verify_should_return}, "Request to $url passed/failed using default as expected"
or do {
# $response->{content} = substr $response->{content}, 0, 50;
$response->{content} =~ s{\n.*}{}s;
diag explain [IO::Socket::SSL::errstr(), $response]
};
# force validation to succeed
if ($data->{pass}) {
my $pass = HTTP::Tiny->new( %{$data->{pass}} )->get($url);
isnt $pass->{status}, '599', "Request to $url completed (forced pass)"
or do {
$pass->{content} =~ s{\n.*}{}s;
diag explain $pass
};
ok $pass->{content}, 'Got some content';
}
# force validation to fail
if ($data->{fail}) {
my $fail = HTTP::Tiny->new( %{$data->{fail}} )->get($url);
is $fail->{status}, '599', "Request to $url failed (forced fail)"
or do {
$fail->{content} =~ s{\n.*}{}s;
diag explain [IO::Socket::SSL::errstr(), $fail]
};
ok $fail->{content}, 'Got some content';
}
};
}