Mojo-SMTP-Client

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

0.10  Wed Apr 22 13:06:04 NOVT 2015
    - Clean ripped childs inside tests to prevent tests failing on BINGOS's
      openBSDs

0.09  Thu Apr 16 23:56:39 NOVT 2015
    - Fix possible memory leak for `starttls' command
    - Support for explicit `hello' command
    - new `prepend_cmd' method

0.08  Thu Mar 26 18:31:20 NOVT 2015
    - Fix tests for cases when IO::Socket::SSL not available
    - Fix bug when last chars of data could be LF without CR
    - Add new `auth' command for `send'
    - Add new recipe about sending emails via public SMTP servers with auth

0.07  Wed Mar 25 16:28:18 NOVT 2015
    - new `tls', `tls_ca', `tls_cert', `tls_key' attributes
    - new `starttls' command for `send'

0.06  Mon Mar 23 18:28:12 NOVT 2015
    - $resp now is an object of Mojo::SMTP::Client::Response class

lib/Mojo/SMTP/Client.pm  view on Meta::CPAN

			$self->{resp_checker}->($delay, $resp);
		}
	);
}

# STARTTLS
sub _cmd_starttls {
	my ($self, $arg) = @_;
	weaken $self;
	
	require IO::Socket::SSL and IO::Socket::SSL->VERSION(0.98);
	
	return (
		sub {
			my $delay = shift;
			$self->_write_cmd('STARTTLS', CMD_STARTTLS);
			$self->_read_response($delay->begin);
			$self->{expected_code} = CMD_OK;
		},
		$self->{resp_checker},
		sub {

lib/Mojo/SMTP/Client.pm  view on Meta::CPAN

			my ($tls_cb, $tid, $loop, $sock);
			
			my $error_handler = sub {
				$loop->remove($tid);
				$loop->reactor->remove($sock);
				$sock = undef;
				$tls_cb->($delay, undef, @_>=2 ? $_[1] : 'Inactivity timeout');
				$tls_cb = $delay = undef;
			};
			
			$sock = IO::Socket::SSL->start_SSL(
				$self->{stream}->steal_handle,
				SSL_ca_file         => $self->tls_ca,
				SSL_cert_file       => $self->tls_cert,
				SSL_key_file        => $self->tls_key,
				SSL_verify_mode     => $self->tls_verify,
				SSL_verifycn_name   => $self->address,
				SSL_verifycn_scheme => $self->tls_ca ? 'smtp' : undef,
				SSL_startHandshake  => 0,
				SSL_error_trap      => $error_handler
			)
			or return $delay->pass(0, $IO::Socket::SSL::SSL_ERROR);
			
			$tls_cb = $delay->begin;
			$loop = $self->_ioloop;
			
			$tid = $loop->timer($self->inactivity_timeout => $error_handler);
			
			$loop->reactor->io($sock => sub {
				if ($sock->connect_SSL) {
					$loop->remove($tid);
					$loop->reactor->remove($sock);
					$self->_make_stream($sock, $loop);
					$self->{starttls} = 1;
					$sock = $loop = undef;
					$tls_cb->($delay, $resp);
					$tls_cb = $delay = undef;
					return;
				}
				
				return $loop->reactor->watch($sock, 1, 0)
					if $IO::Socket::SSL::SSL_ERROR == IO::Socket::SSL::SSL_WANT_READ();
				return $loop->reactor->watch($sock, 0, 1)
					if $IO::Socket::SSL::SSL_ERROR == IO::Socket::SSL::SSL_WANT_WRITE();
				
			})->watch($sock, 0, 1);
		},
		sub {
			my ($delay, $resp, $error) = @_;
			unless ($resp) {
				$self->_rm_stream();
				Mojo::SMTP::Client::Exception::Stream->throw($error);
			}
			

lib/Mojo/SMTP/Client.pm  view on Meta::CPAN


Address of SMTP server (ip or domain name). Default is C<localhost>

=head2 port

Port of SMTP server. Default is C<25> for plain connection and C<465> if TLS is enabled.

=head2 tls

Enable TLS. Should be true if SMTP server expects encrypted connection. Default is false.
Proper version of L<IO::Socket::SSL> should be installed for TLS support in L<Mojo::IOLoop::Client>,
which you can find with C<mojo version> command.

=head2 tls_ca

Path to TLS certificate authority file. Also activates hostname verification.

=head2 tls_cert

Path to the TLS certificate file.

lib/Mojo/SMTP/Client.pm  view on Meta::CPAN

Send greeting to the server. Argument to this command should contain your domain name. Keep in mind, that
C<Mojo::SMTP::Client> will automatically send greeting to the server right after connection if you not specified
C<hello> as first command for C<send>. C<Mojo::SMTP::Client> first tries C<EHLO> command for greeting and if
server doesn't accept it C<Mojo::SMTP::Client> retries with C<HELO> command.

	$smtp->send(hello => 'mymail.me');

=item starttls

Upgrades connection from plain to encrypted. Some servers requires this before sending any other commands.
L<IO::Socket::SSL> 0.98+ should be installed for this to work. See also L</tls_ca>, L</tls_cert>, L</tls_key>
attributes

	$smtp->tls_ca('/etc/ssl/certs/ca-certificates.crt');
	$smtp->send(starttls => 1);

=item auth

Authorize on SMTP server. Argument to this command should be a reference to a hash with C<type>,
C<login> and C<password> keys. Only PLAIN and LOGIN authorization are supported as C<type> for now.
You should authorize only once per session.

t/lib/Utils.pm  view on Meta::CPAN

package Utils;

use strict;
use IO::Socket 'CRLF';
use Socket;
use POSIX 'WNOHANG';

use constant DEBUG => $ENV{MOJO_SMTP_TEST_DEBUG};
use constant TLS => scalar eval "use IO::Socket::SSL 0.98; 1";

$SIG{CHLD} = sub {
	my $pid;
	do { $pid = waitpid(-1, WNOHANG) } while $pid > 0;
};

sub make_smtp_server {
	my $tls = shift;
	
	my @opts = (Listen => 10);
	my $class;
	if ($tls) {
		$class = 'IO::Socket::SSL';
		push @opts, SSL_cert_file => 't/cert/server.crt',
		            SSL_key_file  => 't/cert/server.key';
	}
	else {
		$class = 'IO::Socket::INET';
	}
	my $srv = $class->new(@opts)
		or die $@;
	
	socketpair(my $sock1, my $sock2, AF_UNIX, SOCK_STREAM, PF_UNSPEC)

t/lib/Utils.pm  view on Meta::CPAN

			while (my $resp = <$sock2>) {
				syswrite($clt, $resp) && DEBUG && warn "[$clt] <- $resp" if $resp =~ /^\d+/;
				next if $resp =~ /^\d+-/;
				if ($resp =~ /!quit\s*$/) {
					warn "[$clt] !quit\n" if DEBUG;
					$clt->close();
					last;
				}
				elsif ($resp =~ /!starttls\s*$/) {
					warn "[$clt] !starttls\n" if DEBUG;
					IO::Socket::SSL->start_SSL($clt,
						SSL_server      => 1,
						SSL_cert_file   => 't/cert/server.crt',
						SSL_key_file    => 't/cert/server.key'
					) or die $IO::Socket::SSL::SSL_ERROR;
				}
				
				my $cmd = <$clt> or last;
				warn "[$clt] -> $cmd" if DEBUG;
				syswrite($sock2, $cmd);
			}
		}
		exit;
	}
	



( run in 0.521 second using v1.01-cache-2.11-cpan-4d50c553e7e )