File Coverage

lib/Sisimai/Lhost/GMX.pm
Criterion Covered Total %
statement 43 43 100.0
branch 17 20 85.0
condition 11 13 84.6
subroutine 6 6 100.0
pod 2 2 100.0
total 79 84 94.0


line stmt bran cond sub pod time code
1             package Sisimai::Lhost::GMX;
2 41     41   3353 use parent 'Sisimai::Lhost';
  41         197  
  41         207  
3 41     41   2611 use v5.26;
  41         241  
4 41     41   147 use strict;
  41         63  
  41         740  
5 41     41   138 use warnings;
  41         164  
  41         18673  
6              
7 1     1 1 3 sub description { 'GMX: https://gmx.net/' }
8             sub inquire {
9             # Detect an error from GMX and mail.com
10             # @param [Hash] mhead Message headers of a bounce email
11             # @param [String] mbody Message body of a bounce email
12             # @return [Hash] Bounce data list and message/rfc822 part
13             # @return [undef] failed to decode or the arguments are missing
14             # @since v4.1.4
15 923     923 1 2488 my $class = shift;
16 923 100 100     1805 my $mhead = shift // return undef; return undef unless defined $mhead->{'x-gmx-antispam'};
  922         2327  
17 21   50     58 my $mbody = shift // return undef;
18              
19             # Envelope-To:
20             # X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=V3;
21             # X-GMX-Antivirus: 0 (no virus found)
22             # X-UI-Out-Filterresults: unknown:0;
23 21         54 require Sisimai::SMTP::Command;
24 21         47 state $indicators = __PACKAGE__->INDICATORS;
25 21         26 state $boundaries = ['--- The header of the original message is following. ---'];
26 21         30 state $startingof = {'message' => ['This message was created automatically by mail delivery software']};
27              
28 21         66 my $dscontents = [__PACKAGE__->DELIVERYSTATUS]; my $v = undef;
  21         29  
29 21         73 my $emailparts = Sisimai::RFC5322->part($mbody, $boundaries);
30 21         26 my $readcursor = 0; # (Integer) Points the current cursor position
31 21         24 my $recipients = 0; # (Integer) The number of 'Final-Recipient' header
32              
33 21         124 for my $e ( split("\n", $emailparts->[0]) ) {
34             # Read error messages and delivery status lines from the head of the email to the previous
35             # line of the beginning of the original message.
36 230 100       251 unless( $readcursor ) {
37             # Beginning of the bounce message or message/delivery-status part
38 21 50       74 $readcursor |= $indicators->{'deliverystatus'} if index($e, $startingof->{'message'}->[0]) == 0;
39 21         22 next;
40             }
41 209 100 66     416 next if ($readcursor & $indicators->{'deliverystatus'}) == 0 || $e eq "";
42              
43             # This message was created automatically by mail delivery software.
44             #
45             # A message that you sent could not be delivered to one or more of
46             # its recipients. This is a permanent error. The following address
47             # failed:
48             #
49             # "shironeko@example.jp":
50             # SMTP error from remote server after RCPT command:
51             # host: mx.example.jp
52             # 5.1.1 ... User Unknown
53 162         142 $v = $dscontents->[-1];
54              
55 162 100 100     466 if( index($e, '@') > 1 && (index($e, '"') == 0 || index($e, '<') == 0) ) {
    100 100        
    100          
56             # "shironeko@example.jp":
57             # ---- OR ----
58             #
59             #
60             # Reason:
61             # delivery retry timeout exceeded
62 26 100       59 if( $v->{'recipient'} ) {
63             # There are multiple recipient addresses in the message body.
64 5         15 push @$dscontents, __PACKAGE__->DELIVERYSTATUS;
65 5         8 $v = $dscontents->[-1];
66             }
67 26         119 $v->{'recipient'} = Sisimai::Address->s3s4($e);
68 26         33 $recipients++;
69              
70             } elsif( index($e, 'SMTP error ') == 0 ) {
71             # SMTP error from remote server after RCPT command:
72 21         108 $v->{'command'} = Sisimai::SMTP::Command->find($e);
73              
74             } elsif( index($e, 'host: ') == 0 ) {
75             # host: mx.example.jp
76 21         41 $v->{'rhost'} = substr($e, 6, );
77              
78             } else {
79             # Get error messages
80 94 50       101 next unless $e;
81 94         139 $v->{'diagnosis'} .= $e." ";
82             }
83             }
84 21 50       69 return undef unless $recipients;
85 21         103 return {"ds" => $dscontents, "rfc822" => $emailparts->[1]};
86             }
87              
88             1;
89             __END__