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
@@ -6,22 +6,21 @@ module Sisimai::Bite::Email
|
|
6
6
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Google.pm
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
:
|
9
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
10
|
+
StartingOf = {
|
11
|
+
message: ['Delivery to the following recipient'],
|
12
|
+
error: ['The error that the other server returned was:'],
|
12
13
|
}.freeze
|
13
|
-
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:error => %r/The error that the other server returned was:/,
|
17
|
-
:rfc822 => %r{\A(?:
|
14
|
+
MarkingsOf = {
|
15
|
+
start: %r/Technical details of (?:permanent|temporary) failure:/,
|
16
|
+
rfc822: %r{\A(?:
|
18
17
|
-----[ ]Original[ ]message[ ]-----
|
19
18
|
|[ \t]*-----[ ]Message[ ]header[ ]follows[ ]-----
|
20
19
|
)\z
|
21
20
|
}x,
|
22
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
23
21
|
}.freeze
|
24
|
-
|
22
|
+
|
23
|
+
ReFailures = {
|
25
24
|
expired: %r{(?:
|
26
25
|
DNS[ ]Error:[ ]Could[ ]not[ ]contact[ ]DNS[ ]servers
|
27
26
|
|Delivery[ ]to[ ]the[ ]following[ ]recipient[ ]has[ ]been[ ]delayed
|
@@ -107,12 +106,10 @@ module Sisimai::Bite::Email
|
|
107
106
|
# 550 550 Unknown user *****@***.**.*** (state 18).
|
108
107
|
'18' => { 'command' => 'DATA', 'reason' => 'filtered' },
|
109
108
|
}.freeze
|
110
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
111
109
|
|
112
110
|
def description; return 'Google Gmail: https://mail.google.com'; end
|
113
111
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
114
112
|
def headerlist; return ['X-Failed-Recipients']; end
|
115
|
-
def pattern; return Re0; end
|
116
113
|
|
117
114
|
# Parse bounce messages from Google Gmail
|
118
115
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -176,8 +173,8 @@ module Sisimai::Bite::Email
|
|
176
173
|
# The error that the other server returned was:
|
177
174
|
# 550 5.1.1 <userunknown@example.jp>... User Unknown
|
178
175
|
#
|
179
|
-
return nil unless mhead['from']
|
180
|
-
return nil unless mhead['subject']
|
176
|
+
return nil unless mhead['from'].include?('<mailer-daemon@googlemail.com>')
|
177
|
+
return nil unless mhead['subject'].include?('Delivery Status Notification')
|
181
178
|
|
182
179
|
require 'sisimai/address'
|
183
180
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
@@ -189,15 +186,15 @@ module Sisimai::Bite::Email
|
|
189
186
|
statecode0 = 0 # (Integer) The value of (state *) in the error message
|
190
187
|
v = nil
|
191
188
|
|
192
|
-
hasdivided.
|
189
|
+
while e = hasdivided.shift do
|
193
190
|
if readcursor.zero?
|
194
191
|
# Beginning of the bounce message or delivery status part
|
195
|
-
readcursor |= Indicators[:deliverystatus] if e
|
192
|
+
readcursor |= Indicators[:deliverystatus] if e.include?(StartingOf[:message][0])
|
196
193
|
end
|
197
194
|
|
198
195
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
199
196
|
# Beginning of the original message part
|
200
|
-
if e =~
|
197
|
+
if e =~ MarkingsOf[:rfc822]
|
201
198
|
readcursor |= Indicators[:'message-rfc822']
|
202
199
|
next
|
203
200
|
end
|
@@ -211,7 +208,6 @@ module Sisimai::Bite::Email
|
|
211
208
|
next
|
212
209
|
end
|
213
210
|
rfc822list << e
|
214
|
-
|
215
211
|
else
|
216
212
|
# Before "message/rfc822"
|
217
213
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -247,18 +243,16 @@ module Sisimai::Bite::Email
|
|
247
243
|
v['recipient'] = addr0
|
248
244
|
recipients += 1
|
249
245
|
end
|
250
|
-
|
251
246
|
else
|
252
247
|
v['diagnosis'] ||= ''
|
253
|
-
v['diagnosis']
|
248
|
+
v['diagnosis'] << e + ' '
|
254
249
|
end
|
255
250
|
end
|
256
251
|
end
|
257
|
-
|
258
252
|
return nil if recipients.zero?
|
253
|
+
|
259
254
|
require 'sisimai/string'
|
260
255
|
require 'sisimai/smtp/status'
|
261
|
-
|
262
256
|
dscontents.map do |e|
|
263
257
|
e['agent'] = self.smtpagent
|
264
258
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
@@ -287,12 +281,11 @@ module Sisimai::Bite::Email
|
|
287
281
|
# (state *)
|
288
282
|
e['reason'] = StateTable[statecode0]['reason']
|
289
283
|
e['command'] = StateTable[statecode0]['command']
|
290
|
-
|
291
284
|
else
|
292
285
|
# No state code
|
293
|
-
|
286
|
+
ReFailures.each_key do |r|
|
294
287
|
# Verify each regular expression of session errors
|
295
|
-
next unless e['diagnosis'] =~
|
288
|
+
next unless e['diagnosis'] =~ ReFailures[r]
|
296
289
|
e['reason'] = r.to_s
|
297
290
|
break
|
298
291
|
end
|
@@ -301,10 +294,7 @@ module Sisimai::Bite::Email
|
|
301
294
|
|
302
295
|
# Set pseudo status code
|
303
296
|
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
304
|
-
if e['status'] =~ /\A[45][.][1-7][.][1-9]\z/
|
305
|
-
# Override bounce reason
|
306
|
-
e['reason'] = Sisimai::SMTP::Status.name(e['status'])
|
307
|
-
end
|
297
|
+
e['reason'] = Sisimai::SMTP::Status.name(e['status']) if e['status'] =~ /\A[45][.][1-7][.][1-9]\z/
|
308
298
|
end
|
309
299
|
|
310
300
|
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
@@ -6,28 +6,22 @@ module Sisimai::Bite::Email
|
|
6
6
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/GSuite.pm
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
:
|
12
|
-
|
13
|
-
|
14
|
-
:
|
15
|
-
:error => %r/\AThe[ ]response([ ]from[ ]the[ ]remote[ ]server)?[ ]was:\z/,
|
16
|
-
:html => %r{\AContent-Type:[ ]*text/html;[ ]*charset=['"]?(?:UTF|utf)[-]8['"]?\z},
|
17
|
-
:rfc822 => %r{\AContent-Type:[ ]*(?:message/rfc822|text/rfc822-headers)\z},
|
18
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
9
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
10
|
+
MarkingsOf = {
|
11
|
+
message: %r/\A[*][*][ ].+[ ][*][*]\z/,
|
12
|
+
rfc822: %r{\AContent-Type:[ ]*(?:message/rfc822|text/rfc822-headers)\z},
|
13
|
+
error: %r/\AThe[ ]response([ ]from[ ]the[ ]remote[ ]server)?[ ]was:\z/,
|
14
|
+
html: %r{\AContent-Type:[ ]*text/html;[ ]*charset=['"]?(?:UTF|utf)[-]8['"]?\z},
|
19
15
|
}.freeze
|
20
16
|
ErrorMayBe = {
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
17
|
+
userunknown: %r/because the address couldn't be found/,
|
18
|
+
notaccept: %r/Null MX/,
|
19
|
+
networkerror: %r/DNS type .+ lookup of .+ responded with code NXDOMAIN/,
|
24
20
|
}.freeze
|
25
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
26
21
|
|
27
22
|
def description; return 'G Suite: https://gsuite.google.com'; end
|
28
23
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
29
24
|
def headerlist; return ['X-Gm-Message-State']; end
|
30
|
-
def pattern; return Re0; end
|
31
25
|
|
32
26
|
# Parse bounce messages from G Suite (Transfer from G Suite to a destinaion host)
|
33
27
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -44,8 +38,8 @@ module Sisimai::Bite::Email
|
|
44
38
|
return nil unless mhead
|
45
39
|
return nil unless mbody
|
46
40
|
|
47
|
-
return nil unless mhead['from']
|
48
|
-
return nil unless mhead['subject']
|
41
|
+
return nil unless mhead['from'].include?('<mailer-daemon@googlemail.com>')
|
42
|
+
return nil unless mhead['subject'].include?('Delivery Status Notification')
|
49
43
|
return nil unless mhead['x-gm-message-state']
|
50
44
|
|
51
45
|
require 'sisimai/address'
|
@@ -55,7 +49,7 @@ module Sisimai::Bite::Email
|
|
55
49
|
blanklines = 0 # (Integer) The number of blank lines
|
56
50
|
readcursor = 0 # (Integer) Points the current cursor position
|
57
51
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
58
|
-
endoferror =
|
52
|
+
endoferror = false # (Integer) Flag for a blank line after error messages
|
59
53
|
anotherset = {} # (Hash) Another error information
|
60
54
|
emptylines = 0 # (Integer) The number of empty lines
|
61
55
|
connvalues = 0 # (Integer) Flag, 1 if all the value of connheader have been set
|
@@ -65,15 +59,15 @@ module Sisimai::Bite::Email
|
|
65
59
|
}
|
66
60
|
v = nil
|
67
61
|
|
68
|
-
hasdivided.
|
62
|
+
while e = hasdivided.shift do
|
69
63
|
if readcursor.zero?
|
70
64
|
# Beginning of the bounce message or delivery status part
|
71
|
-
readcursor |= Indicators[:deliverystatus] if e =~
|
65
|
+
readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
|
72
66
|
end
|
73
67
|
|
74
68
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
75
69
|
# Beginning of the original message part
|
76
|
-
if e =~
|
70
|
+
if e =~ MarkingsOf[:rfc822]
|
77
71
|
readcursor |= Indicators[:'message-rfc822']
|
78
72
|
next
|
79
73
|
end
|
@@ -87,7 +81,6 @@ module Sisimai::Bite::Email
|
|
87
81
|
next
|
88
82
|
end
|
89
83
|
rfc822list << e
|
90
|
-
|
91
84
|
else
|
92
85
|
# Before "message/rfc822"
|
93
86
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -101,7 +94,7 @@ module Sisimai::Bite::Email
|
|
101
94
|
# Last-Attempt-Date: Fri, 24 Mar 2017 23:34:10 -0700 (PDT)
|
102
95
|
v = dscontents[-1]
|
103
96
|
|
104
|
-
if cv = e.match(/\
|
97
|
+
if cv = e.match(/\AFinal-Recipient:[ ]*(?:RFC|rfc)822;[ ]*(.+)\z/)
|
105
98
|
# Final-Recipient: rfc822; kijitora@example.de
|
106
99
|
if v['recipient']
|
107
100
|
# There are multiple recipient addresses in the message body.
|
@@ -111,63 +104,60 @@ module Sisimai::Bite::Email
|
|
111
104
|
v['recipient'] = cv[1]
|
112
105
|
recipients += 1
|
113
106
|
|
114
|
-
elsif cv = e.match(/\
|
107
|
+
elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
|
115
108
|
# Action: failed
|
116
109
|
v['action'] = cv[1].downcase
|
117
110
|
|
118
|
-
elsif cv = e.match(/\
|
111
|
+
elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
|
119
112
|
# Status: 5.0.0
|
120
113
|
v['status'] = cv[1]
|
121
114
|
|
122
|
-
elsif cv = e.match(/\
|
115
|
+
elsif cv = e.match(/\ARemote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
123
116
|
# Remote-MTA: dns; 192.0.2.222 (192.0.2.222, the server for the domain.)
|
124
117
|
v['rhost'] = cv[1].downcase
|
125
118
|
v['rhost'] = '' if v['rhost'] =~ /\A\s+\z/ # Remote-MTA: DNS;
|
126
119
|
|
127
|
-
elsif cv = e.match(/\
|
120
|
+
elsif cv = e.match(/\ALast-Attempt-Date:[ ]*(.+)\z/)
|
128
121
|
# Last-Attempt-Date: Fri, 24 Mar 2017 23:34:10 -0700 (PDT)
|
129
122
|
v['date'] = cv[1]
|
130
|
-
|
131
123
|
else
|
132
|
-
if cv = e.match(/\
|
124
|
+
if cv = e.match(/\ADiagnostic-Code:[ ]*(.+?);[ ]*(.+)\z/)
|
133
125
|
# Diagnostic-Code: smtp; 550 #5.1.0 Address rejected.
|
134
126
|
v['spec'] = cv[1].upcase
|
135
127
|
v['diagnosis'] = cv[2]
|
136
128
|
else
|
137
129
|
# Append error messages continued from the previous line
|
138
|
-
if endoferror
|
139
|
-
endoferror
|
140
|
-
endoferror
|
130
|
+
if endoferror == false && v['diagnosis'].to_s.size > 0
|
131
|
+
endoferror ||= true if e.empty?
|
132
|
+
endoferror ||= true if e.start_with?('--')
|
141
133
|
|
142
134
|
next if endoferror
|
143
|
-
next unless e
|
144
|
-
v['diagnosis']
|
135
|
+
next unless e.start_with?(' ')
|
136
|
+
v['diagnosis'] << e
|
145
137
|
end
|
146
138
|
end
|
147
139
|
end
|
148
|
-
|
149
140
|
else
|
150
141
|
# Reporting-MTA: dns; googlemail.com
|
151
142
|
# Received-From-MTA: dns; sironeko@example.jp
|
152
143
|
# Arrival-Date: Fri, 24 Mar 2017 23:34:07 -0700 (PDT)
|
153
144
|
# X-Original-Message-ID: <06C1ED5C-7E02-4036-AEE1-AA448067FB2C@example.jp>
|
154
|
-
if cv = e.match(/\
|
145
|
+
if cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
155
146
|
# Reporting-MTA: dns; mx.example.jp
|
156
147
|
next if connheader['lhost'].size > 0
|
157
148
|
connheader['lhost'] = cv[1].downcase
|
158
149
|
connvalues += 1
|
159
150
|
|
160
|
-
elsif cv = e.match(/\
|
151
|
+
elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
|
161
152
|
# Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
|
162
153
|
next if connheader['date'].size > 0
|
163
154
|
connheader['date'] = cv[1]
|
164
155
|
connvalues += 1
|
165
|
-
|
166
156
|
else
|
167
157
|
# Detect SMTP session error or connection error
|
168
|
-
if e =~
|
158
|
+
if e =~ MarkingsOf[:error]
|
169
159
|
# The response from the remote server was:
|
170
|
-
anotherset['diagnosis']
|
160
|
+
anotherset['diagnosis'] << e
|
171
161
|
else
|
172
162
|
# ** Address not found **
|
173
163
|
#
|
@@ -176,7 +166,7 @@ module Sisimai::Bite::Email
|
|
176
166
|
#
|
177
167
|
# The response from the remote server was:
|
178
168
|
# 550 #5.1.0 Address rejected.
|
179
|
-
next if e =~
|
169
|
+
next if e =~ MarkingsOf[:html]
|
180
170
|
|
181
171
|
if anotherset['diagnosis']
|
182
172
|
# Continued error messages from the previous line like
|
@@ -187,14 +177,14 @@ module Sisimai::Bite::Email
|
|
187
177
|
emptylines += 1
|
188
178
|
next
|
189
179
|
end
|
190
|
-
anotherset['diagnosis']
|
180
|
+
anotherset['diagnosis'] << ' ' << e
|
191
181
|
else
|
192
182
|
# ** Address not found **
|
193
183
|
#
|
194
184
|
# Your message wasn't delivered to * because the address couldn't be found.
|
195
185
|
# Check for typos or unnecessary spaces and try again.
|
196
186
|
next if e.empty?
|
197
|
-
next unless e =~
|
187
|
+
next unless e =~ MarkingsOf[:message]
|
198
188
|
anotherset['diagnosis'] = e
|
199
189
|
end
|
200
190
|
end
|
@@ -203,12 +193,11 @@ module Sisimai::Bite::Email
|
|
203
193
|
end
|
204
194
|
end
|
205
195
|
end
|
206
|
-
|
207
196
|
return nil if recipients.zero?
|
197
|
+
|
208
198
|
require 'sisimai/string'
|
209
199
|
require 'sisimai/smtp/reply'
|
210
200
|
require 'sisimai/smtp/status'
|
211
|
-
|
212
201
|
dscontents.map do |e|
|
213
202
|
# Set default values if each value is empty.
|
214
203
|
connheader.each_key { |a| e[a] ||= connheader[a] || '' }
|
@@ -224,7 +213,10 @@ module Sisimai::Bite::Email
|
|
224
213
|
as = nil # status
|
225
214
|
ar = nil # replycode
|
226
215
|
|
227
|
-
|
216
|
+
e['status'] ||= ''
|
217
|
+
e['replycode'] ||= ''
|
218
|
+
|
219
|
+
if e['status'] == '' || e['status'].start_with?('4.0.0', '5.0.0')
|
228
220
|
# Check the value of D.S.N. in anotherset
|
229
221
|
as = Sisimai::SMTP::Status.find(anotherset['diagnosis'])
|
230
222
|
if as.size > 0 && as[-3, 3] != '0.0'
|
@@ -233,7 +225,7 @@ module Sisimai::Bite::Email
|
|
233
225
|
end
|
234
226
|
end
|
235
227
|
|
236
|
-
if e['replycode']
|
228
|
+
if e['replycode'].empty? || e['replycode'].start_with?('400', '500')
|
237
229
|
# Check the value of SMTP reply code in anotherset
|
238
230
|
ar = Sisimai::SMTP::Reply.find(anotherset['diagnosis'])
|
239
231
|
if ar.size > 0 && ar[-2, 2].to_i != 0
|
@@ -258,7 +250,6 @@ module Sisimai::Bite::Email
|
|
258
250
|
e['reason'] = q.to_s
|
259
251
|
break
|
260
252
|
end
|
261
|
-
|
262
253
|
end
|
263
254
|
|
264
255
|
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
@@ -7,41 +7,32 @@ module Sisimai::Bite::Email
|
|
7
7
|
# Imported from p5-Sisimail/lib/Sisimai/Bite::Email/IMailServer.pm
|
8
8
|
require 'sisimai/bite/email'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
:'
|
13
|
-
|
14
|
-
|
15
|
-
:begin => %r/\A\z/, # Blank line
|
16
|
-
:error => %r/Body of message generated response:/,
|
17
|
-
:rfc822 => %r/\AOriginal message follows[.]\z/,
|
18
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
10
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
11
|
+
StartingOf = {
|
12
|
+
message: [''], # Blank line
|
13
|
+
rfc822: ['Original message follows.'],
|
14
|
+
error: ['Body of message generated response:'],
|
19
15
|
}.freeze
|
16
|
+
|
20
17
|
ReSMTP = {
|
21
|
-
conn: %r
|
22
|
-
SMTP[ ]connection[ ]failed,
|
23
|
-
|Unexpected[ ]connection[ ]response[ ]from[ ]server:
|
24
|
-
)
|
25
|
-
},
|
18
|
+
conn: %r/(?:SMTP connection failed,|Unexpected connection response from server:)/,
|
26
19
|
ehlo: %r|Unexpected response to EHLO/HELO:|,
|
27
20
|
mail: %r|Server response to MAIL FROM:|,
|
28
21
|
rcpt: %r|Additional RCPT TO generated following response:|,
|
29
22
|
data: %r|DATA command generated response:|,
|
30
23
|
}.freeze
|
31
|
-
|
32
|
-
hostunknown: %r/Unknown
|
33
|
-
userunknown: %r/\A(?:Unknown
|
34
|
-
mailboxfull: %r/\AUser
|
35
|
-
securityerr: %r/\ARequested
|
36
|
-
undefined: %r/\Aundeliverable
|
37
|
-
expired: %r/\ADelivery
|
24
|
+
ReFailures = {
|
25
|
+
hostunknown: %r/Unknown host/,
|
26
|
+
userunknown: %r/\A(?:Unknown user|Invalid final delivery userid)/,
|
27
|
+
mailboxfull: %r/\AUser mailbox exceeds allowed size/,
|
28
|
+
securityerr: %r/\ARequested action not taken: virus detected/,
|
29
|
+
undefined: %r/\Aundeliverable to /,
|
30
|
+
expired: %r/\ADelivery failed \d+ attempts/,
|
38
31
|
}.freeze
|
39
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
40
32
|
|
41
33
|
def description; return 'IPSWITCH IMail Server'; end
|
42
34
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
43
35
|
def headerlist; return ['X-Mailer']; end
|
44
|
-
def pattern; return Re0; end
|
45
36
|
|
46
37
|
# Parse bounce messages from IMailServer
|
47
38
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -59,8 +50,8 @@ module Sisimai::Bite::Email
|
|
59
50
|
return nil unless mbody
|
60
51
|
|
61
52
|
match = 0
|
62
|
-
match += 1 if mhead['subject'] =~
|
63
|
-
match += 1 if mhead['x-mailer']
|
53
|
+
match += 1 if mhead['subject'] =~ /\AUndeliverable Mail[ ]*\z/
|
54
|
+
match += 1 if mhead['x-mailer'].to_s.start_with?('<SMTP32 v')
|
64
55
|
return nil if match.zero?
|
65
56
|
|
66
57
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
@@ -71,10 +62,10 @@ module Sisimai::Bite::Email
|
|
71
62
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
72
63
|
v = nil
|
73
64
|
|
74
|
-
hasdivided.
|
65
|
+
while e = hasdivided.shift do
|
75
66
|
if readcursor.zero?
|
76
67
|
# Beginning of the bounce message or delivery status part
|
77
|
-
if e
|
68
|
+
if e == StartingOf[:message][0]
|
78
69
|
readcursor |= Indicators[:deliverystatus]
|
79
70
|
next
|
80
71
|
end
|
@@ -82,7 +73,7 @@ module Sisimai::Bite::Email
|
|
82
73
|
|
83
74
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
84
75
|
# Beginning of the original message part
|
85
|
-
if e
|
76
|
+
if e == StartingOf[:rfc822][0]
|
86
77
|
readcursor |= Indicators[:'message-rfc822']
|
87
78
|
next
|
88
79
|
end
|
@@ -96,7 +87,6 @@ module Sisimai::Bite::Email
|
|
96
87
|
next
|
97
88
|
end
|
98
89
|
rfc822list << e
|
99
|
-
|
100
90
|
else
|
101
91
|
# Before "message/rfc822"
|
102
92
|
break if readcursor & Indicators[:'message-rfc822'] > 0
|
@@ -126,24 +116,20 @@ module Sisimai::Bite::Email
|
|
126
116
|
end
|
127
117
|
v['recipient'] = cv[1]
|
128
118
|
recipients += 1
|
129
|
-
|
130
119
|
else
|
131
120
|
# Other error message text
|
132
|
-
v['alterrors']
|
133
|
-
|
134
|
-
# Body of message generated response:
|
135
|
-
v['alterrors'] = e
|
136
|
-
end
|
121
|
+
v['alterrors'] << ' ' << e if v['alterrors']
|
122
|
+
v['alterrors'] = e if e.include?(StartingOf[:error][0])
|
137
123
|
end
|
138
124
|
end
|
139
125
|
end
|
140
126
|
return nil if recipients.zero?
|
141
|
-
require 'sisimai/string'
|
142
127
|
|
128
|
+
require 'sisimai/string'
|
143
129
|
dscontents.map do |e|
|
144
130
|
e['agent'] = self.smtpagent
|
145
131
|
|
146
|
-
if e['alterrors']
|
132
|
+
if e['alterrors'].to_s.size > 0
|
147
133
|
# Copy alternative error message
|
148
134
|
e['diagnosis'] = if e['diagnosis']
|
149
135
|
e['alterrors'] + ' ' + e['diagnosis']
|
@@ -162,9 +148,9 @@ module Sisimai::Bite::Email
|
|
162
148
|
break
|
163
149
|
end
|
164
150
|
|
165
|
-
|
151
|
+
ReFailures.each_key do |r|
|
166
152
|
# Verify each regular expression of session errors
|
167
|
-
next unless e['diagnosis'] =~
|
153
|
+
next unless e['diagnosis'] =~ ReFailures[r]
|
168
154
|
e['reason'] = r.to_s
|
169
155
|
break
|
170
156
|
end
|