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 )