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