Haineko
view release on metacpan or search on metacpan
lib/Haineko/Sendmail.pm view on Meta::CPAN
package Haineko::Sendmail;
use strict;
use warnings;
use Encode;
use Try::Tiny;
use Time::Piece;
use Scalar::Util;
use Haineko::Log;
use Haineko::JSON;
use Haineko::Default;
use Haineko::SMTPD::Milter;
use Haineko::SMTPD::Session;
use Haineko::SMTPD::Response;
sub submit {
my $class = shift;
my $httpd = shift; # (Haineko::HTTPD)
my $serverconf = $httpd->{'conf'}->{'smtpd'};
my $defaultset = Haineko::Default->conf;
my $responsecn = 'Haineko::SMTPD::Response';
my $responsejk = 'response'; # (String) Response json key name
my $exceptions = 0; # (Integer) Flag, be set in try {...} catch { ... }
my $tmpsession = undef; # (Haineko::SMTPD::Session) Temporary session object
# Create a queue id (session id)
my $queueident = Haineko::SMTPD::Session->make_queueid;
# Variables related user information such as hostname or port number.
my $xforwarded = [ split( ',', $httpd->req->header('X-Forwarded-For') || q() ) ];
my $remoteaddr = pop @$xforwarded || $httpd->req->address // undef;
my $remoteport = $httpd->req->env->{'REMOTE_PORT'} // undef;
my $remotehost = $httpd->req->env->{'REMOTE_HOST'} // undef;
my $remoteuser = $httpd->req->env->{'REMOTE_USER'} // undef;
my $useragent1 = $httpd->req->user_agent // undef;
# Syslog object
my $syslogargv = {
'queueid' => $queueident,
'facility' => $serverconf->{'syslog'}->{'facility'},
'disabled' => $serverconf->{'syslog'}->{'disabled'},
'useragent' => $useragent1,
'remoteaddr' => $remoteaddr,
'remoteport' => $remoteport,
};
for my $e ( 'facility', 'disabled' ) {
# Fallback to the default value when these values are not defined in
# etc/haineko.cf
$syslogargv->{ $e } //= $defaultset->{'smtpd'}->{'syslog'}->{ $e };
}
my $nekosyslog = Haineko::Log->new( %$syslogargv );
my $esresponse = undef;
# Create a new SMTP Session
$tmpsession = Haineko::SMTPD::Session->new(
'queueid' => $queueident,
'referer' => $httpd->req->referer // q(),
'useragent' => $useragent1,
'remoteaddr' => $remoteaddr,
'remoteport' => $remoteport );
if( $httpd->debug == 0 && $httpd->req->method eq 'GET' ) {
# GET method is not permitted in production mode.
# Use ``POST'' method instead.
$esresponse = $responsecn->r( 'http', 'method-not-supported' );
$tmpsession->add_response( $esresponse );
$nekosyslog->w( 'err', $esresponse->damn );
return $httpd->res->json( 405, $tmpsession->damn );
}
CONN: {
# ____ ___ _ _ _ _
# / ___/ _ \| \ | | \ | |
# | | | | | | \| | \| |
# | |__| |_| | |\ | |\ |
# \____\___/|_| \_|_| \_|
#
# Check the remote address
my $relayhosts = undef;
my $ip4network = undef;
try {
# Check etc/relayhosts file. The remote host or the network should
# be listed in the file.
$exceptions = 0;
require Net::CIDR::Lite;
$relayhosts = Haineko::JSON->loadfile( $serverconf->{'access'}->{'conn'} );
$ip4network = Net::CIDR::Lite->new( @{ $relayhosts->{'relayhosts'} } );
( run in 0.546 second using v1.01-cache-2.11-cpan-ceb78f64989 )