File Coverage

blib/lib/Email/Send/SMTP.pm
Criterion Covered Total %
statement 19 74 25.6
branch 3 40 7.5
condition 0 11 0.0
subroutine 5 8 62.5
pod 0 4 0.0
total 27 137 19.7


line stmt bran cond sub pod time code
1             package Email::Send::SMTP;
2 2     2   1594 use strict;
  2         4  
  2         73  
3              
4 2     2   9 use vars qw[$VERSION];
  2         5  
  2         92  
5 2     2   1847 use Email::Address 1.80;
  2         66826  
  2         230  
6             BEGIN {
7 2     2   6 local $Return::Value::NO_CLUCK = 1;
8 2         26 require Return::Value;
9 2         1705 Return::Value->import;
10             }
11              
12             $VERSION = '2.199';
13              
14             sub is_available {
15 1     1 0 4 my ($class, %args) = @_;
16 1         2 my $success = 1;
17 1         3 $success = eval { require Net::SMTP };
  1         1103  
18 1 50       5830 $success = eval { require Net::SMTP::SSL } if $args{ssl};
  0         0  
19 1 50       4 $success = eval { require Net::SMTP::TLS } if $args{tls};
  0         0  
20 1 50       11 return $success
21             ? success
22             : failure $@;
23             }
24              
25             sub get_env_sender {
26 0     0 0   my ($class, $message) = @_;
27              
28 0 0         return unless my $hdr = $message->header('From');
29 0           my $from = (Email::Address->parse($hdr))[0]->address;
30             }
31              
32             sub get_env_recipients {
33 0     0 0   my ($class, $message) = @_;
34              
35 0           my %to = map { $_->address => 1 }
  0            
36 0 0         map { Email::Address->parse($_) }
37 0           grep { defined and length }
38 0           map { $message->header($_) }
39             qw(To Cc Bcc);
40              
41 0           return keys %to;
42             }
43              
44             sub send {
45 0     0 0   my ($class, $message, @args) = @_;
46              
47 0           my %args;
48 0 0         if ( @args % 2 ) {
49 0           my $host = shift @args;
50 0           %args = @args;
51 0           $args{Host} = $host;
52             } else {
53 0           %args = @args;
54             }
55              
56 0   0       my $host = delete($args{Host}) || 'localhost';
57              
58 0 0         my $smtp_class = $args{ssl} ? 'Net::SMTP::SSL'
    0          
59             : $args{tls} ? 'Net::SMTP::TLS'
60             : 'Net::SMTP';
61              
62 0 0         eval "require $smtp_class; 1" or die;
63              
64 0 0         if ( $smtp_class eq 'Net::SMTP::TLS' ) {
65             # ::TLS has different User/Password than the rest
66 0   0       $args{User} ||= $args{username};
67 0   0       $args{Password} ||= $args{password};
68             }
69              
70 0           my $SMTP = $smtp_class->new($host, %args);
71 0 0         return failure "Couldn't connect to $host" unless $SMTP;
72            
73 0           my ($user, $pass) = @args{qw[username password]};
74              
75             # for ::TLS, the auth is done by the new()
76 0 0 0       if ( $user and not $smtp_class eq 'Net::SMTP::TLS' ) {
77 0 0         $SMTP->auth($user, $pass)
78             or return failure "Couldn't authenticate '$user:...'";
79             }
80            
81 0           my @bad;
82 0           eval {
83 0           my $from = $class->get_env_sender($message);
84              
85             # ::TLS has no useful return value, but will croak on failure.
86 0 0         eval { $SMTP->mail($from); 1 } or return failure "FROM: <$from> denied";
  0            
  0            
87              
88 0           my @to = $class->get_env_recipients($message);
89              
90 0 0         if (eval { $SMTP->isa('Net::SMTP::TLS') }) {
  0            
91 0           $SMTP->to(@to);
92             } else {
93 0           my @ok = $SMTP->to(@to, { SkipBad => 1 });
94              
95 0 0         if ( @to != @ok ) {
96 0           my %to; @to{@to} = (1) x @to;
  0            
97 0           delete @to{@ok};
98 0           @bad = keys %to;
99             }
100             }
101            
102 0 0         return failure "No valid recipients" if @bad == @to;
103             };
104              
105 0 0         return failure $@ if $@;
106              
107 0 0         if ( $smtp_class eq 'Net::SMTP::TLS' ) {
108 0           $SMTP->data;
109 0           $SMTP->datasend( $message->as_string );
110 0           $SMTP->dataend;
111             }
112             else {
113 0 0         return failure "Can't send data" unless $SMTP->data( $message->as_string );
114             }
115              
116 0           $SMTP->quit;
117 0           return success "Message sent", prop => { bad => [ @bad ], };
118             }
119              
120             1;
121              
122             __END__