File Coverage

lib/Sisimai/Lhost/Biglobe.pm
Criterion Covered Total %
statement 52 54 96.3
branch 19 24 79.1
condition 3 4 75.0
subroutine 6 6 100.0
pod 2 2 100.0
total 82 90 91.1


line stmt bran cond sub pod time code
1             package Sisimai::Lhost::Biglobe;
2 16     16   6026 use parent 'Sisimai::Lhost';
  16         43  
  16         84  
3 16     16   979 use feature ':5.10';
  16         29  
  16         1088  
4 16     16   122 use strict;
  16         42  
  16         310  
5 16     16   79 use warnings;
  16         45  
  16         11686  
6              
7 2     2 1 1213 sub description { 'BIGLOBE: https://www.biglobe.ne.jp' }
8             sub make {
9             # Detect an error from Biglobe
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 parse or the arguments are missing
14             # @since v4.0.0
15 204     204 1 726 my $class = shift;
16 204   100     631 my $mhead = shift // return undef;
17 203   50     491 my $mbody = shift // return undef;
18              
19 203 100       893 return undef unless $mhead->{'from'} =~ /postmaster[@](?:biglobe|inacatv|tmtv|ttv)[.]ne[.]jp/;
20 6 50       24 return undef unless index($mhead->{'subject'}, 'Returned mail:') == 0;
21              
22 6         32 state $indicators = __PACKAGE__->INDICATORS;
23 6         23 state $rebackbone = qr|^Content-Type:[ ]message/rfc822|m;
24 6         22 state $startingof = {
25             'message' => [' ----- The following addresses had delivery problems -----'],
26             'error' => [' ----- Non-delivered information -----'],
27             };
28 6         13 state $messagesof = {
29             'filtered' => ['Mail Delivery Failed... User unknown'],
30             'mailboxfull' => ["The number of messages in recipient's mailbox exceeded the local limit."],
31             };
32              
33 6         36 my $dscontents = [__PACKAGE__->DELIVERYSTATUS];
34 6         31 my $emailsteak = Sisimai::RFC5322->fillet($mbody, $rebackbone);
35 6         18 my $readcursor = 0; # (Integer) Points the current cursor position
36 6         12 my $recipients = 0; # (Integer) The number of 'Final-Recipient' header
37 6         15 my $v = undef;
38              
39 6         37 for my $e ( split("\n", $emailsteak->[0]) ) {
40             # Read error messages and delivery status lines from the head of the email
41             # to the previous line of the beginning of the original message.
42 42 100       67 unless( $readcursor ) {
43             # Beginning of the bounce message or message/delivery-status part
44 18 100       75 $readcursor |= $indicators->{'deliverystatus'} if index($e, $startingof->{'message'}->[0]) == 0;
45 18         29 next;
46             }
47 24 50       51 next unless $readcursor & $indicators->{'deliverystatus'};
48 24 100       43 next unless length $e;
49              
50             # This is a MIME-encapsulated message.
51             #
52             # ----_Biglobe000000/00000.biglobe.ne.jp
53             # Content-Type: text/plain; charset="iso-2022-jp"
54             #
55             # ----- The following addresses had delivery problems -----
56             # ********@***.biglobe.ne.jp
57             #
58             # ----- Non-delivered information -----
59             # The number of messages in recipient's mailbox exceeded the local limit.
60             #
61             # ----_Biglobe000000/00000.biglobe.ne.jp
62             # Content-Type: message/rfc822
63             #
64 18         22 $v = $dscontents->[-1];
65              
66 18 100       60 if( $e =~ /\A([^ ]+[@][^ ]+)\z/ ) {
67             # ----- The following addresses had delivery problems -----
68             # ********@***.biglobe.ne.jp
69 6 50       23 if( $v->{'recipient'} ) {
70             # There are multiple recipient addresses in the message body.
71 0         0 push @$dscontents, __PACKAGE__->DELIVERYSTATUS;
72 0         0 $v = $dscontents->[-1];
73             }
74              
75 6         39 my $r = Sisimai::Address->s3s4($1);
76 6 50       33 next unless Sisimai::RFC5322->is_emailaddress($r);
77 6         21 $v->{'recipient'} = $r;
78 6         19 $recipients++;
79              
80             } else {
81 12 100       51 next if $e =~ /\A[^\w]/;
82 6         52 $v->{'diagnosis'} .= $e.' ';
83             }
84             }
85 6 50       25 return undef unless $recipients;
86              
87 6         17 for my $e ( @$dscontents ) {
88 6         44 $e->{'diagnosis'} = Sisimai::String->sweep($e->{'diagnosis'});
89              
90 6         27 SESSION: for my $r ( keys %$messagesof ) {
91             # Verify each regular expression of session errors
92 8 100       20 next unless grep { index($e->{'diagnosis'}, $_) > -1 } @{ $messagesof->{ $r } };
  8         50  
  8         18  
93 6         12 $e->{'reason'} = $r;
94 6         17 last;
95             }
96             }
97 6         32 return { 'ds' => $dscontents, 'rfc822' => $emailsteak->[1] };
98             }
99              
100             1;
101             __END__