App-MatrixTool
view release on metacpan or search on metacpan
lib/App/MatrixTool/HTTPClient.pm view on Meta::CPAN
#
# (C) Paul Evans, 2015 -- leonerd@leonerd.org.uk
package App::MatrixTool::HTTPClient;
use strict;
use warnings;
our $VERSION = '0.08';
use Carp;
use Future 0.33; # ->catch
use Future::Utils qw( repeat_until_success );
use IO::Async::Loop;
use IO::Async::Resolver 0.68; # failure details
use IO::Async::Resolver::DNS 0.06 qw( ERR_NO_HOST ERR_NO_ADDRESS ); # Future return with failure details
use JSON qw( encode_json decode_json );
use URI;
use Socket qw( getnameinfo NI_NUMERICHOST SOCK_RAW );
use constant DEFAULT_MATRIX_PORT => 8448;
=head1 NAME
C<App::MatrixTool::HTTPClient> - HTTP client helper for L<App::MatrixTool>
=head1 DESCRIPTION
Provides helper methods to perform HTTP client operations that may be required
by commands of L<App::MatrixTool>.
=cut
sub new
{
my $class = shift;
my $loop = IO::Async::Loop->new; # magic constructor
return bless {
@_,
resolver => $loop->resolver,
loop => $loop,
}, $class;
}
=head1 METHODS
=cut
sub ua
{
my $self = shift;
return $self->{ua} ||= do {
require IO::Async::SSL;
require Net::Async::HTTP;
require HTTP::Request;
my $ua = Net::Async::HTTP->new(
SSL_verify_mode => 0,
fail_on_error => 1, # turn 4xx/5xx errors into Future failures
);
$self->{loop}->add( $ua );
$ua;
};
}
=head2 resolve_matrix
@res = $client->resolve_matrix( $server_name )->get
Returns a list of C<HASH> references. Each has at least the keys C<target>
and C<port>. These should be tried in order until one succeeds.
=cut
sub resolve_matrix
{
my $self = shift;
my ( $server_name ) = @_;
if( my ( $host, $port ) = $server_name =~ m/^(\S+):(\d+)$/ ) {
return Future->done( { target => $host, port => $port } );
}
$self->{resolver}->res_query(
dname => "_matrix._tcp.$server_name",
type => "SRV",
)->then( sub {
my ( undef, @srvs ) = @_;
Future->done( @srvs );
})->catch_with_f(
resolve => sub {
my ( $f, $message, undef, undef, $errnum ) = @_;
return $f unless $errnum == ERR_NO_HOST or $errnum == ERR_NO_ADDRESS;
Future->done( { target => $server_name, port => DEFAULT_MATRIX_PORT } );
}
);
}
=head2 resolve_addr
@addrs = $client->resolve_addr( $hostname )->get
Returns a list of human-readable string representations of the IP addresses
resolved by the given hostname.
=cut
sub resolve_addr
{
my $self = shift;
my ( $host ) = @_;
$self->{resolver}->getaddrinfo(
host => $host,
service => "",
family => $self->{family},
( run in 1.768 second using v1.01-cache-2.11-cpan-e1769b4cff6 )