File Coverage

blib/lib/Email/Sender/Transport/QMQP.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Email::Sender::Transport::QMQP;
2             {
3             $Email::Sender::Transport::QMQP::VERSION = '0.001';
4             }
5             # ABSTRACT: send mail via QMQP
6              
7 1     1   1695720 use Moose;
  0            
  0            
8             with 'Email::Sender::Transport';
9              
10              
11             has 'host' => (is => 'ro',
12             isa => 'Str',
13             required => 1,
14             default => sub { 'localhost' });
15              
16             has 'port' => (is => 'ro',
17             isa => 'Str',
18             required => 1,
19             default => sub { 628 });
20              
21              
22             sub send_email {
23             my ($self, $email, $envelope) = @_;
24              
25             my $socket;
26             if ($self->port =~ m,^/,) {
27             require IO::Socket::UNIX;
28             $socket = IO::Socket::UNIX->new (Peer => $self->port) or Email::Sender::Failure->throw ("Couldn't connect to qmqp socket at " . $self->port . ", " . $!);
29             } else {
30             require IO::Socket::INET;
31             $socket = IO::Socket::INET->new (PeerAddr => $self->host, PeerPort => $self->port) or Email::Sender::Failure->throw ("Couldn't connect to qmqp socket at " . join (':', $self->host, $self->port) . ", " . $!);
32             }
33              
34             my $payload = join '', map {sprintf "%d:%s,", length $_, $_} $email->as_string, $envelope->{from}, @{$envelope->{to}};
35             $socket->printf ('%d:%s,', length $payload, $payload) or Email::Sender::Failure->throw ("Couldn't send message via socket: $!");
36              
37             my $response = $socket->getline;
38              
39             if (my ($length, $code, $detail) = $response =~ m/^(\d+):(\S)(.+),$/) {
40             if ($code eq "K") {
41             $self->success;
42             } else {
43             my $class = join '::', 'Email::Sender::Failure', ($detail eq "D" ? 'Permanent' : 'Temporary');
44             $class->throw ('Transmission failed: ' . $detail);
45             }
46             } else {
47             Email::Sender::Failure::Temporary->throw ("Bad response from server: $response");
48             }
49             }
50              
51             __PACKAGE__->meta->make_immutable;
52             no Moose;
53              
54             1;
55              
56             __END__
57             =pod
58              
59             =head1 NAME
60              
61             Email::Sender::Transport::QMQP - send mail via QMQP
62              
63             =head1 VERSION
64              
65             version 0.001
66              
67             =head1 METHODS
68              
69             =head2 send_email
70              
71             We connect to the QMQP service wherever specified, format the email
72             and envelope information as appropriate, send it, then look for and
73             parse the response, passing along the results appropriately.
74              
75             =head2 DESCRIPTION
76              
77             This transport sends mail by connecting to a host implementing the
78             C<QMQP> protocol (generally running either C<qmail> or C<postfix>).
79              
80             If the hostname or the port of the C<QMQP> server host is not provided
81             in the constructor (see below) then the library will try
82             C<localhost:628>
83              
84             To specify the QMQP server location, use the port and host parameters:
85              
86             my $sender = Email::Sender::Transport::QMQP->new({ host => $host, port => $port });
87              
88             If host is set to an absolute file path (starting with '/'), it's
89             assumed to be a Unix socket path, and is connected to accordingly.
90              
91             =head1 AUTHOR
92              
93             Michael Alan Dorman <mdorman@ironicdesign.com>
94              
95             =head1 COPYRIGHT AND LICENSE
96              
97             This software is copyright (c) 2012 by Ironic Design, Inc..
98              
99             This is free software; you can redistribute it and/or modify it under
100             the same terms as the Perl 5 programming language system itself.
101              
102             =cut
103