Armadito-Agent

 view release on metacpan or  search on metacpan

lib/Armadito/Agent/HTTP/Client.pm  view on Meta::CPAN

package Armadito::Agent::HTTP::Client;

use strict;
use warnings;

use English qw(-no_match_vars);
use HTTP::Status;
use LWP::UserAgent;
use UNIVERSAL::require;

use Armadito::Agent::Logger qw(LOG_DEBUG2);

my $log_prefix = "[http client] ";

sub new {
	my ( $class, %params ) = @_;

	die "non-existing certificate file $params{ca_cert_file}"
		if $params{ca_cert_file} && !-f $params{ca_cert_file};

	die "non-existing certificate directory $params{ca_cert_dir}"
		if $params{ca_cert_dir} && !-d $params{ca_cert_dir};

	my $self = {
		logger => $params{logger} || Armadito::Agent::Logger->new(),
		user => $params{user},
		password     => $params{password},
		ssl_set      => 0,
		no_ssl_check => $params{no_ssl_check},
		ca_cert_dir  => $params{ca_cert_dir},
		ca_cert_file => $params{ca_cert_file}
	};
	bless $self, $class;

	$self->{ua} = LWP::UserAgent->new(
		requests_redirectable => [ 'POST', 'GET', 'HEAD' ],
		agent                 => $Armadito::Agent::AGENT_STRING,
		timeout => $params{timeout} || 180,
		parse_head => 0,
		keep_alive => 1,
	);

	if ( $params{proxy} ) {
		$self->{ua}->proxy( [ 'http', 'https' ], $params{proxy} );
	}
	else {
		$self->{ua}->env_proxy();
	}

	return $self;
}

sub request {
	my ( $self, $request, $file ) = @_;

	my $logger = $self->{logger};

	my $url    = $request->uri();
	my $scheme = $url->scheme();
	$self->_setSSLOptions() if $scheme eq 'https' && !$self->{ssl_set};

	my $result = HTTP::Response->new(500);
	eval {
		if ( $OSNAME eq 'MSWin32' && $scheme eq 'https' ) {
			alarm $self->{ua}->timeout();
		}
		$result = $self->{ua}->request( $request, $file );
		alarm 0;
	};

	if ( !$result->is_success() ) {

		# authentication required
		if ( $result->code() == 401 ) {
			if ( $self->{user} && $self->{password} ) {
				$logger->debug( $log_prefix . "authentication required, submitting credentials" );

				my $header  = $result->header('www-authenticate');
				my ($realm) = $header =~ /^Basic realm="(.*)"/;
				my $host    = $url->host();
				my $port    = $url->port()
					|| ( $scheme eq 'https' ? 443 : 80 );
				$self->{ua}->credentials( "$host:$port", $realm, $self->{user}, $self->{password} );

				# replay request
				eval {
					if ( $OSNAME eq 'MSWin32' && $scheme eq 'https' ) {
						alarm $self->{ua}->{timeout};
					}
					$result = $self->{ua}->request( $request, $file );
					alarm 0;
				};
				if ( !$result->is_success() ) {
					$logger->error( $log_prefix . "authentication required, wrong credentials" );
				}
			}
			else {
				# abort
				$logger->error( $log_prefix . "authentication required, no credentials available" );
			}



( run in 0.499 second using v1.01-cache-2.11-cpan-df04353d9ac )