Haineko
view release on metacpan or search on metacpan
lib/Haineko/SMTPD/Relay/Haineko.pm view on Meta::CPAN
package Haineko::SMTPD::Relay::Haineko;
use parent 'Haineko::SMTPD::Relay';
use strict;
use warnings;
use Furl;
use Try::Tiny;
use Time::Piece;
use Haineko::JSON;
use Haineko::SMTPD::Response;
sub new {
my $class = shift;
my $argvs = { @_ };
$argvs->{'time'} ||= Time::Piece->new;
$argvs->{'sleep'} ||= 5;
$argvs->{'timeout'} ||= 30;
return bless $argvs, __PACKAGE__;
}
sub sendmail {
my $self = shift;
my $hainekourl = sprintf( "http://%s:%d/submit", $self->{'host'}, $self->{'port'} );
my $parameters = {
'ehlo' => $self->{'ehlo'},
'mail' => $self->{'mail'},
'rcpt' => [ $self->{'rcpt'} ],
'header' => {
'from' => $self->{'head'}->{'From'},
'subject' => $self->{'head'}->{'Subject'},
'charset' => $self->{'attr'}->{'charset'},
},
'body' => $self->{'body'},
};
if( $self->{'head'}->{'Reply-To'} ) {
$parameters->{'header'}->{'replyto'} = $self->{'head'}->{'Reply-To'};
}
my $jsonstring = Haineko::JSON->dumpjson( $parameters );
my $httpheader = [];
my $httpobject = undef;
my $htresponse = undef;
my $hainekores = undef;
if( $self->{'username'} && $self->{'password'} ) {
# Encode credentials for Basic-Authentication
require MIME::Base64;
my $v = MIME::Base64::encode_base64( $self->{'username'}.':'.$self->{'password'} );
$httpheader = [ 'Authorization' => sprintf( "Basic %s", $v ) ];
}
$httpobject = Furl->new(
'agent' => __PACKAGE__,
'timeout' => 10,
'headers' => $httpheader,
'ssl_opts' => { 'SSL_verify_mode' => 0 }
);
my $smtpstatus = 0;
my $retryuntil = $self->{'retry'} || 0;
my $sendmailto = sub {
$htresponse = $httpobject->post( $hainekourl, $httpheader, $jsonstring );
return 0 unless defined $htresponse;
return 0 unless $htresponse->is_success;
$smtpstatus = 1;
return 1;
};
while(1) {
last if $sendmailto->();
last if $retryuntil == 0;
$retryuntil--;
sleep $self->{'sleep'};
}
if( defined $htresponse ) {
# Check the response from another Haineko
my $htcontents = undef;
my $nekoparams = {
'code' => $htresponse->code,
'host' => $self->{'host'},
'port' => $self->{'port'},
'rcpt' => $self->{'rcpt'},
'error' => $htresponse->is_success ? 0 : 1,
'mailer' => 'Haineko',
'message' => [],
'command' => 'POST',
};
if( $htresponse->body =~ m/Cannot connect to\s/ ) {
# Cannot connect to 192.0.2.1:2794: timeout at
$self->response( Haineko::SMTPD::Response->r( 'conn', 'cannot-connect' ) );
map { $self->response->{ $_ } = $self->{ $_ } } ( qw|host port rcpt| );
} else {
# Received as a JSON ?
try {
my $c = $htresponse->body || q();
my $v = {};
if( $c =~ m/(Failed to send HTTP request)/ ) {
# Failed to send HTTP request
( run in 2.002 seconds using v1.01-cache-2.11-cpan-5b529ec07f3 )