sisimai 4.22.3-java → 4.22.4-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sisimai might be problematic. Click here for more details.

Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Benchmarks.mk +54 -0
  4. data/ChangeLog.md +23 -2
  5. data/Developers.mk +42 -35
  6. data/Makefile +10 -0
  7. data/README-JA.md +13 -13
  8. data/README.md +14 -14
  9. data/lib/sisimai.rb +12 -18
  10. data/lib/sisimai/address.rb +64 -82
  11. data/lib/sisimai/arf.rb +27 -42
  12. data/lib/sisimai/bite/email.rb +2 -4
  13. data/lib/sisimai/bite/email/activehunter.rb +12 -17
  14. data/lib/sisimai/bite/email/amazonses.rb +30 -48
  15. data/lib/sisimai/bite/email/amazonworkmail.rb +20 -27
  16. data/lib/sisimai/bite/email/aol.rb +27 -35
  17. data/lib/sisimai/bite/email/apachejames.rb +17 -28
  18. data/lib/sisimai/bite/email/bigfoot.rb +20 -33
  19. data/lib/sisimai/bite/email/biglobe.rb +15 -24
  20. data/lib/sisimai/bite/email/courier.rb +37 -61
  21. data/lib/sisimai/bite/email/domino.rb +19 -28
  22. data/lib/sisimai/bite/email/einsundeins.rb +20 -34
  23. data/lib/sisimai/bite/email/exchange2003.rb +25 -43
  24. data/lib/sisimai/bite/email/exchange2007.rb +15 -23
  25. data/lib/sisimai/bite/email/exim.rb +101 -120
  26. data/lib/sisimai/bite/email/ezweb.rb +28 -44
  27. data/lib/sisimai/bite/email/facebook.rb +26 -37
  28. data/lib/sisimai/bite/email/fml.rb +11 -20
  29. data/lib/sisimai/bite/email/gmx.rb +17 -27
  30. data/lib/sisimai/bite/email/google.rb +19 -29
  31. data/lib/sisimai/bite/email/gsuite.rb +39 -48
  32. data/lib/sisimai/bite/email/imailserver.rb +25 -39
  33. data/lib/sisimai/bite/email/interscanmss.rb +19 -26
  34. data/lib/sisimai/bite/email/kddi.rb +20 -33
  35. data/lib/sisimai/bite/email/mailfoundry.rb +14 -24
  36. data/lib/sisimai/bite/email/mailmarshalsmtp.rb +15 -24
  37. data/lib/sisimai/bite/email/mailru.rb +40 -59
  38. data/lib/sisimai/bite/email/mcafee.rb +21 -35
  39. data/lib/sisimai/bite/email/messagelabs.rb +23 -38
  40. data/lib/sisimai/bite/email/messagingserver.rb +15 -27
  41. data/lib/sisimai/bite/email/mfilter.rb +19 -28
  42. data/lib/sisimai/bite/email/mxlogic.rb +31 -49
  43. data/lib/sisimai/bite/email/notes.rb +16 -24
  44. data/lib/sisimai/bite/email/office365.rb +29 -38
  45. data/lib/sisimai/bite/email/opensmtpd.rb +50 -67
  46. data/lib/sisimai/bite/email/outlook.rb +24 -36
  47. data/lib/sisimai/bite/email/postfix.rb +33 -42
  48. data/lib/sisimai/bite/email/qmail.rb +44 -59
  49. data/lib/sisimai/bite/email/receivingses.rb +28 -36
  50. data/lib/sisimai/bite/email/sendgrid.rb +28 -37
  51. data/lib/sisimai/bite/email/sendmail.rb +35 -51
  52. data/lib/sisimai/bite/email/surfcontrol.rb +17 -25
  53. data/lib/sisimai/bite/email/userdefined.rb +17 -28
  54. data/lib/sisimai/bite/email/v5sendmail.rb +32 -41
  55. data/lib/sisimai/bite/email/verizon.rb +31 -56
  56. data/lib/sisimai/bite/email/x1.rb +11 -18
  57. data/lib/sisimai/bite/email/x2.rb +11 -23
  58. data/lib/sisimai/bite/email/x3.rb +10 -19
  59. data/lib/sisimai/bite/email/x4.rb +46 -65
  60. data/lib/sisimai/bite/email/x5.rb +26 -37
  61. data/lib/sisimai/bite/email/yahoo.rb +11 -19
  62. data/lib/sisimai/bite/email/yandex.rb +19 -30
  63. data/lib/sisimai/bite/email/zoho.rb +21 -30
  64. data/lib/sisimai/bite/json.rb +1 -2
  65. data/lib/sisimai/bite/json/amazonses.rb +20 -25
  66. data/lib/sisimai/bite/json/sendgrid.rb +1 -1
  67. data/lib/sisimai/data.rb +36 -55
  68. data/lib/sisimai/data/json.rb +3 -3
  69. data/lib/sisimai/data/yaml.rb +1 -1
  70. data/lib/sisimai/datetime.rb +5 -21
  71. data/lib/sisimai/mail.rb +4 -6
  72. data/lib/sisimai/mail/maildir.rb +1 -1
  73. data/lib/sisimai/mda.rb +41 -44
  74. data/lib/sisimai/message.rb +2 -3
  75. data/lib/sisimai/message/email.rb +42 -52
  76. data/lib/sisimai/message/json.rb +7 -7
  77. data/lib/sisimai/mime.rb +25 -23
  78. data/lib/sisimai/order/email.rb +2 -2
  79. data/lib/sisimai/order/json.rb +2 -7
  80. data/lib/sisimai/reason.rb +41 -46
  81. data/lib/sisimai/reason/blocked.rb +60 -71
  82. data/lib/sisimai/reason/contenterror.rb +4 -8
  83. data/lib/sisimai/reason/delivered.rb +1 -3
  84. data/lib/sisimai/reason/exceedlimit.rb +10 -20
  85. data/lib/sisimai/reason/expired.rb +5 -9
  86. data/lib/sisimai/reason/feedback.rb +1 -3
  87. data/lib/sisimai/reason/filtered.rb +19 -38
  88. data/lib/sisimai/reason/hasmoved.rb +5 -8
  89. data/lib/sisimai/reason/hostunknown.rb +11 -18
  90. data/lib/sisimai/reason/mailboxfull.rb +14 -24
  91. data/lib/sisimai/reason/mailererror.rb +3 -5
  92. data/lib/sisimai/reason/mesgtoobig.rb +15 -25
  93. data/lib/sisimai/reason/networkerror.rb +8 -10
  94. data/lib/sisimai/reason/norelaying.rb +9 -14
  95. data/lib/sisimai/reason/notaccept.rb +9 -21
  96. data/lib/sisimai/reason/onhold.rb +3 -8
  97. data/lib/sisimai/reason/policyviolation.rb +8 -10
  98. data/lib/sisimai/reason/rejected.rb +36 -49
  99. data/lib/sisimai/reason/securityerror.rb +11 -13
  100. data/lib/sisimai/reason/spamdetected.rb +23 -37
  101. data/lib/sisimai/reason/suspend.rb +9 -10
  102. data/lib/sisimai/reason/syntaxerror.rb +3 -4
  103. data/lib/sisimai/reason/systemerror.rb +7 -9
  104. data/lib/sisimai/reason/systemfull.rb +2 -4
  105. data/lib/sisimai/reason/toomanyconn.rb +17 -30
  106. data/lib/sisimai/reason/undefined.rb +1 -3
  107. data/lib/sisimai/reason/userunknown.rb +28 -38
  108. data/lib/sisimai/reason/vacation.rb +4 -6
  109. data/lib/sisimai/reason/virusdetected.rb +4 -6
  110. data/lib/sisimai/rfc2606.rb +1 -2
  111. data/lib/sisimai/rfc3464.rb +87 -101
  112. data/lib/sisimai/rfc3834.rb +29 -39
  113. data/lib/sisimai/rfc5322.rb +17 -24
  114. data/lib/sisimai/rhost.rb +10 -7
  115. data/lib/sisimai/rhost/exchangeonline.rb +124 -255
  116. data/lib/sisimai/rhost/franceptt.rb +2 -2
  117. data/lib/sisimai/rhost/godaddy.rb +12 -25
  118. data/lib/sisimai/rhost/googleapps.rb +82 -183
  119. data/lib/sisimai/smtp.rb +4 -4
  120. data/lib/sisimai/smtp/error.rb +8 -8
  121. data/lib/sisimai/smtp/reply.rb +1 -1
  122. data/lib/sisimai/smtp/status.rb +1 -0
  123. data/lib/sisimai/string.rb +5 -7
  124. data/lib/sisimai/version.rb +1 -1
  125. data/set-of-emails/README.md +1 -1
  126. data/set-of-emails/maildir/bsd/README.md +50 -50
  127. data/sisimai-java.gemspec +1 -1
  128. data/sisimai.gemspec +1 -1
  129. metadata +4 -4
  130. data/lib/sisimai/skeleton.rb +0 -43
@@ -16,20 +16,18 @@ module Sisimai
16
16
  }
17
17
  end
18
18
  def headerlist; return []; end
19
- def pattern; return []; end
20
19
 
21
20
  # @abstract MTA list
22
21
  # @return [Array] MTA list with order
23
22
  def index
24
- return %w|
23
+ return %w[
25
24
  Sendmail Postfix Qmail Exim Courier OpenSMTPD Exchange2007 Exchange2003
26
25
  Google Yahoo GSuite Aol Outlook Office365 SendGrid AmazonSES MailRu
27
26
  Yandex MessagingServer Domino Notes ReceivingSES AmazonWorkMail Verizon
28
27
  GMX Bigfoot Facebook Zoho EinsUndEins MessageLabs EZweb KDDI Biglobe
29
28
  ApacheJames McAfee MXLogic MailFoundry IMailServer
30
29
  MFILTER Activehunter InterScanMSS SurfControl MailMarshalSMTP
31
- X1 X2 X3 X4 X5 V5sendmail FML
32
- |
30
+ X1 X2 X3 X4 X5 V5sendmail FML]
33
31
  end
34
32
 
35
33
  # @abstract Parse bounce messages
@@ -7,22 +7,15 @@ module Sisimai::Bite::Email
7
7
  # Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Activehunter.pm
8
8
  require 'sisimai/bite/email'
9
9
 
10
- Re0 = {
11
- :from => %r/\A"MAILER-DAEMON"/,
12
- :subject => %r/FAILURE NOTICE :/,
13
- }.freeze
14
- Re1 = {
15
- :begin => %r/\A ----- The following addresses had permanent fatal errors -----\z/,
16
- :error => %r/\A ----- Transcript of session follows -----\z/,
17
- :rfc822 => %r|\AContent-type: message/rfc822\z|,
18
- :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
19
- }.freeze
20
10
  Indicators = Sisimai::Bite::Email.INDICATORS
11
+ StartingOf = {
12
+ message: [' ----- The following addresses had permanent fatal errors -----'],
13
+ rfc822: ['Content-type: message/rfc822'],
14
+ }.freeze
21
15
 
22
16
  def description; return 'TransWARE Active!hunter'; end
23
17
  def smtpagent; return Sisimai::Bite.smtpagent(self); end
24
18
  def headerlist; return ['X-AHMAILID']; end
25
- def pattern; return Re0; end
26
19
 
27
20
  # Parse bounce messages from TransWARE Active!hunter
28
21
  # @param [Hash] mhead Message headers of a bounce email
@@ -38,6 +31,9 @@ module Sisimai::Bite::Email
38
31
  def scan(mhead, mbody)
39
32
  return nil unless mhead
40
33
  return nil unless mbody
34
+
35
+ # :from => %r/\A"MAILER-DAEMON"/,
36
+ # :subject => %r/FAILURE NOTICE :/,
41
37
  return nil unless mhead['x-ahmailid']
42
38
 
43
39
  dscontents = [Sisimai::Bite.DELIVERYSTATUS]
@@ -48,10 +44,10 @@ module Sisimai::Bite::Email
48
44
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
49
45
  v = nil
50
46
 
51
- hasdivided.each do |e|
47
+ while e = hasdivided.shift do
52
48
  if readcursor.zero?
53
49
  # Beginning of the bounce message or delivery status part
54
- if e =~ Re1[:begin]
50
+ if e == StartingOf[:message][0]
55
51
  readcursor |= Indicators[:deliverystatus]
56
52
  next
57
53
  end
@@ -59,7 +55,7 @@ module Sisimai::Bite::Email
59
55
 
60
56
  if (readcursor & Indicators[:'message-rfc822']).zero?
61
57
  # Beginning of the original message part
62
- if e =~ Re1[:rfc822]
58
+ if e == StartingOf[:rfc822][0]
63
59
  readcursor |= Indicators[:'message-rfc822']
64
60
  next
65
61
  end
@@ -73,7 +69,6 @@ module Sisimai::Bite::Email
73
69
  next
74
70
  end
75
71
  rfc822list << e
76
-
77
72
  else
78
73
  # Before "message/rfc822"
79
74
  next if (readcursor & Indicators[:deliverystatus]).zero?
@@ -95,8 +90,8 @@ module Sisimai::Bite::Email
95
90
  v = dscontents[-1]
96
91
  end
97
92
  v['recipient'] = cv[1]
93
+ v['diagnosis'] = ''
98
94
  recipients += 1
99
-
100
95
  else
101
96
  # ----- Transcript of session follows -----
102
97
  # 550 sorry, no mailbox here by that name (#5.1.1 - chkusr)
@@ -106,8 +101,8 @@ module Sisimai::Bite::Email
106
101
  end
107
102
  end
108
103
  return nil if recipients.zero?
109
- require 'sisimai/string'
110
104
 
105
+ require 'sisimai/string'
111
106
  dscontents.map do |e|
112
107
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
113
108
  e['agent'] = self.smtpagent
@@ -8,24 +8,12 @@ module Sisimai::Bite::Email
8
8
  require 'sisimai/bite/email'
9
9
 
10
10
  # http://aws.amazon.com/ses/
11
- ReE = { :'x-mailer' => %r/Amazon[ ]WorkMail/ }.freeze
12
- Re0 = {
13
- :from => %r/\AMAILER-DAEMON[@]email[-]bounces[.]amazonses[.]com\z/,
14
- :subject => %r/\ADelivery Status Notification [(]Failure[)]\z/,
15
- }.freeze
16
- Re1 = {
17
- :begin => %r/\A(?:
18
- The[ ]following[ ]message[ ]to[ ][<]
19
- |An[ ]error[ ]occurred[ ]while[ ]trying[ ]to[ ]deliver[ ]the[ ]mail[ ]
20
- )
21
- /x,
22
- :rfc822 => %r|\Acontent-type: message/rfc822\z|,
23
- :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
24
- }.freeze
25
- ReFailure = {
26
- expired: %r/Delivery[ ]expired/x,
27
- }.freeze
28
11
  Indicators = Sisimai::Bite::Email.INDICATORS
12
+ StartingOf = {
13
+ message: ['The following message to <', 'An error occurred while trying to deliver the mail'],
14
+ rfc822: ['content-type: message/rfc822'],
15
+ }.freeze
16
+ ReFailures = { expired: %r/Delivery expired/ }.freeze
29
17
 
30
18
  def description; return 'Amazon SES(Sending): http://aws.amazon.com/ses/'; end
31
19
  def smtpagent; return Sisimai::Bite.smtpagent(self); end
@@ -35,7 +23,6 @@ module Sisimai::Bite::Email
35
23
  # X-AWS-Outgoing: 199.255.192.156
36
24
  # X-SES-Outgoing: 2016.10.12-54.240.27.6
37
25
  def headerlist; return ['X-AWS-Outgoing', 'X-SES-Outgoing', 'x-amz-sns-message-id']; end
38
- def pattern; return Re0; end
39
26
 
40
27
  # Parse bounce messages from Amazon SES
41
28
  # @param [Hash] mhead Message headers of a bounce email
@@ -52,9 +39,11 @@ module Sisimai::Bite::Email
52
39
  return nil unless mhead
53
40
  return nil unless mbody
54
41
 
55
- match = 0
56
- return nil if mhead['x-mailer'] =~ ReE[:'x-mailer']
42
+ # :from => %r/\AMAILER-DAEMON[@]email[-]bounces[.]amazonses[.]com\z/,
43
+ # :subject => %r/\ADelivery Status Notification [(]Failure[)]\z/,
44
+ return nil if mhead['x-mailer'].to_s.include?('Amazon WorkMail')
57
45
 
46
+ match = 0
58
47
  match += 1 if mhead['x-aws-outgoing']
59
48
  match += 1 if mhead['x-ses-outgoing']
60
49
  return nil if match.zero?
@@ -72,14 +61,14 @@ module Sisimai::Bite::Email
72
61
  }
73
62
  v = nil
74
63
 
75
- hasdivided.each do |e|
64
+ while e = hasdivided.shift do
76
65
  # Save the current line for the next loop
77
66
  havepassed << e
78
67
  p = havepassed[-2]
79
68
 
80
69
  if readcursor.zero?
81
70
  # Beginning of the bounce message or delivery status part
82
- if e =~ Re1[:begin]
71
+ if e.start_with?(StartingOf[:message][0], StartingOf[:message][1])
83
72
  readcursor |= Indicators[:deliverystatus]
84
73
  next
85
74
  end
@@ -87,7 +76,7 @@ module Sisimai::Bite::Email
87
76
 
88
77
  if (readcursor & Indicators[:'message-rfc822']).zero?
89
78
  # Beginning of the original message part
90
- if e =~ Re1[:rfc822]
79
+ if e == StartingOf[:rfc822][0]
91
80
  readcursor |= Indicators[:'message-rfc822']
92
81
  next
93
82
  end
@@ -102,7 +91,6 @@ module Sisimai::Bite::Email
102
91
  next
103
92
  end
104
93
  rfc822list << e
105
-
106
94
  else
107
95
  # Before "message/rfc822"
108
96
  next if (readcursor & Indicators[:deliverystatus]).zero?
@@ -121,7 +109,7 @@ module Sisimai::Bite::Email
121
109
  # content-type: message/rfc822
122
110
  v = dscontents[-1]
123
111
 
124
- if cv = e.match(/\A[Ff]inal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
112
+ if cv = e.match(/\AFinal-Recipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
125
113
  # Final-Recipient: RFC822; userunknown@example.jp
126
114
  if v['recipient']
127
115
  # There are multiple recipient addresses in the message body.
@@ -131,42 +119,39 @@ module Sisimai::Bite::Email
131
119
  v['recipient'] = cv[1]
132
120
  recipients += 1
133
121
 
134
- elsif cv = e.match(/\A[Xx]-[Aa]ctual-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
122
+ elsif cv = e.match(/\AX-Actual-Recipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
135
123
  # X-Actual-Recipient: RFC822; kijitora@example.co.jp
136
124
  v['alias'] = cv[1]
137
125
 
138
- elsif cv = e.match(/\A[Aa]ction:[ ]*(.+)\z/)
126
+ elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
139
127
  # Action: failed
140
128
  v['action'] = cv[1].downcase
141
129
 
142
- elsif cv = e.match(/\A[Ss]tatus:[ ]*(\d[.]\d+[.]\d+)/)
130
+ elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
143
131
  # Status: 5.1.1
144
132
  # Status:5.2.0
145
133
  # Status: 5.1.0 (permanent failure)
146
134
  v['status'] = cv[1]
147
135
 
148
- elsif cv = e.match(/\A[Rr]emote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
136
+ elsif cv = e.match(/\ARemote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
149
137
  # Remote-MTA: DNS; mx.example.jp
150
138
  v['rhost'] = cv[1].downcase
151
139
 
152
- elsif cv = e.match(/\A[Ll]ast-[Aa]ttempt-[Dd]ate:[ ]*(.+)\z/)
140
+ elsif cv = e.match(/\ALast-Attempt-Date:[ ]*(.+)\z/)
153
141
  # Last-Attempt-Date: Fri, 14 Feb 2014 12:30:08 -0500
154
142
  v['date'] = cv[1]
155
-
156
143
  else
157
- if cv = e.match(/\A[Dd]iagnostic-[Cc]ode:[ ]*(.+?);[ ]*(.+)\z/)
144
+ if cv = e.match(/\ADiagnostic-Code:[ ]*(.+?);[ ]*(.+)\z/)
158
145
  # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
159
146
  v['spec'] = cv[1].upcase
160
147
  v['diagnosis'] = cv[2]
161
148
 
162
- elsif p =~ /\A[Dd]iagnostic-[Cc]ode:[ ]*/ && cv = e.match(/\A[ \t]+(.+)\z/)
149
+ elsif p.start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
163
150
  # Continued line of the value of Diagnostic-Code header
164
- v['diagnosis'] ||= ''
165
- v['diagnosis'] += ' ' + cv[1]
166
- havepassed[-1] = 'Diagnostic-Code: ' + e
151
+ v['diagnosis'] << ' ' << cv[1]
152
+ havepassed[-1] = 'Diagnostic-Code: ' << e
167
153
  end
168
154
  end
169
-
170
155
  else
171
156
  # The following message to <kijitora@example.jp> was undeliverable.
172
157
  # The reason for the problem:
@@ -178,7 +163,7 @@ module Sisimai::Bite::Email
178
163
  #
179
164
  # Reporting-MTA: dns; a192-79.smtp-out.amazonses.com
180
165
  #
181
- if cv = e.match(/\A[Rr]eporting-MTA:[ ]*[DNSdns]+;[ ]*(.+)\z/)
166
+ if cv = e.match(/\AReporting-MTA:[ ]*[DNSdns]+;[ ]*(.+)\z/)
182
167
  # Reporting-MTA: dns; mx.example.jp
183
168
  next if connheader['lhost'].size > 0
184
169
  connheader['lhost'] = cv[1].downcase
@@ -200,21 +185,19 @@ module Sisimai::Bite::Email
200
185
  recipients = j['ds'].size
201
186
  end
202
187
  end
203
-
204
188
  return nil if recipients.zero?
189
+
205
190
  require 'sisimai/string'
206
191
  require 'sisimai/smtp/status'
207
-
208
192
  dscontents.map do |e|
209
193
  # Set default values if each value is empty.
210
194
  connheader.each_key { |a| e[a] ||= connheader[a] || '' }
211
195
 
212
- e['agent'] = self.smtpagent
213
- e['diagnosis'] ||= ''
214
- e['diagnosis'] = e['diagnosis'].gsub(/\\n/, ' ')
215
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
196
+ e['agent'] = self.smtpagent
197
+ e['diagnosis'] = e['diagnosis'].to_s.gsub(/\\n/, ' ')
198
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
216
199
 
217
- if e['status'] =~ /\A[45][.][01][.]0\z/
200
+ if e['status'].to_s.start_with?('5.0.0', '5.1.0', '4.0.0', '4.1.0')
218
201
  # Get other D.S.N. value from the error message
219
202
  errormessage = e['diagnosis']
220
203
 
@@ -222,14 +205,13 @@ module Sisimai::Bite::Email
222
205
  # 5.1.0 - Unknown address error 550-'5.7.1 ...
223
206
  errormessage = cv[1]
224
207
  end
225
-
226
208
  pseudostatus = Sisimai::SMTP::Status.find(errormessage)
227
209
  e['status'] = pseudostatus if pseudostatus.size > 0
228
210
  end
229
211
 
230
- ReFailure.each_key do |r|
212
+ ReFailures.each_key do |r|
231
213
  # Verify each regular expression of session errors
232
- next unless e['diagnosis'] =~ ReFailure[r]
214
+ next unless e['diagnosis'] =~ ReFailures[r]
233
215
  e['reason'] = r.to_s
234
216
  break
235
217
  end
@@ -7,17 +7,11 @@ module Sisimai::Bite::Email
7
7
  require 'sisimai/bite/email'
8
8
 
9
9
  # https://aws.amazon.com/workmail/
10
- Re0 = {
11
- :'subject' => %r/Delivery[_ ]Status[_ ]Notification[_ ].+Failure/,
12
- :'received' => %r/.+[.]smtp-out[.].+[.]amazonses[.]com\b/,
13
- :'x-mailer' => %r/\AAmazon WorkMail\z/,
14
- }.freeze
15
- Re1 = {
16
- :begin => %r/\ATechnical report:\z/,
17
- :rfc822 => %r|\Acontent-type: message/rfc822\z|,
18
- :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
19
- }.freeze
20
10
  Indicators = Sisimai::Bite::Email.INDICATORS
11
+ StartingOf = {
12
+ message: ['Technical report:'],
13
+ rfc822: ['content-type: message/rfc822'],
14
+ }.freeze
21
15
 
22
16
  def description; return 'Amazon WorkMail: https://aws.amazon.com/workmail/'; end
23
17
  def smtpagent; return Sisimai::Bite.smtpagent(self); end
@@ -26,7 +20,6 @@ module Sisimai::Bite::Email
26
20
  # X-Original-Mailer: Amazon WorkMail
27
21
  # X-Ses-Outgoing: 2016.01.14-54.240.27.159
28
22
  def headerlist; return ['X-SES-Outgoing', 'X-Original-Mailer']; end
29
- def pattern; return Re0; end
30
23
 
31
24
  # Parse bounce messages from Amazon WorkMail
32
25
  # @param [Hash] mhead Message headers of a bounce email
@@ -43,6 +36,9 @@ module Sisimai::Bite::Email
43
36
  return nil unless mhead
44
37
  return nil unless mbody
45
38
 
39
+ # :'subject' => %r/Delivery[_ ]Status[_ ]Notification[_ ].+Failure/,
40
+ # :'received' => %r/.+[.]smtp-out[.].+[.]amazonses[.]com\b/,
41
+ # :'x-mailer' => %r/\AAmazon WorkMail\z/,
46
42
  match = 0
47
43
  xmail = mhead['x-original-mailer'] || mhead['x-mailer'] || ''
48
44
 
@@ -50,7 +46,7 @@ module Sisimai::Bite::Email
50
46
  unless xmail.empty?
51
47
  # X-Mailer: Amazon WorkMail
52
48
  # X-Original-Mailer: Amazon WorkMail
53
- match += 1 if xmail =~ Re0[:'x-mailer']
49
+ match += 1 if xmail == 'Amazon WorkMail'
54
50
  end
55
51
  return nil if match < 2
56
52
 
@@ -66,10 +62,10 @@ module Sisimai::Bite::Email
66
62
  }
67
63
  v = nil
68
64
 
69
- hasdivided.each do |e|
65
+ while e = hasdivided.shift do
70
66
  if readcursor.zero?
71
67
  # Beginning of the bounce message or delivery status part
72
- if e =~ Re1[:begin]
68
+ if e == StartingOf[:message][0]
73
69
  readcursor |= Indicators[:deliverystatus]
74
70
  next
75
71
  end
@@ -77,7 +73,7 @@ module Sisimai::Bite::Email
77
73
 
78
74
  if (readcursor & Indicators[:'message-rfc822']).zero?
79
75
  # Beginning of the original message part
80
- if e =~ Re1[:rfc822]
76
+ if e == StartingOf[:rfc822][0]
81
77
  readcursor |= Indicators[:'message-rfc822']
82
78
  next
83
79
  end
@@ -91,7 +87,6 @@ module Sisimai::Bite::Email
91
87
  next
92
88
  end
93
89
  rfc822list << e
94
-
95
90
  else
96
91
  # Before "message/rfc822"
97
92
  next if (readcursor & Indicators[:deliverystatus]).zero?
@@ -104,7 +99,7 @@ module Sisimai::Bite::Email
104
99
  # Status: 4.4.7
105
100
  v = dscontents[-1]
106
101
 
107
- if cv = e.match(/\A[Ff]inal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
102
+ if cv = e.match(/\AFinal-Recipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
108
103
  # Final-Recipient: RFC822; kijitora@example.jp
109
104
  if v['recipient']
110
105
  # There are multiple recipient addresses in the message body.
@@ -114,16 +109,15 @@ module Sisimai::Bite::Email
114
109
  v['recipient'] = cv[1]
115
110
  recipients += 1
116
111
 
117
- elsif cv = e.match(/\A[Aa]ction:[ ]*(.+)\z/)
112
+ elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
118
113
  # Action: failed
119
114
  v['action'] = cv[1].downcase
120
115
 
121
- elsif cv = e.match(/\A[Ss]tatus:[ ]*(\d[.]\d+[.]\d+)/)
116
+ elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
122
117
  # Status: 5.1.1
123
118
  v['status'] = cv[1]
124
-
125
119
  else
126
- if cv = e.match(/\A[Dd]iagnostic-[Cc]ode:[ ]*(.+?);[ ]*(.+)\z/)
120
+ if cv = e.match(/\ADiagnostic-Code:[ ]*(.+?);[ ]*(.+)\z/)
127
121
  # Diagnostic-Code: SMTP; 550 5.1.1 <kijitora@example.jp>... User Unknown
128
122
  v['spec'] = cv[1].upcase
129
123
  v['diagnosis'] = cv[2]
@@ -134,7 +128,7 @@ module Sisimai::Bite::Email
134
128
  #
135
129
  # Reporting-MTA: dsn; a27-85.smtp-out.us-west-2.amazonses.com
136
130
  #
137
- if cv = e.match(/\A[Rr]eporting-MTA:[ ]*[DNSdns]+;[ ]*(.+)\z/)
131
+ if cv = e.match(/\AReporting-MTA:[ ]*[DNSdns]+;[ ]*(.+)\z/)
138
132
  # Reporting-MTA: dns; mx.example.jp
139
133
  next if connheader['lhost'].size > 0
140
134
  connheader['lhost'] = cv[1].downcase
@@ -146,21 +140,19 @@ module Sisimai::Bite::Email
146
140
  # <head>
147
141
  # <meta name="Generator" content="Amazon WorkMail v3.0-2023.77">
148
142
  # <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
149
- break if e =~ /\A[<]!DOCTYPE HTML[>][<]html[>]\z/
143
+ break if e.start_with?('<!DOCTYPE HTML><html>')
150
144
  end
151
145
  end
152
-
153
146
  return nil if recipients.zero?
147
+
154
148
  require 'sisimai/string'
155
149
  require 'sisimai/smtp/status'
156
-
157
150
  dscontents.map do |e|
158
151
  # Set default values if each value is empty.
159
152
  connheader.each_key { |a| e[a] ||= connheader[a] || '' }
160
153
 
161
154
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
162
-
163
- if e['status'] =~ /\A[45][.][01][.]0\z/
155
+ if e['status'].to_s.start_with?('5.0.0', '5.1.0', '4.0.0', '4.1.0')
164
156
  # Get other D.S.N. value from the error message
165
157
  errormessage = e['diagnosis']
166
158
 
@@ -168,6 +160,7 @@ module Sisimai::Bite::Email
168
160
  # 5.1.0 - Unknown address error 550-'5.7.1 ...
169
161
  errormessage = cv[1]
170
162
  end
163
+
171
164
  pseudostatus = Sisimai::SMTP::Status.find(errormessage)
172
165
  e['status'] = pseudostatus if pseudostatus.size > 0
173
166
  end
@@ -6,20 +6,15 @@ module Sisimai::Bite::Email
6
6
  # Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Aol.pm
7
7
  require 'sisimai/bite/email'
8
8
 
9
- Re0 = {
10
- :from => %r/\APostmaster [<]Postmaster[@]AOL[.]com[>]\z/,
11
- :subject => %r/\AUndeliverable: /,
12
- }.freeze
13
- Re1 = {
14
- :begin => %r|\AContent-Type: message/delivery-status|,
15
- :rfc822 => %r|\AContent-Type: message/rfc822|,
16
- :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
9
+ Indicators = Sisimai::Bite::Email.INDICATORS
10
+ StartingOf = {
11
+ message: ['Content-Type: message/delivery-status'],
12
+ rfc822: ['Content-Type: message/rfc822'],
17
13
  }.freeze
18
- ReFailure = {
19
- hostunknown: %r/Host[ ]or[ ]domain[ ]name[ ]not[ ]found/,
20
- notaccept: %r/type=MX:[ ]Malformed[ ]or[ ]unexpected[ ]name[ ]server[ ]reply/,
14
+ ReFailures = {
15
+ hostunknown: %r/Host or domain name not found/,
16
+ notaccept: %r/type=MX: Malformed or unexpected name server reply/,
21
17
  }.freeze
22
- Indicators = Sisimai::Bite::Email.INDICATORS
23
18
 
24
19
  def description; return 'Aol Mail: http://www.aol.com'; end
25
20
  def smtpagent; return Sisimai::Bite.smtpagent(self); end
@@ -35,7 +30,6 @@ module Sisimai::Bite::Email
35
30
  # X-Outbound-Mail-Relay-Queue-ID: 07391702BF4DC
36
31
  # X-Outbound-Mail-Relay-Sender: rfc822; shironeko@aol.example.jp
37
32
  def headerlist; return ['X-AOL-IP']; end
38
- def pattern; return Re0; end
39
33
 
40
34
  # Parse bounce messages from Aol Mail
41
35
  # @param [Hash] mhead Message headers of a bounce email
@@ -51,6 +45,9 @@ module Sisimai::Bite::Email
51
45
  def scan(mhead, mbody)
52
46
  return nil unless mhead
53
47
  return nil unless mbody
48
+
49
+ # :from => %r/\APostmaster [<]Postmaster[@]AOL[.]com[>]\z/,
50
+ # :subject => %r/\AUndeliverable: /,
54
51
  return nil unless mhead['x-aol-ip']
55
52
 
56
53
  dscontents = [Sisimai::Bite.DELIVERYSTATUS]
@@ -67,14 +64,14 @@ module Sisimai::Bite::Email
67
64
  }
68
65
  v = nil
69
66
 
70
- hasdivided.each do |e|
67
+ while e = hasdivided.shift do
71
68
  # Save the current line for the next loop
72
69
  havepassed << e
73
70
  p = havepassed[-2]
74
71
 
75
72
  if readcursor.zero?
76
73
  # Beginning of the bounce message or delivery status part
77
- if e =~ Re1[:begin]
74
+ if e.start_with?(StartingOf[:message][0])
78
75
  readcursor |= Indicators[:deliverystatus]
79
76
  next
80
77
  end
@@ -82,7 +79,7 @@ module Sisimai::Bite::Email
82
79
 
83
80
  if (readcursor & Indicators[:'message-rfc822']).zero?
84
81
  # Beginning of the original message part
85
- if e =~ Re1[:rfc822]
82
+ if e.start_with?(StartingOf[:rfc822][0])
86
83
  readcursor |= Indicators[:'message-rfc822']
87
84
  next
88
85
  end
@@ -96,7 +93,6 @@ module Sisimai::Bite::Email
96
93
  next
97
94
  end
98
95
  rfc822list << e
99
-
100
96
  else
101
97
  # Before "message/rfc822"
102
98
  next if (readcursor & Indicators[:deliverystatus]).zero?
@@ -111,7 +107,7 @@ module Sisimai::Bite::Email
111
107
  # Diagnostic-Code: smtp; 550 5.2.2 <kijitora@example.co.jp>... Mailbox Full
112
108
  v = dscontents[-1]
113
109
 
114
- if cv = e.match(/\A[Ff]inal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
110
+ if cv = e.match(/\AFinal-Recipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
115
111
  # Final-Recipient: RFC822; userunknown@example.jp
116
112
  if v['recipient']
117
113
  # There are multiple recipient addresses in the message body.
@@ -121,33 +117,30 @@ module Sisimai::Bite::Email
121
117
  v['recipient'] = cv[1]
122
118
  recipients += 1
123
119
 
124
- elsif cv = e.match(/\A[Aa]ction:[ ]*(.+)\z/)
120
+ elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
125
121
  # Action: failed
126
122
  v['action'] = cv[1].downcase
127
123
 
128
- elsif cv = e.match(/\A[Ss]tatus:[ ]*(\d[.]\d+[.]\d+)/)
124
+ elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
129
125
  # Status:5.2.0
130
126
  v['status'] = cv[1]
131
127
 
132
- elsif cv = e.match(/\A[Rr]emote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
128
+ elsif cv = e.match(/\ARemote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
133
129
  # Remote-MTA: DNS; mx.example.jp
134
130
  v['rhost'] = cv[1].downcase
135
-
136
131
  else
137
132
  # Get error message
138
- if cv = e.match(/\A[Dd]iagnostic-[Cc]ode:[ ]*(.+?);[ ]*(.+)\z/)
133
+ if cv = e.match(/\ADiagnostic-Code:[ ]*(.+?);[ ]*(.+)\z/)
139
134
  # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
140
135
  v['spec'] = cv[1].upcase
141
136
  v['diagnosis'] = cv[2]
142
137
 
143
- elsif p =~ /\A[Dd]iagnostic-[Cc]ode:[ ]*/ && cv = e.match(/\A[ \t]+(.+)\z/)
138
+ elsif p.start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
144
139
  # Continued line of the value of Diagnostic-Code header
145
- v['diagnosis'] ||= ''
146
- v['diagnosis'] += ' ' + cv[1]
147
- havepassed[-1] = 'Diagnostic-Code: ' + e
140
+ v['diagnosis'] << ' ' << cv[1]
141
+ havepassed[-1] = 'Diagnostic-Code: ' << e
148
142
  end
149
143
  end
150
-
151
144
  else
152
145
  # Content-Type: message/delivery-status
153
146
  # Content-Transfer-Encoding: 7bit
@@ -156,13 +149,13 @@ module Sisimai::Bite::Email
156
149
  # X-Outbound-Mail-Relay-Queue-ID: CCBA43800007F
157
150
  # X-Outbound-Mail-Relay-Sender: rfc822; shironeko@aol.example.jp
158
151
  # Arrival-Date: Fri, 21 Nov 2014 17:14:34 -0500 (EST)
159
- if cv = e.match(/\A[Rr]eporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
152
+ if cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
160
153
  # Reporting-MTA: dns; mx.example.jp
161
154
  next if connheader['lhost'].size > 0
162
155
  connheader['lhost'] = cv[1].downcase
163
156
  connvalues += 1
164
157
 
165
- elsif cv = e.match(/\A[Aa]rrival-[Dd]ate:[ ]*(.+)\z/)
158
+ elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
166
159
  # Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
167
160
  next if connheader['date'].size > 0
168
161
  connheader['date'] = cv[1]
@@ -172,11 +165,10 @@ module Sisimai::Bite::Email
172
165
  end
173
166
  end
174
167
  end
175
-
176
168
  return nil if recipients.zero?
169
+
177
170
  require 'sisimai/string'
178
171
  require 'sisimai/smtp/status'
179
-
180
172
  dscontents.map do |e|
181
173
  # Set default values if each value is empty.
182
174
  connheader.each_key { |a| e[a] ||= connheader[a] || '' }
@@ -185,14 +177,14 @@ module Sisimai::Bite::Email
185
177
  e['diagnosis'] = e['diagnosis'].gsub(/\\n/, ' ')
186
178
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
187
179
 
188
- ReFailure.each_key do |r|
180
+ ReFailures.each_key do |r|
189
181
  # Verify each regular expression of session errors
190
- next unless e['diagnosis'] =~ ReFailure[r]
182
+ next unless e['diagnosis'] =~ ReFailures[r]
191
183
  e['reason'] = r.to_s
192
184
  break
193
185
  end
194
186
 
195
- if e['status'].empty? || e['status'] =~ /\A\d[.]0[.]0\z/
187
+ if e['status'].empty? || e['status'].end_with?('.0.0')
196
188
  # There is no value of Status header or the value is 5.0.0, 4.0.0
197
189
  pseudostatus = Sisimai::SMTP::Status.find(e['diagnosis'])
198
190
  e['status'] = pseudostatus if pseudostatus.size > 0