File Coverage

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


line stmt bran cond sub pod time code
1             package Sisimai::Lhost::Biglobe;
2 16     16   5893 use parent 'Sisimai::Lhost';
  16         35  
  16         89  
3 16     16   996 use feature ':5.10';
  16         30  
  16         1071  
4 16     16   90 use strict;
  16         32  
  16         333  
5 16     16   71 use warnings;
  16         29  
  16         11397  
6              
7 2     2 1 1161 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 757 my $class = shift;
16 204   100     672 my $mhead = shift // return undef;
17 203   50     546 my $mbody = shift // return undef;
18              
19 203 100       1062 return undef unless $mhead->{'from'} =~ /postmaster[@](?:biglobe|inacatv|tmtv|ttv)[.]ne[.]jp/;
20 6 50       27 return undef unless index($mhead->{'subject'}, 'Returned mail:') == 0;
21              
22 6         30 state $indicators = __PACKAGE__->INDICATORS;
23 6         20 state $rebackbone = qr|^Content-Type:[ ]message/rfc822|m;
24 6         20 state $startingof = {
25             'message' => [' ----- The following addresses had delivery problems -----'],
26             'error' => [' ----- Non-delivered information -----'],
27             };
28 6         15 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         29 my $dscontents = [__PACKAGE__->DELIVERYSTATUS];
34 6         41 my $emailsteak = Sisimai::RFC5322->fillet($mbody, $rebackbone);
35 6         14 my $readcursor = 0; # (Integer) Points the current cursor position
36 6         14 my $recipients = 0; # (Integer) The number of 'Final-Recipient' header
37 6         8 my $v = undef;
38              
39 6         39 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       70 unless( $readcursor ) {
43             # Beginning of the bounce message or message/delivery-status part
44 18 100       57 $readcursor |= $indicators->{'deliverystatus'} if index($e, $startingof->{'message'}->[0]) == 0;
45 18         28 next;
46             }
47 24 50       51 next unless $readcursor & $indicators->{'deliverystatus'};
48 24 100       54 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       55 if( $e =~ /\A([^ ]+[@][^ ]+)\z/ ) {
67             # ----- The following addresses had delivery problems -----
68             # ********@***.biglobe.ne.jp
69 6 50       19 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         42 my $r = Sisimai::Address->s3s4($1);
76 6 50       29 next unless Sisimai::RFC5322->is_emailaddress($r);
77 6         18 $v->{'recipient'} = $r;
78 6         10 $recipients++;
79              
80             } else {
81 12 100       34 next if $e =~ /\A[^\w]/;
82 6         29 $v->{'diagnosis'} .= $e.' ';
83             }
84             }
85 6 50       109 return undef unless $recipients;
86              
87 6         15 for my $e ( @$dscontents ) {
88 6         41 $e->{'diagnosis'} = Sisimai::String->sweep($e->{'diagnosis'});
89              
90 6         54 SESSION: for my $r ( keys %$messagesof ) {
91             # Verify each regular expression of session errors
92 6 50       11 next unless grep { index($e->{'diagnosis'}, $_) > -1 } @{ $messagesof->{ $r } };
  6         38  
  6         18  
93 6         15 $e->{'reason'} = $r;
94 6         17 last;
95             }
96             }
97 6         32 return { 'ds' => $dscontents, 'rfc822' => $emailsteak->[1] };
98             }
99              
100             1;
101             __END__