sisimai 4.25.17-java → 5.0.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +3 -3
- data/ANALYTICAL-PRECISION +2 -2
- data/Benchmarks.mk +3 -3
- data/CONTRIBUTING +1 -1
- data/ChangeLog.md +406 -407
- data/Developers.mk +5 -6
- data/Gemfile +1 -1
- data/Makefile +12 -12
- data/README-JA.md +142 -94
- data/README.md +282 -150
- data/Rakefile +9 -3
- data/Repository.mk +2 -3
- data/lib/sisimai/address.rb +118 -74
- data/lib/sisimai/arf.rb +84 -82
- data/lib/sisimai/datetime.rb +5 -52
- data/lib/sisimai/{data → fact}/json.rb +7 -9
- data/lib/sisimai/fact/yaml.rb +31 -0
- data/lib/sisimai/fact.rb +468 -0
- data/lib/sisimai/lhost/activehunter.rb +12 -14
- data/lib/sisimai/lhost/amavis.rb +11 -14
- data/lib/sisimai/lhost/amazonses.rb +37 -41
- data/lib/sisimai/lhost/amazonworkmail.rb +15 -18
- data/lib/sisimai/lhost/aol.rb +12 -14
- data/lib/sisimai/lhost/apachejames.rb +19 -21
- data/lib/sisimai/lhost/barracuda.rb +10 -12
- data/lib/sisimai/lhost/bigfoot.rb +21 -21
- data/lib/sisimai/lhost/biglobe.rb +15 -16
- data/lib/sisimai/lhost/courier.rb +20 -20
- data/lib/sisimai/lhost/domino.rb +23 -19
- data/lib/sisimai/lhost/einsundeins.rb +20 -16
- data/lib/sisimai/lhost/exchange2003.rb +30 -29
- data/lib/sisimai/lhost/exchange2007.rb +70 -58
- data/lib/sisimai/lhost/exim.rb +175 -161
- data/lib/sisimai/lhost/ezweb.rb +31 -56
- data/lib/sisimai/lhost/facebook.rb +21 -33
- data/lib/sisimai/lhost/fml.rb +43 -48
- data/lib/sisimai/lhost/gmail.rb +29 -29
- data/lib/sisimai/lhost/gmx.rb +18 -17
- data/lib/sisimai/lhost/googlegroups.rb +9 -10
- data/lib/sisimai/lhost/gsuite.rb +21 -27
- data/lib/sisimai/lhost/imailserver.rb +25 -39
- data/lib/sisimai/lhost/interscanmss.rb +28 -31
- data/lib/sisimai/lhost/kddi.rb +22 -28
- data/lib/sisimai/lhost/mailfoundry.rb +11 -12
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
- data/lib/sisimai/lhost/mailru.rb +33 -27
- data/lib/sisimai/lhost/mcafee.rb +21 -31
- data/lib/sisimai/lhost/messagelabs.rb +17 -20
- data/lib/sisimai/lhost/messagingserver.rb +40 -37
- data/lib/sisimai/lhost/mfilter.rb +15 -16
- data/lib/sisimai/lhost/mxlogic.rb +24 -23
- data/lib/sisimai/lhost/notes.rb +17 -17
- data/lib/sisimai/lhost/office365.rb +63 -27
- data/lib/sisimai/lhost/opensmtpd.rb +12 -13
- data/lib/sisimai/lhost/outlook.rb +12 -15
- data/lib/sisimai/lhost/postfix.rb +179 -129
- data/lib/sisimai/lhost/powermta.rb +12 -14
- data/lib/sisimai/lhost/qmail.rb +44 -47
- data/lib/sisimai/lhost/receivingses.rb +15 -20
- data/lib/sisimai/lhost/sendgrid.rb +34 -32
- data/lib/sisimai/lhost/sendmail.rb +66 -53
- data/lib/sisimai/lhost/surfcontrol.rb +19 -19
- data/lib/sisimai/lhost/v5sendmail.rb +45 -39
- data/lib/sisimai/lhost/verizon.rb +35 -39
- data/lib/sisimai/lhost/x1.rb +18 -17
- data/lib/sisimai/lhost/x2.rb +17 -14
- data/lib/sisimai/lhost/x3.rb +19 -19
- data/lib/sisimai/lhost/x4.rb +72 -57
- data/lib/sisimai/lhost/x5.rb +17 -19
- data/lib/sisimai/lhost/x6.rb +41 -17
- data/lib/sisimai/lhost/yahoo.rb +17 -16
- data/lib/sisimai/lhost/yandex.rb +16 -20
- data/lib/sisimai/lhost/zoho.rb +16 -15
- data/lib/sisimai/lhost.rb +8 -10
- data/lib/sisimai/mail/maildir.rb +1 -3
- data/lib/sisimai/mail/mbox.rb +3 -4
- data/lib/sisimai/mail/memory.rb +0 -1
- data/lib/sisimai/mail/stdin.rb +1 -3
- data/lib/sisimai/mail.rb +3 -7
- data/lib/sisimai/mda.rb +28 -42
- data/lib/sisimai/message.rb +435 -325
- data/lib/sisimai/order.rb +5 -5
- data/lib/sisimai/reason/authfailure.rb +64 -0
- data/lib/sisimai/reason/badreputation.rb +53 -0
- data/lib/sisimai/reason/blocked.rb +94 -160
- data/lib/sisimai/reason/contenterror.rb +8 -9
- data/lib/sisimai/reason/delivered.rb +4 -6
- data/lib/sisimai/reason/exceedlimit.rb +10 -12
- data/lib/sisimai/reason/expired.rb +6 -8
- data/lib/sisimai/reason/feedback.rb +2 -3
- data/lib/sisimai/reason/filtered.rb +17 -19
- data/lib/sisimai/reason/hasmoved.rb +9 -10
- data/lib/sisimai/reason/hostunknown.rb +15 -15
- data/lib/sisimai/reason/mailboxfull.rb +10 -12
- data/lib/sisimai/reason/mailererror.rb +18 -20
- data/lib/sisimai/reason/mesgtoobig.rb +9 -11
- data/lib/sisimai/reason/networkerror.rb +5 -8
- data/lib/sisimai/reason/norelaying.rb +8 -11
- data/lib/sisimai/reason/notaccept.rb +13 -14
- data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
- data/lib/sisimai/reason/onhold.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +14 -12
- data/lib/sisimai/reason/rejected.rb +26 -24
- data/lib/sisimai/reason/requireptr.rb +69 -0
- data/lib/sisimai/reason/securityerror.rb +33 -36
- data/lib/sisimai/reason/spamdetected.rb +114 -147
- data/lib/sisimai/reason/speeding.rb +49 -0
- data/lib/sisimai/reason/suspend.rb +11 -11
- data/lib/sisimai/reason/syntaxerror.rb +11 -10
- data/lib/sisimai/reason/systemerror.rb +7 -9
- data/lib/sisimai/reason/systemfull.rb +7 -8
- data/lib/sisimai/reason/toomanyconn.rb +9 -11
- data/lib/sisimai/reason/undefined.rb +2 -3
- data/lib/sisimai/reason/userunknown.rb +129 -146
- data/lib/sisimai/reason/vacation.rb +3 -4
- data/lib/sisimai/reason/virusdetected.rb +10 -11
- data/lib/sisimai/reason.rb +59 -64
- data/lib/sisimai/rfc1894.rb +55 -28
- data/lib/sisimai/rfc2045.rb +373 -0
- data/lib/sisimai/rfc3464.rb +250 -308
- data/lib/sisimai/rfc3834.rb +42 -45
- data/lib/sisimai/rfc5322.rb +75 -100
- data/lib/sisimai/rfc5965.rb +31 -0
- data/lib/sisimai/rhost/cox.rb +5 -6
- data/lib/sisimai/rhost/franceptt.rb +6 -8
- data/lib/sisimai/rhost/godaddy.rb +12 -12
- data/lib/sisimai/rhost/{googleapps.rb → google.rb} +80 -72
- data/lib/sisimai/rhost/iua.rb +9 -10
- data/lib/sisimai/rhost/kddi.rb +6 -8
- data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
- data/lib/sisimai/rhost/mimecast.rb +42 -40
- data/lib/sisimai/rhost/nttdocomo.rb +13 -18
- data/lib/sisimai/rhost/spectrum.rb +10 -12
- data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
- data/lib/sisimai/rhost.rb +23 -31
- data/lib/sisimai/smtp/command.rb +59 -0
- data/lib/sisimai/smtp/error.rb +4 -7
- data/lib/sisimai/smtp/reply.rb +161 -74
- data/lib/sisimai/smtp/status.rb +504 -393
- data/lib/sisimai/smtp/transcript.rb +124 -0
- data/lib/sisimai/smtp.rb +0 -1
- data/lib/sisimai/string.rb +74 -5
- data/lib/sisimai/time.rb +1 -2
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +35 -21
- data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
- data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
- data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
- data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
- data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
- data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
- data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
- data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
- data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +42 -23
- data/.rspec +0 -2
- data/lib/sisimai/data/yaml.rb +0 -33
- data/lib/sisimai/data.rb +0 -411
- data/lib/sisimai/mime.rb +0 -456
- data/set-of-emails/maildir/mac/reported-from-nick4tech-san-01.eml +0 -6
- /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
@@ -1,11 +1,10 @@
|
|
1
1
|
module Sisimai
|
2
2
|
module Reason
|
3
|
-
# Sisimai::Reason::VirusDetected checks the bounce reason is "virusdetected"
|
4
|
-
#
|
3
|
+
# Sisimai::Reason::VirusDetected checks the bounce reason is "virusdetected" or not. This class
|
4
|
+
# is called only Sisimai::Reason class.
|
5
5
|
#
|
6
|
-
# This is an error that any virus or trojan horse detected in the message by
|
7
|
-
#
|
8
|
-
# divided from "securityerror" at Sisimai 4.22.0.
|
6
|
+
# This is an error that any virus or trojan horse detected in the message by a virus scanner program
|
7
|
+
# at a destination mail server. This reason has been divided from "securityerror" at Sisimai 4.22.0.
|
9
8
|
#
|
10
9
|
# Your message was infected with a virus. You should download a virus
|
11
10
|
# scanner and check your computer for viruses.
|
@@ -14,15 +13,15 @@ module Sisimai
|
|
14
13
|
# Recipient: <kijitora@example.jp>
|
15
14
|
#
|
16
15
|
module VirusDetected
|
17
|
-
# Imported from p5-Sisimail/lib/Sisimai/Reason/VirusDetected.pm
|
18
16
|
class << self
|
19
17
|
Index = [
|
20
18
|
'it has a potentially executable attachment',
|
21
19
|
'the message was rejected because it contains prohibited virus or spam content',
|
22
20
|
'this form of attachment has been used by recent viruses or other malware',
|
23
21
|
'virus detected',
|
22
|
+
'virus phishing/malicious_url detected',
|
24
23
|
'your message was infected with a virus',
|
25
|
-
]
|
24
|
+
].freeze
|
26
25
|
|
27
26
|
def text; return 'virusdetected'; end
|
28
27
|
def description; return 'Email rejected due to a virus scanner on a destination host'; end
|
@@ -39,7 +38,7 @@ module Sisimai
|
|
39
38
|
end
|
40
39
|
|
41
40
|
# The bounce reason is "virusdetected" or not
|
42
|
-
# @param [Sisimai::
|
41
|
+
# @param [Sisimai::Fact] argvs Object to be detected the reason
|
43
42
|
# @return [True,False] true: virus detected
|
44
43
|
# false: virus was not detected
|
45
44
|
# @since 4.22.0
|
@@ -48,9 +47,9 @@ module Sisimai
|
|
48
47
|
# The value of "reason" isn't "visusdetected" when the value of "smtpcommand" is an SMTP
|
49
48
|
# command to be sent before the SMTP DATA command because all the MTAs read the headers
|
50
49
|
# and the entire message body after the DATA command.
|
51
|
-
return true if argvs
|
52
|
-
return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs
|
53
|
-
return true if match(argvs
|
50
|
+
return true if argvs['reason'] == 'virusdetected'
|
51
|
+
return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs['smtpcommand'])
|
52
|
+
return true if match(argvs['diagnosticcode'].downcase)
|
54
53
|
return false
|
55
54
|
end
|
56
55
|
|
data/lib/sisimai/reason.rb
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
module Sisimai
|
2
|
-
# Sisimai::Reason detects the bounce reason from the
|
3
|
-
# object as an argument of get() method. This class is called only Sisimai::
|
4
|
-
# class.
|
2
|
+
# Sisimai::Reason detects the bounce reason from the Hash table which is to be constructed to
|
3
|
+
# Sisimai::Fact object as an argument of get() method. This class is called only Sisimai::Fact class.
|
5
4
|
module Reason
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Reason.pm
|
7
5
|
class << self
|
8
6
|
# All the error reason list Sisimai support
|
9
7
|
# @return [Array] Reason list
|
10
8
|
def index
|
11
9
|
return %w[
|
12
|
-
Blocked ContentError ExceedLimit Expired Filtered HasMoved
|
13
|
-
MailboxFull MailerError MesgTooBig NetworkError NotAccept
|
14
|
-
Rejected NoRelaying SpamDetected VirusDetected PolicyViolation
|
15
|
-
Suspend SystemError SystemFull TooManyConn UserUnknown SyntaxError
|
10
|
+
AuthFailure BadReputation Blocked ContentError ExceedLimit Expired Filtered HasMoved
|
11
|
+
HostUnknown MailboxFull MailerError MesgTooBig NetworkError NotAccept NotCompliantRFC
|
12
|
+
OnHold Rejected NoRelaying Speeding SpamDetected VirusDetected PolicyViolation
|
13
|
+
SecurityError Suspend RequirePTR SystemError SystemFull TooManyConn UserUnknown SyntaxError
|
16
14
|
]
|
17
15
|
end
|
18
16
|
|
@@ -27,55 +25,57 @@ module Sisimai
|
|
27
25
|
end
|
28
26
|
|
29
27
|
# Reason list better to retry detecting an error reason
|
30
|
-
# @return [
|
28
|
+
# @return [Hash] Reason list
|
31
29
|
def retry
|
32
30
|
return {
|
33
|
-
'undefined' =>
|
34
|
-
'
|
31
|
+
'undefined' => true, 'onhold' => true, 'systemerror' => true, 'securityerror' => true,
|
32
|
+
'expired' => true, 'suspend' => true, 'networkerror' => true, 'hostunknown' => true,
|
33
|
+
'userunknown' => true
|
35
34
|
}.freeze
|
36
35
|
end
|
37
36
|
ModulePath = Sisimai::Reason.path
|
38
37
|
GetRetried = Sisimai::Reason.retry
|
39
38
|
ClassOrder = [
|
40
39
|
%w[
|
41
|
-
MailboxFull MesgTooBig ExceedLimit Suspend HasMoved NoRelaying UserUnknown
|
42
|
-
Filtered Rejected HostUnknown SpamDetected TooManyConn
|
40
|
+
MailboxFull MesgTooBig ExceedLimit Suspend HasMoved NoRelaying AuthFailure UserUnknown
|
41
|
+
Filtered RequirePTR NotCompliantRFC Rejected HostUnknown SpamDetected Speeding TooManyConn
|
42
|
+
Blocked
|
43
43
|
],
|
44
44
|
%w[
|
45
|
-
MailboxFull SpamDetected PolicyViolation VirusDetected NoRelaying
|
46
|
-
SecurityError SystemError NetworkError Suspend Expired ContentError
|
45
|
+
MailboxFull SpamDetected PolicyViolation VirusDetected NoRelaying AuthFailure
|
46
|
+
BadReputation SecurityError SystemError NetworkError Speeding Suspend Expired ContentError
|
47
47
|
SystemFull NotAccept MailerError
|
48
48
|
],
|
49
49
|
%w[
|
50
|
-
MailboxFull MesgTooBig ExceedLimit Suspend UserUnknown Filtered Rejected
|
51
|
-
|
52
|
-
SystemError NetworkError Suspend Expired ContentError HasMoved SystemFull
|
53
|
-
|
50
|
+
MailboxFull MesgTooBig ExceedLimit Suspend UserUnknown Filtered Rejected HostUnknown
|
51
|
+
SpamDetected Speeding TooManyConn Blocked SpamDetected AuthFailure SecurityError
|
52
|
+
SystemError NetworkError Suspend Expired ContentError HasMoved SystemFull NotAccept
|
53
|
+
MailerError NoRelaying SyntaxError OnHold
|
54
54
|
]
|
55
55
|
]
|
56
56
|
|
57
57
|
# Detect the bounce reason
|
58
|
-
# @param [
|
59
|
-
# @return [String,
|
60
|
-
# is missing or invalid object
|
58
|
+
# @param [Hash] argvs Parsed email object
|
59
|
+
# @return [String, nil] Bounce reason or nil if the argument is missing or not Hash
|
61
60
|
# @see anotherone
|
62
61
|
def get(argvs)
|
63
62
|
return nil unless argvs
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# regular expression of retry() method.
|
69
|
-
return argvs.reason unless argvs.reason.empty?
|
63
|
+
unless GetRetried[argvs['reason']]
|
64
|
+
# Return reason text already decided except reason match with the regular expression of
|
65
|
+
# retry() method.
|
66
|
+
return argvs['reason'] unless argvs['reason'].empty?
|
70
67
|
end
|
71
|
-
return 'delivered' if argvs
|
68
|
+
return 'delivered' if argvs['deliverystatus'].start_with?('2.')
|
72
69
|
|
73
70
|
reasontext = ''
|
74
|
-
|
71
|
+
issuedcode = argvs['diagnosticcode'] || ''
|
72
|
+
codeformat = argvs['diagnostictype'] || ''
|
73
|
+
|
74
|
+
if codeformat == 'SMTP' || codeformat == ''
|
75
75
|
# Diagnostic-Code: SMTP; ... or empty value
|
76
76
|
ClassOrder[0].each do |e|
|
77
|
-
# Check the value of Diagnostic-Code: and the value of Status:, it is a
|
78
|
-
#
|
77
|
+
# Check the value of Diagnostic-Code: and the value of Status:, it is a deliverystats,
|
78
|
+
# with true() method in each Sisimai::Reason::* class.
|
79
79
|
p = 'Sisimai::Reason::' << e
|
80
80
|
r = nil
|
81
81
|
begin
|
@@ -98,13 +98,13 @@ module Sisimai
|
|
98
98
|
if reasontext == 'undefined' || reasontext.empty?
|
99
99
|
# Action: delayed => "expired"
|
100
100
|
reasontext = nil
|
101
|
-
reasontext ||= 'expired' if argvs
|
101
|
+
reasontext ||= 'expired' if argvs['action'] == 'delayed'
|
102
102
|
return reasontext if reasontext
|
103
103
|
|
104
104
|
# Try to match with message patterns in Sisimai::Reason::Vacation
|
105
105
|
require 'sisimai/reason/vacation'
|
106
|
-
reasontext = 'vacation' if Sisimai::Reason::Vacation.match(
|
107
|
-
reasontext ||= 'onhold' unless
|
106
|
+
reasontext = 'vacation' if Sisimai::Reason::Vacation.match(issuedcode.downcase)
|
107
|
+
reasontext ||= 'onhold' unless issuedcode.empty?
|
108
108
|
reasontext ||= 'undefined'
|
109
109
|
end
|
110
110
|
end
|
@@ -112,24 +112,24 @@ module Sisimai
|
|
112
112
|
end
|
113
113
|
|
114
114
|
# Detect the other bounce reason, fall back method for get()
|
115
|
-
# @param [
|
116
|
-
# @return [String, Nil]
|
117
|
-
# is missing or invalid object
|
115
|
+
# @param [Hash] argvs Parsed email object
|
116
|
+
# @return [String, Nil] Bounce reason or nli if the argument is missing or not Hash
|
118
117
|
# @see get
|
119
118
|
def anotherone(argvs)
|
120
|
-
return
|
121
|
-
return argvs.reason unless argvs.reason.empty?
|
119
|
+
return argvs['reason'] unless argvs['reason'].empty?
|
122
120
|
|
123
121
|
require 'sisimai/smtp/status'
|
124
|
-
|
122
|
+
issuedcode = argvs['diagnosticcode'].downcase || ''
|
123
|
+
codeformat = argvs['diagnostictype'] || ''
|
124
|
+
actiontext = argvs['action'] || ''
|
125
|
+
statuscode = argvs['deliverystatus'] || ''
|
125
126
|
reasontext = Sisimai::SMTP::Status.name(statuscode) || ''
|
126
127
|
|
127
128
|
catch :TRY_TO_MATCH do
|
128
129
|
while true
|
129
|
-
diagnostic = argvs.diagnosticcode.downcase || ''
|
130
130
|
trytomatch = reasontext.empty? ? true : false
|
131
131
|
trytomatch ||= true if GetRetried[reasontext]
|
132
|
-
trytomatch ||= true if
|
132
|
+
trytomatch ||= true if codeformat != 'SMTP'
|
133
133
|
throw :TRY_TO_MATCH unless trytomatch
|
134
134
|
|
135
135
|
# Could not decide the reason by the value of Status:
|
@@ -145,25 +145,26 @@ module Sisimai
|
|
145
145
|
next
|
146
146
|
end
|
147
147
|
|
148
|
-
next unless r.match(
|
148
|
+
next unless r.match(issuedcode)
|
149
149
|
reasontext = e.downcase
|
150
150
|
break
|
151
151
|
end
|
152
152
|
throw :TRY_TO_MATCH unless reasontext.empty?
|
153
153
|
|
154
154
|
# Check the value of Status:
|
155
|
-
|
156
|
-
if
|
155
|
+
code2digit = statuscode[0, 3] || ''
|
156
|
+
if code2digit == '5.6' || code2digit == '4.6'
|
157
157
|
# X.6.0 Other or undefined media error
|
158
158
|
reasontext = 'contenterror'
|
159
159
|
|
160
|
-
elsif
|
160
|
+
elsif code2digit == '5.7' || code2digit == '4.7'
|
161
161
|
# X.7.0 Other or undefined security status
|
162
162
|
reasontext = 'securityerror'
|
163
163
|
|
164
|
-
elsif
|
164
|
+
elsif codeformat.start_with?('X-UNIX')
|
165
165
|
# Diagnostic-Code: X-UNIX; ...
|
166
166
|
reasontext = 'mailererror'
|
167
|
+
|
167
168
|
else
|
168
169
|
# 50X Syntax Error?
|
169
170
|
require 'sisimai/reason/syntaxerror'
|
@@ -172,13 +173,13 @@ module Sisimai
|
|
172
173
|
throw :TRY_TO_MATCH unless reasontext.empty?
|
173
174
|
|
174
175
|
# Check the value of Action: field, first
|
175
|
-
if
|
176
|
+
if actiontext.start_with?('delayed', 'expired')
|
176
177
|
# Action: delayed, expired
|
177
178
|
reasontext = 'expired'
|
178
179
|
else
|
179
180
|
# Rejected at connection or after EHLO|HELO
|
180
|
-
|
181
|
-
reasontext = 'blocked' if %w[HELO EHLO].index(
|
181
|
+
thecommand = argvs['smtpcommand'] || ''
|
182
|
+
reasontext = 'blocked' if %w[HELO EHLO].index(thecommand)
|
182
183
|
end
|
183
184
|
throw :TRY_TO_MATCH
|
184
185
|
end
|
@@ -193,12 +194,12 @@ module Sisimai
|
|
193
194
|
return nil unless argv1
|
194
195
|
|
195
196
|
reasontext = ''
|
196
|
-
|
197
|
+
issuedcode = argv1.downcase
|
197
198
|
|
198
199
|
# Diagnostic-Code: SMTP; ... or empty value
|
199
200
|
ClassOrder[2].each do |e|
|
200
|
-
# Check the value of Diagnostic-Code: and the value of Status:, it is a
|
201
|
-
#
|
201
|
+
# Check the value of Diagnostic-Code: and the value of Status:, it is a deliverystats, with
|
202
|
+
# true() method in each Sisimai::Reason::* class.
|
202
203
|
p = 'Sisimai::Reason::' << e
|
203
204
|
r = nil
|
204
205
|
begin
|
@@ -209,26 +210,20 @@ module Sisimai
|
|
209
210
|
next
|
210
211
|
end
|
211
212
|
|
212
|
-
next unless r.match(
|
213
|
+
next unless r.match(issuedcode)
|
213
214
|
reasontext = r.text
|
214
215
|
break
|
215
216
|
end
|
216
217
|
return reasontext unless reasontext.empty?
|
217
218
|
|
218
|
-
|
219
|
-
if cv = argv1.match(/\A(SMTP|X-.+);/i)
|
220
|
-
# Check the value of typestring
|
221
|
-
typestring = cv[1].upcase
|
222
|
-
end
|
223
|
-
|
224
|
-
if typestring == 'X-UNIX'
|
219
|
+
if issuedcode.upcase == 'X-UNIX'
|
225
220
|
# X-Unix; ...
|
226
221
|
reasontext = 'mailererror'
|
227
222
|
else
|
228
223
|
# Detect the bounce reason from "Status:" code
|
229
224
|
require 'sisimai/smtp/status'
|
230
|
-
|
231
|
-
reasontext = Sisimai::SMTP::Status.name(
|
225
|
+
cv = Sisimai::SMTP::Status.find(argv1) || ''
|
226
|
+
reasontext = Sisimai::SMTP::Status.name(cv) || 'undefined'
|
232
227
|
end
|
233
228
|
return reasontext
|
234
229
|
end
|
data/lib/sisimai/rfc1894.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module Sisimai
|
2
2
|
# Sisimai::RFC1894 DSN field defined in RFC3464 (obsoletes RFC1894)
|
3
3
|
module RFC1894
|
4
|
-
# Imported from p5-Sisimail/lib/Sisimai/RFC1894.pm
|
5
4
|
class << self
|
6
|
-
FieldNames =
|
5
|
+
FieldNames = {
|
7
6
|
# https://tools.ietf.org/html/rfc3464#section-2.2
|
8
|
-
# Some fields of a DSN apply to all of the delivery attempts described by
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
7
|
+
# Some fields of a DSN apply to all of the delivery attempts described by that DSN. At
|
8
|
+
# most, these fields may appear once in any DSN. These fields are used to correlate the
|
9
|
+
# DSN with the original message transaction and to provide additional information which
|
10
|
+
# may be useful to gateways.
|
12
11
|
#
|
13
12
|
# The following fields (not defined in RFC 3464) are used in Sisimai
|
14
13
|
# - X-Original-Message-ID: <....> (GSuite)
|
@@ -16,13 +15,16 @@ module Sisimai
|
|
16
15
|
# The following fields are not used in Sisimai:
|
17
16
|
# - Original-Envelope-Id
|
18
17
|
# - DSN-Gateway
|
19
|
-
|
18
|
+
'arrival-date' => ':',
|
19
|
+
'received-from-mta' => ';',
|
20
|
+
'reporting-mta' => ';',
|
21
|
+
'x-original-message-id' => '@',
|
20
22
|
|
21
23
|
# https://tools.ietf.org/html/rfc3464#section-2.3
|
22
|
-
# A DSN contains information about attempts to deliver a message to one or
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
24
|
+
# A DSN contains information about attempts to deliver a message to one or more recipi-
|
25
|
+
# ents. The delivery information for any particular recipient is contained in a group of
|
26
|
+
# contiguous per-recipient fields. Each group of per-recipient fields is preceded by a
|
27
|
+
# blank line.
|
26
28
|
#
|
27
29
|
# The following fields (not defined in RFC 3464) are used in Sisimai
|
28
30
|
# - X-Actual-Recipient: RFC822; ....
|
@@ -30,18 +32,24 @@ module Sisimai
|
|
30
32
|
# The following fields are not used in Sisimai:
|
31
33
|
# - Will-Retry-Until
|
32
34
|
# - Final-Log-ID
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
'action' => 'e',
|
36
|
+
'diagnostic-code' => ';',
|
37
|
+
'final-recipient' => ';',
|
38
|
+
'last-attempt-date' => ':',
|
39
|
+
'original-recipient' => ';',
|
40
|
+
'remote-mta' => ';',
|
41
|
+
'status' => '.',
|
42
|
+
'x-actual-recipient' => ';',
|
43
|
+
}.freeze
|
36
44
|
|
37
45
|
CapturesOn = {
|
38
|
-
'addr' => %r/\A((?:Original|Final|X-Actual)-Recipient):[ ]
|
39
|
-
'code' => %r/\A(Diagnostic-Code):[ ]
|
40
|
-
'date' => %r/\A((?:Arrival|Last-Attempt)-Date):[ ]
|
41
|
-
'host' => %r/\A((?:Received-From|Remote|Reporting)-MTA):[ ]
|
42
|
-
'list' => %r/\A(Action):[ ]
|
43
|
-
'stat' => %r/\A(Status):[ ]
|
44
|
-
'text' => %r/\A(X-Original-Message-ID):[ ]
|
46
|
+
'addr' => %r/\A((?:Original|Final|X-Actual)-Recipient):[ ](.+?);[ ]*(.+)/,
|
47
|
+
'code' => %r/\A(Diagnostic-Code):[ ](.+?);[ ]*(.*)/,
|
48
|
+
'date' => %r/\A((?:Arrival|Last-Attempt)-Date):[ ](.+)/,
|
49
|
+
'host' => %r/\A((?:Received-From|Remote|Reporting)-MTA):[ ](.+?);[ ]*(.+)/,
|
50
|
+
'list' => %r/\A(Action):[ ](delayed|deliverable|delivered|expanded|expired|failed|failure|relayed)/i,
|
51
|
+
'stat' => %r/\A(Status):[ ]([245][.]\d+[.]\d+)/,
|
52
|
+
'text' => %r/\A(X-Original-Message-ID):[ ](.+)/,
|
45
53
|
#'text' => %r/\A(Final-Log-ID|Original-Envelope-Id):[ ]*(.+)/,
|
46
54
|
}.freeze
|
47
55
|
|
@@ -61,6 +69,13 @@ module Sisimai
|
|
61
69
|
'x-original-message-id' => 'text',
|
62
70
|
}.freeze
|
63
71
|
|
72
|
+
def FIELDINDEX
|
73
|
+
return %w[
|
74
|
+
Action Arrival-Date Diagnostic-Code Final-Recipient Last-Attempt-Date Original-Recipient
|
75
|
+
Received-From-MTA Remote-MTA Reporting-MTA Status X-Actual-Recipienet X-Original-Message-ID
|
76
|
+
]
|
77
|
+
end
|
78
|
+
|
64
79
|
# Table to be converted to key name defined in Sisimai::Lhost class
|
65
80
|
# @param [Symbol] group RFC822 Header group name
|
66
81
|
# @return [Array,Hash] RFC822 Header list
|
@@ -81,23 +96,35 @@ module Sisimai
|
|
81
96
|
end
|
82
97
|
|
83
98
|
# Check the argument matches with a field defined in RFC3464
|
84
|
-
# @param [String] argv0 A line
|
85
|
-
# @return [
|
99
|
+
# @param [String] argv0 A line including field and value defined in RFC3464
|
100
|
+
# @return [Boolean] false: did not matched, true: matched
|
86
101
|
# @since v4.25.0
|
87
102
|
def match(argv0 = '')
|
103
|
+
label = Sisimai::RFC1894.label(argv0)
|
104
|
+
|
105
|
+
return false unless label
|
106
|
+
return false unless FieldNames.has_key?(label)
|
107
|
+
return false unless argv0.include?(FieldNames[label])
|
108
|
+
return true
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns a field name as a lqbel from the given string
|
112
|
+
# @param [String] argv0 A line including field and value defined in RFC3464
|
113
|
+
# @return [String] Field name as a label
|
114
|
+
# @since v4.25.15
|
115
|
+
def label(argv0 = '')
|
88
116
|
return nil if argv0.empty?
|
89
|
-
return
|
90
|
-
return 2 if FieldNames[1].any? { |a| argv0.start_with?(a) }
|
91
|
-
return nil
|
117
|
+
return argv0.split(':', 2).shift.downcase
|
92
118
|
end
|
93
119
|
|
94
120
|
# Check the argument is including field defined in RFC3464 and return values
|
95
|
-
# @param [String] argv0 A line
|
121
|
+
# @param [String] argv0 A line including field and value defined in RFC3464
|
96
122
|
# @return [Array] ['field-name', 'value-type', 'Value', 'field-group']
|
97
123
|
# @since v4.25.0
|
98
124
|
def field(argv0 = '')
|
99
125
|
return nil if argv0.empty?
|
100
|
-
|
126
|
+
label = Sisimai::RFC1894.label(argv0)
|
127
|
+
group = FieldGroup[label] || ''
|
101
128
|
|
102
129
|
return nil if group.empty?
|
103
130
|
return nil unless CapturesOn[group]
|