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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/Benchmarks.mk +54 -0
- data/ChangeLog.md +23 -2
- data/Developers.mk +42 -35
- data/Makefile +10 -0
- data/README-JA.md +13 -13
- data/README.md +14 -14
- data/lib/sisimai.rb +12 -18
- data/lib/sisimai/address.rb +64 -82
- data/lib/sisimai/arf.rb +27 -42
- data/lib/sisimai/bite/email.rb +2 -4
- data/lib/sisimai/bite/email/activehunter.rb +12 -17
- data/lib/sisimai/bite/email/amazonses.rb +30 -48
- data/lib/sisimai/bite/email/amazonworkmail.rb +20 -27
- data/lib/sisimai/bite/email/aol.rb +27 -35
- data/lib/sisimai/bite/email/apachejames.rb +17 -28
- data/lib/sisimai/bite/email/bigfoot.rb +20 -33
- data/lib/sisimai/bite/email/biglobe.rb +15 -24
- data/lib/sisimai/bite/email/courier.rb +37 -61
- data/lib/sisimai/bite/email/domino.rb +19 -28
- data/lib/sisimai/bite/email/einsundeins.rb +20 -34
- data/lib/sisimai/bite/email/exchange2003.rb +25 -43
- data/lib/sisimai/bite/email/exchange2007.rb +15 -23
- data/lib/sisimai/bite/email/exim.rb +101 -120
- data/lib/sisimai/bite/email/ezweb.rb +28 -44
- data/lib/sisimai/bite/email/facebook.rb +26 -37
- data/lib/sisimai/bite/email/fml.rb +11 -20
- data/lib/sisimai/bite/email/gmx.rb +17 -27
- data/lib/sisimai/bite/email/google.rb +19 -29
- data/lib/sisimai/bite/email/gsuite.rb +39 -48
- data/lib/sisimai/bite/email/imailserver.rb +25 -39
- data/lib/sisimai/bite/email/interscanmss.rb +19 -26
- data/lib/sisimai/bite/email/kddi.rb +20 -33
- data/lib/sisimai/bite/email/mailfoundry.rb +14 -24
- data/lib/sisimai/bite/email/mailmarshalsmtp.rb +15 -24
- data/lib/sisimai/bite/email/mailru.rb +40 -59
- data/lib/sisimai/bite/email/mcafee.rb +21 -35
- data/lib/sisimai/bite/email/messagelabs.rb +23 -38
- data/lib/sisimai/bite/email/messagingserver.rb +15 -27
- data/lib/sisimai/bite/email/mfilter.rb +19 -28
- data/lib/sisimai/bite/email/mxlogic.rb +31 -49
- data/lib/sisimai/bite/email/notes.rb +16 -24
- data/lib/sisimai/bite/email/office365.rb +29 -38
- data/lib/sisimai/bite/email/opensmtpd.rb +50 -67
- data/lib/sisimai/bite/email/outlook.rb +24 -36
- data/lib/sisimai/bite/email/postfix.rb +33 -42
- data/lib/sisimai/bite/email/qmail.rb +44 -59
- data/lib/sisimai/bite/email/receivingses.rb +28 -36
- data/lib/sisimai/bite/email/sendgrid.rb +28 -37
- data/lib/sisimai/bite/email/sendmail.rb +35 -51
- data/lib/sisimai/bite/email/surfcontrol.rb +17 -25
- data/lib/sisimai/bite/email/userdefined.rb +17 -28
- data/lib/sisimai/bite/email/v5sendmail.rb +32 -41
- data/lib/sisimai/bite/email/verizon.rb +31 -56
- data/lib/sisimai/bite/email/x1.rb +11 -18
- data/lib/sisimai/bite/email/x2.rb +11 -23
- data/lib/sisimai/bite/email/x3.rb +10 -19
- data/lib/sisimai/bite/email/x4.rb +46 -65
- data/lib/sisimai/bite/email/x5.rb +26 -37
- data/lib/sisimai/bite/email/yahoo.rb +11 -19
- data/lib/sisimai/bite/email/yandex.rb +19 -30
- data/lib/sisimai/bite/email/zoho.rb +21 -30
- data/lib/sisimai/bite/json.rb +1 -2
- data/lib/sisimai/bite/json/amazonses.rb +20 -25
- data/lib/sisimai/bite/json/sendgrid.rb +1 -1
- data/lib/sisimai/data.rb +36 -55
- data/lib/sisimai/data/json.rb +3 -3
- data/lib/sisimai/data/yaml.rb +1 -1
- data/lib/sisimai/datetime.rb +5 -21
- data/lib/sisimai/mail.rb +4 -6
- data/lib/sisimai/mail/maildir.rb +1 -1
- data/lib/sisimai/mda.rb +41 -44
- data/lib/sisimai/message.rb +2 -3
- data/lib/sisimai/message/email.rb +42 -52
- data/lib/sisimai/message/json.rb +7 -7
- data/lib/sisimai/mime.rb +25 -23
- data/lib/sisimai/order/email.rb +2 -2
- data/lib/sisimai/order/json.rb +2 -7
- data/lib/sisimai/reason.rb +41 -46
- data/lib/sisimai/reason/blocked.rb +60 -71
- data/lib/sisimai/reason/contenterror.rb +4 -8
- data/lib/sisimai/reason/delivered.rb +1 -3
- data/lib/sisimai/reason/exceedlimit.rb +10 -20
- data/lib/sisimai/reason/expired.rb +5 -9
- data/lib/sisimai/reason/feedback.rb +1 -3
- data/lib/sisimai/reason/filtered.rb +19 -38
- data/lib/sisimai/reason/hasmoved.rb +5 -8
- data/lib/sisimai/reason/hostunknown.rb +11 -18
- data/lib/sisimai/reason/mailboxfull.rb +14 -24
- data/lib/sisimai/reason/mailererror.rb +3 -5
- data/lib/sisimai/reason/mesgtoobig.rb +15 -25
- data/lib/sisimai/reason/networkerror.rb +8 -10
- data/lib/sisimai/reason/norelaying.rb +9 -14
- data/lib/sisimai/reason/notaccept.rb +9 -21
- data/lib/sisimai/reason/onhold.rb +3 -8
- data/lib/sisimai/reason/policyviolation.rb +8 -10
- data/lib/sisimai/reason/rejected.rb +36 -49
- data/lib/sisimai/reason/securityerror.rb +11 -13
- data/lib/sisimai/reason/spamdetected.rb +23 -37
- data/lib/sisimai/reason/suspend.rb +9 -10
- data/lib/sisimai/reason/syntaxerror.rb +3 -4
- data/lib/sisimai/reason/systemerror.rb +7 -9
- data/lib/sisimai/reason/systemfull.rb +2 -4
- data/lib/sisimai/reason/toomanyconn.rb +17 -30
- data/lib/sisimai/reason/undefined.rb +1 -3
- data/lib/sisimai/reason/userunknown.rb +28 -38
- data/lib/sisimai/reason/vacation.rb +4 -6
- data/lib/sisimai/reason/virusdetected.rb +4 -6
- data/lib/sisimai/rfc2606.rb +1 -2
- data/lib/sisimai/rfc3464.rb +87 -101
- data/lib/sisimai/rfc3834.rb +29 -39
- data/lib/sisimai/rfc5322.rb +17 -24
- data/lib/sisimai/rhost.rb +10 -7
- data/lib/sisimai/rhost/exchangeonline.rb +124 -255
- data/lib/sisimai/rhost/franceptt.rb +2 -2
- data/lib/sisimai/rhost/godaddy.rb +12 -25
- data/lib/sisimai/rhost/googleapps.rb +82 -183
- data/lib/sisimai/smtp.rb +4 -4
- data/lib/sisimai/smtp/error.rb +8 -8
- data/lib/sisimai/smtp/reply.rb +1 -1
- data/lib/sisimai/smtp/status.rb +1 -0
- data/lib/sisimai/string.rb +5 -7
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/README.md +1 -1
- data/set-of-emails/maildir/bsd/README.md +50 -50
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +4 -4
- data/lib/sisimai/skeleton.rb +0 -43
data/lib/sisimai/bite/email.rb
CHANGED
@@ -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.
|
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
|
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
|
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
|
-
|
56
|
-
|
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.
|
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
|
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
|
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(/\
|
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(/\
|
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(/\
|
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(/\
|
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(/\
|
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(/\
|
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(/\
|
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
|
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
|
-
|
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(/\
|
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']
|
213
|
-
e['diagnosis']
|
214
|
-
e['diagnosis']
|
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']
|
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
|
-
|
212
|
+
ReFailures.each_key do |r|
|
231
213
|
# Verify each regular expression of session errors
|
232
|
-
next unless e['diagnosis'] =~
|
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
|
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.
|
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
|
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
|
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(/\
|
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(/\
|
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(/\
|
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(/\
|
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(/\
|
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
|
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
|
-
|
10
|
-
|
11
|
-
:
|
12
|
-
|
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
|
-
|
19
|
-
hostunknown: %r/Host
|
20
|
-
notaccept: %r/type=MX:
|
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.
|
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
|
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
|
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(/\
|
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(/\
|
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(/\
|
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(/\
|
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(/\
|
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
|
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
|
-
|
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(/\
|
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(/\
|
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
|
-
|
180
|
+
ReFailures.each_key do |r|
|
189
181
|
# Verify each regular expression of session errors
|
190
|
-
next unless e['diagnosis'] =~
|
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']
|
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
|