sisimai 5.1.0-java → 5.2.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 +4 -4
- data/.github/workflows/rake-test.yml +1 -1
- data/ChangeLog.md +102 -0
- data/Makefile +4 -2
- data/README-JA.md +23 -16
- data/README.md +22 -15
- data/lib/sisimai/arf.rb +121 -210
- data/lib/sisimai/fact.rb +208 -158
- data/lib/sisimai/lda.rb +98 -0
- data/lib/sisimai/lhost/activehunter.rb +1 -1
- data/lib/sisimai/lhost/amazonses.rb +185 -301
- data/lib/sisimai/lhost/apachejames.rb +48 -51
- data/lib/sisimai/lhost/biglobe.rb +1 -2
- data/lib/sisimai/lhost/courier.rb +10 -8
- data/lib/sisimai/lhost/domino.rb +25 -25
- data/lib/sisimai/lhost/dragonfly.rb +3 -4
- data/lib/sisimai/lhost/einsundeins.rb +3 -4
- data/lib/sisimai/lhost/exchange2003.rb +6 -8
- data/lib/sisimai/lhost/exchange2007.rb +111 -101
- data/lib/sisimai/lhost/exim.rb +232 -242
- data/lib/sisimai/lhost/ezweb.rb +43 -51
- data/lib/sisimai/lhost/fml.rb +2 -3
- data/lib/sisimai/lhost/gmail.rb +32 -28
- data/lib/sisimai/lhost/gmx.rb +4 -16
- data/lib/sisimai/lhost/googlegroups.rb +9 -8
- data/lib/sisimai/lhost/googleworkspace.rb +94 -0
- data/lib/sisimai/lhost/imailserver.rb +7 -16
- data/lib/sisimai/lhost/interscanmss.rb +1 -1
- data/lib/sisimai/lhost/kddi.rb +3 -4
- data/lib/sisimai/lhost/mailfoundry.rb +2 -5
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +1 -2
- data/lib/sisimai/lhost/messagingserver.rb +14 -13
- data/lib/sisimai/lhost/mfilter.rb +4 -3
- data/lib/sisimai/lhost/notes.rb +2 -4
- data/lib/sisimai/lhost/opensmtpd.rb +2 -2
- data/lib/sisimai/lhost/postfix.rb +25 -27
- data/lib/sisimai/lhost/qmail.rb +130 -106
- data/lib/sisimai/lhost/sendmail.rb +19 -18
- data/lib/sisimai/lhost/v5sendmail.rb +88 -60
- data/lib/sisimai/lhost/verizon.rb +2 -2
- data/lib/sisimai/lhost/x1.rb +1 -1
- data/lib/sisimai/lhost/x2.rb +1 -2
- data/lib/sisimai/lhost/x3.rb +2 -2
- data/lib/sisimai/lhost/x6.rb +1 -1
- data/lib/sisimai/lhost/zoho.rb +2 -2
- data/lib/sisimai/lhost.rb +18 -21
- data/lib/sisimai/message.rb +93 -146
- data/lib/sisimai/order.rb +21 -77
- data/lib/sisimai/reason/authfailure.rb +1 -4
- data/lib/sisimai/reason/badreputation.rb +2 -2
- data/lib/sisimai/reason/blocked.rb +7 -10
- data/lib/sisimai/reason/contenterror.rb +7 -1
- data/lib/sisimai/reason/exceedlimit.rb +1 -4
- data/lib/sisimai/reason/failedstarttls.rb +42 -0
- data/lib/sisimai/reason/filtered.rb +5 -4
- data/lib/sisimai/reason/hasmoved.rb +1 -2
- data/lib/sisimai/reason/hostunknown.rb +3 -3
- data/lib/sisimai/reason/mailboxfull.rb +2 -4
- data/lib/sisimai/reason/mailererror.rb +1 -2
- data/lib/sisimai/reason/mesgtoobig.rb +2 -4
- data/lib/sisimai/reason/norelaying.rb +2 -3
- data/lib/sisimai/reason/notaccept.rb +2 -3
- data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
- data/lib/sisimai/reason/rejected.rb +1 -1
- data/lib/sisimai/reason/requireptr.rb +2 -2
- data/lib/sisimai/reason/securityerror.rb +1 -3
- data/lib/sisimai/reason/spamdetected.rb +6 -8
- data/lib/sisimai/reason/speeding.rb +1 -2
- data/lib/sisimai/reason/suppressed.rb +36 -0
- data/lib/sisimai/reason/suspend.rb +1 -3
- data/lib/sisimai/reason/systemerror.rb +5 -0
- data/lib/sisimai/reason/toomanyconn.rb +1 -2
- data/lib/sisimai/reason/userunknown.rb +1 -1
- data/lib/sisimai/reason/virusdetected.rb +5 -6
- data/lib/sisimai/reason.rb +77 -73
- data/lib/sisimai/rfc1123.rb +152 -0
- data/lib/sisimai/rfc1894.rb +102 -62
- data/lib/sisimai/rfc2045.rb +2 -1
- data/lib/sisimai/rfc3464/thirdparty.rb +102 -0
- data/lib/sisimai/rfc3464.rb +222 -343
- data/lib/sisimai/rfc3834.rb +1 -1
- data/lib/sisimai/rfc5322.rb +7 -17
- data/lib/sisimai/rfc791.rb +69 -0
- data/lib/sisimai/rhost/aol.rb +36 -0
- data/lib/sisimai/rhost/apple.rb +5 -2
- data/lib/sisimai/rhost/cox.rb +3 -2
- data/lib/sisimai/rhost/facebook.rb +100 -0
- data/lib/sisimai/rhost/franceptt.rb +3 -2
- data/lib/sisimai/rhost/godaddy.rb +3 -2
- data/lib/sisimai/rhost/google.rb +19 -17
- data/lib/sisimai/rhost/gsuite.rb +42 -0
- data/lib/sisimai/rhost/iua.rb +3 -3
- data/lib/sisimai/rhost/kddi.rb +3 -2
- data/lib/sisimai/rhost/messagelabs.rb +37 -0
- data/lib/sisimai/rhost/microsoft.rb +56 -49
- data/lib/sisimai/rhost/mimecast.rb +29 -27
- data/lib/sisimai/rhost/nttdocomo.rb +4 -3
- data/lib/sisimai/rhost/outlook.rb +36 -0
- data/lib/sisimai/rhost/spectrum.rb +3 -2
- data/lib/sisimai/rhost/tencent.rb +3 -2
- data/lib/sisimai/rhost/yahooinc.rb +4 -3
- data/lib/sisimai/rhost.rb +69 -39
- data/lib/sisimai/smtp/command.rb +31 -21
- data/lib/sisimai/smtp/failure.rb +103 -0
- data/lib/sisimai/smtp/reply.rb +29 -25
- data/lib/sisimai/smtp/status.rb +36 -19
- data/lib/sisimai/smtp/transcript.rb +15 -15
- data/lib/sisimai/string.rb +0 -46
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
- data/set-of-emails/maildir/bsd/{lhost-aol-03.eml → rhost-aol-03.eml} +1264 -1264
- data/set-of-emails/maildir/bsd/{lhost-aol-04.eml → rhost-aol-04.eml} +1260 -1260
- data/set-of-emails/maildir/bsd/{lhost-aol-05.eml → rhost-aol-05.eml} +105 -105
- data/set-of-emails/maildir/bsd/{lhost-aol-06.eml → rhost-aol-06.eml} +105 -105
- data/set-of-emails/maildir/bsd/rhost-gsuite-01.eml +189 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-02.eml +180 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-03.eml +251 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-04.eml +211 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-05.eml +226 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-06.eml +257 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-07.eml +289 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-08.eml +231 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-09.eml +231 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-10.eml +254 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-11.eml +228 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-12.eml +271 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-13.eml +261 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-14.eml +273 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/{lhost-messagelabs-01.eml → rhost-messagelabs-01.eml} +93 -93
- data/set-of-emails/maildir/bsd/rhost-outlook-01.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-02.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-03.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-04.eml +79 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-06.eml +75 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-07.eml +70 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-08.eml +70 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-09.eml +56 -0
- data/set-of-emails/maildir/tmp/arf-22.eml +49 -0
- data/set-of-emails/maildir/tmp/arf-23.eml +49 -0
- data/set-of-emails/maildir/tmp/arf-24.eml +50 -0
- data/set-of-emails/maildir/tmp/lhost-exim-07.eml +28 -0
- metadata +73 -56
- data/lib/sisimai/lhost/amavis.rb +0 -163
- data/lib/sisimai/lhost/amazonworkmail.rb +0 -127
- data/lib/sisimai/lhost/aol.rb +0 -125
- data/lib/sisimai/lhost/barracuda.rb +0 -92
- data/lib/sisimai/lhost/bigfoot.rb +0 -125
- data/lib/sisimai/lhost/facebook.rb +0 -188
- data/lib/sisimai/lhost/gsuite.rb +0 -194
- data/lib/sisimai/lhost/mailru.rb +0 -214
- data/lib/sisimai/lhost/mcafee.rb +0 -109
- data/lib/sisimai/lhost/messagelabs.rb +0 -120
- data/lib/sisimai/lhost/mxlogic.rb +0 -198
- data/lib/sisimai/lhost/office365.rb +0 -252
- data/lib/sisimai/lhost/outlook.rb +0 -129
- data/lib/sisimai/lhost/powermta.rb +0 -118
- data/lib/sisimai/lhost/receivingses.rb +0 -126
- data/lib/sisimai/lhost/sendgrid.rb +0 -150
- data/lib/sisimai/lhost/surfcontrol.rb +0 -105
- data/lib/sisimai/lhost/x4.rb +0 -269
- data/lib/sisimai/lhost/x5.rb +0 -112
- data/lib/sisimai/lhost/yahoo.rb +0 -102
- data/lib/sisimai/lhost/yandex.rb +0 -118
- data/lib/sisimai/mda.rb +0 -121
- data/lib/sisimai/smtp/error.rb +0 -119
- /data/set-of-emails/maildir/bsd/{lhost-googlegroups-15.eml → lhost-googleworkspace-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-x4-08.eml → lhost-x2-06.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-01.eml → rfc3464-51.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-03.eml → rfc3464-52.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-04.eml → rfc3464-53.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-05.eml → rfc3464-54.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-06.eml → rfc3464-55.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-07.eml → rfc3464-56.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-08.eml → rfc3464-57.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-09.eml → rfc3464-58.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-10.eml → rfc3464-59.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-11.eml → rfc3464-60.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-12.eml → rfc3464-61.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-13.eml → rfc3464-62.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-14.eml → rfc3464-63.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-15.eml → rfc3464-64.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-02.eml → rfc3464-65.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-aol-01.eml → rhost-aol-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-aol-02.eml → rhost-aol-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-facebook-03.eml → rhost-facebook-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-facebook-04.eml → rhost-facebook-04.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-messagelabs-02.eml → rhost-messagelabs-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-messagelabs-03.eml → rhost-messagelabs-03.eml} +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-37.eml +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-38.eml +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-39.eml +0 -0
data/lib/sisimai/lhost/aol.rb
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Aol decodes a bounce email which created by Aol Mail https://mail.aol.com/.
|
3
|
-
# Methods in the module are called from only Sisimai::Message.
|
4
|
-
module Aol
|
5
|
-
class << self
|
6
|
-
require 'sisimai/lhost'
|
7
|
-
|
8
|
-
Indicators = Sisimai::Lhost.INDICATORS
|
9
|
-
Boundaries = ['Content-Type: message/rfc822'].freeze
|
10
|
-
StartingOf = { message: ['Content-Type: message/delivery-status'] }.freeze
|
11
|
-
MessagesOf = {
|
12
|
-
'hostunknown' => ['Host or domain name not found'],
|
13
|
-
'notaccept' => ['type=MX: Malformed or unexpected name server reply'],
|
14
|
-
}.freeze
|
15
|
-
|
16
|
-
# @abstract Decodes the bounce message from Aol Mail
|
17
|
-
# @param [Hash] mhead Message headers of a bounce email
|
18
|
-
# @param [String] mbody Message body of a bounce email
|
19
|
-
# @return [Hash] Bounce data list and message/rfc822 part
|
20
|
-
# @return [Nil] it failed to decode or the arguments are missing
|
21
|
-
def inquire(mhead, mbody)
|
22
|
-
# X-AOL-IP: 192.0.2.135
|
23
|
-
# X-AOL-VSS-INFO: 5600.1067/98281
|
24
|
-
# X-AOL-VSS-CODE: clean
|
25
|
-
# x-aol-sid: 3039ac1afc14546fb98a0945
|
26
|
-
# X-AOL-SCOLL-EIL: 1
|
27
|
-
# x-aol-global-disposition: G
|
28
|
-
# x-aol-sid: 3039ac1afd4d546fb97d75c6
|
29
|
-
# X-BounceIO-Id: 9D38DE46-21BC-4309-83E1-5F0D788EFF1F.1_0
|
30
|
-
# X-Outbound-Mail-Relay-Queue-ID: 07391702BF4DC
|
31
|
-
# X-Outbound-Mail-Relay-Sender: rfc822; shironeko@aol.example.jp
|
32
|
-
return nil unless mhead['x-aol-ip']
|
33
|
-
|
34
|
-
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
35
|
-
permessage = {} # (Hash) Store values of each Per-Message field
|
36
|
-
|
37
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
38
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
39
|
-
bodyslices = emailparts[0].split("\n")
|
40
|
-
readslices = ['']
|
41
|
-
readcursor = 0 # (Integer) Points the current cursor position
|
42
|
-
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
43
|
-
v = nil
|
44
|
-
|
45
|
-
while e = bodyslices.shift do
|
46
|
-
# Read error messages and delivery status lines from the head of the email to the previous
|
47
|
-
# line of the beginning of the original message.
|
48
|
-
readslices << e # Save the current line for the next loop
|
49
|
-
|
50
|
-
if readcursor == 0
|
51
|
-
# Beginning of the bounce message or message/delivery-status part
|
52
|
-
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
53
|
-
next
|
54
|
-
end
|
55
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
56
|
-
next if e.empty?
|
57
|
-
|
58
|
-
if f = Sisimai::RFC1894.match(e)
|
59
|
-
# "e" matched with any field defined in RFC3464
|
60
|
-
next unless o = Sisimai::RFC1894.field(e)
|
61
|
-
v = dscontents[-1]
|
62
|
-
|
63
|
-
if o[-1] == 'addr'
|
64
|
-
# Final-Recipient: rfc822; kijitora@example.jp
|
65
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
66
|
-
if o[0] == 'final-recipient'
|
67
|
-
# Final-Recipient: rfc822; kijitora@example.jp
|
68
|
-
if v['recipient']
|
69
|
-
# There are multiple recipient addresses in the message body.
|
70
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
71
|
-
v = dscontents[-1]
|
72
|
-
end
|
73
|
-
v['recipient'] = o[2]
|
74
|
-
recipients += 1
|
75
|
-
else
|
76
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
77
|
-
v['alias'] = o[2]
|
78
|
-
end
|
79
|
-
elsif o[-1] == 'code'
|
80
|
-
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
81
|
-
v['spec'] = o[1]
|
82
|
-
v['diagnosis'] = o[2]
|
83
|
-
else
|
84
|
-
# Other DSN fields defined in RFC3464
|
85
|
-
next unless fieldtable[o[0]]
|
86
|
-
v[fieldtable[o[0]]] = o[2]
|
87
|
-
|
88
|
-
next unless f
|
89
|
-
permessage[fieldtable[o[0]]] = o[2]
|
90
|
-
end
|
91
|
-
else
|
92
|
-
# Continued line of the value of Diagnostic-Code field
|
93
|
-
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
94
|
-
next unless e.start_with?(' ')
|
95
|
-
v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
|
96
|
-
readslices[-1] = 'Diagnostic-Code: ' << e
|
97
|
-
end
|
98
|
-
end
|
99
|
-
return nil unless recipients > 0
|
100
|
-
|
101
|
-
dscontents.each do |e|
|
102
|
-
# Set default values if each value is empty.
|
103
|
-
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
104
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
|
105
|
-
|
106
|
-
MessagesOf.each_key do |r|
|
107
|
-
# Verify each regular expression of session errors
|
108
|
-
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
109
|
-
e['reason'] = r
|
110
|
-
break
|
111
|
-
end
|
112
|
-
|
113
|
-
if e['status'].empty? || e['status'].end_with?('.0.0')
|
114
|
-
# There is no value of Status header or the value is 5.0.0, 4.0.0
|
115
|
-
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || ''
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
120
|
-
end
|
121
|
-
def description; return 'Aol Mail: https://www.aol.com'; end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
@@ -1,92 +0,0 @@
|
|
1
|
-
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Barracuda decodes a bounce email which created by Barracuda https://www.barracuda.com/.
|
3
|
-
# Methods in the module are called from only Sisimai::Message.
|
4
|
-
module Barracuda
|
5
|
-
class << self
|
6
|
-
require 'sisimai/lhost'
|
7
|
-
|
8
|
-
Indicators = Sisimai::Lhost.INDICATORS
|
9
|
-
Boundaries = ['Content-Type: text/rfc822-headers'].freeze
|
10
|
-
StartingOf = { message: ['Your message to:'] }.freeze
|
11
|
-
|
12
|
-
# @abstract Decodes the bounce message from Barracuda
|
13
|
-
# @param [Hash] mhead Message headers of a bounce email
|
14
|
-
# @param [String] mbody Message body of a bounce email
|
15
|
-
# @return [Hash] Bounce data list and message/rfc822 part
|
16
|
-
# @return [Nil] it failed to decode or the arguments are missing
|
17
|
-
# @since v4.25.6
|
18
|
-
def inquire(mhead, mbody)
|
19
|
-
# Subject: **Message you sent blocked by our bulk email filter**
|
20
|
-
return nil unless mhead['subject'].to_s.end_with?('our bulk email filter**')
|
21
|
-
|
22
|
-
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
23
|
-
permessage = {} # (Hash) Store values of each Per-Message field
|
24
|
-
|
25
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
26
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
27
|
-
bodyslices = emailparts[0].split("\n")
|
28
|
-
readcursor = 0 # (Integer) Points the current cursor position
|
29
|
-
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
30
|
-
v = nil
|
31
|
-
|
32
|
-
while e = bodyslices.shift do
|
33
|
-
# Read error messages and delivery status lines from the head of the email to the previous
|
34
|
-
# line of the beginning of the original message.
|
35
|
-
if readcursor == 0
|
36
|
-
# Beginning of the bounce message or message/delivery-status part
|
37
|
-
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
38
|
-
next
|
39
|
-
end
|
40
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
41
|
-
next if e.empty?
|
42
|
-
|
43
|
-
if f = Sisimai::RFC1894.match(e)
|
44
|
-
# "e" matched with any field defined in RFC3464
|
45
|
-
next unless o = Sisimai::RFC1894.field(e)
|
46
|
-
v = dscontents[-1]
|
47
|
-
|
48
|
-
if o[-1] == 'addr'
|
49
|
-
# Final-Recipient: rfc822; kijitora@example.jp
|
50
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
51
|
-
if o[0] == 'final-recipient'
|
52
|
-
# Final-Recipient: rfc822; kijitora@example.jp
|
53
|
-
if v['recipient']
|
54
|
-
# There are multiple recipient addresses in the message body.
|
55
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
56
|
-
v = dscontents[-1]
|
57
|
-
end
|
58
|
-
v['recipient'] = o[2]
|
59
|
-
recipients += 1
|
60
|
-
else
|
61
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
62
|
-
v['alias'] = o[2]
|
63
|
-
end
|
64
|
-
elsif o[-1] == 'code'
|
65
|
-
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
66
|
-
v['spec'] = o[1]
|
67
|
-
v['diagnosis'] = o[2]
|
68
|
-
else
|
69
|
-
# Other DSN fields defined in RFC3464
|
70
|
-
next unless fieldtable[o[0]]
|
71
|
-
v[fieldtable[o[0]]] = o[2]
|
72
|
-
|
73
|
-
next unless f
|
74
|
-
permessage[fieldtable[o[0]]] = o[2]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
return nil unless recipients > 0
|
79
|
-
|
80
|
-
dscontents.each do |e|
|
81
|
-
# Set default values if each value is empty.
|
82
|
-
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
83
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].to_s.tr("\n", ' '))
|
84
|
-
end
|
85
|
-
|
86
|
-
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
87
|
-
end
|
88
|
-
def description; return 'Barracuda: https://www.barracuda.com'; end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
@@ -1,125 +0,0 @@
|
|
1
|
-
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Bigfoot decodes a bounce email which created by Bigfoot https://www.bigfoot.com/.
|
3
|
-
# Methods in the module are called from only Sisimai::Message.
|
4
|
-
module Bigfoot
|
5
|
-
class << self
|
6
|
-
require 'sisimai/lhost'
|
7
|
-
|
8
|
-
Indicators = Sisimai::Lhost.INDICATORS
|
9
|
-
Boundaries = ['Content-Type: message/partial'].freeze
|
10
|
-
MarkingsOf = { message: ' ----- Transcript of session follows -----' }.freeze
|
11
|
-
|
12
|
-
# @abstract Decodes the bounce message from Bigfoot
|
13
|
-
# @param [Hash] mhead Message headers of a bounce email
|
14
|
-
# @param [String] mbody Message body of a bounce email
|
15
|
-
# @return [Hash] Bounce data list and message/rfc822 part
|
16
|
-
# @return [Nil] it failed to decode or the arguments are missing
|
17
|
-
def inquire(mhead, mbody)
|
18
|
-
# :subject => %r/\AReturned mail: /,
|
19
|
-
match = 0
|
20
|
-
match += 1 if mhead['from'].include?('@bigfoot.com>')
|
21
|
-
match += 1 if mhead['received'].any? { |a| a.include?('.bigfoot.com') }
|
22
|
-
return nil unless match > 0
|
23
|
-
|
24
|
-
require 'sisimai/smtp/command'
|
25
|
-
require 'sisimai/rfc1894'
|
26
|
-
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
27
|
-
permessage = {} # (Hash) Store values of each Per-Message field
|
28
|
-
|
29
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
30
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
31
|
-
bodyslices = emailparts[0].split("\n")
|
32
|
-
readslices = ['']
|
33
|
-
readcursor = 0 # (Integer) Points the current cursor position
|
34
|
-
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
35
|
-
thecommand = '' # (String) SMTP Command name begin with the string '>>>'
|
36
|
-
esmtpreply = '' # (String) Reply from remote server on SMTP session
|
37
|
-
v = nil
|
38
|
-
|
39
|
-
while e = bodyslices.shift do
|
40
|
-
# Read error messages and delivery status lines from the head of the email to the previous
|
41
|
-
# line of the beginning of the original message.
|
42
|
-
readslices << e # Save the current line for the next loop
|
43
|
-
|
44
|
-
if readcursor == 0
|
45
|
-
# Beginning of the bounce message or message/delivery-status part
|
46
|
-
readcursor |= Indicators[:deliverystatus] if e.start_with?(MarkingsOf[:message])
|
47
|
-
next
|
48
|
-
end
|
49
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
50
|
-
next if e.empty?
|
51
|
-
|
52
|
-
if f = Sisimai::RFC1894.match(e)
|
53
|
-
# "e" matched with any field defined in RFC3464
|
54
|
-
next unless o = Sisimai::RFC1894.field(e)
|
55
|
-
v = dscontents[-1]
|
56
|
-
|
57
|
-
if o[-1] == 'addr'
|
58
|
-
# Final-Recipient: rfc822; kijitora@example.jp
|
59
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
60
|
-
if o[0] == 'final-recipient'
|
61
|
-
# Final-Recipient: rfc822; kijitora@example.jp
|
62
|
-
if v['recipient']
|
63
|
-
# There are multiple recipient addresses in the message body.
|
64
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
65
|
-
v = dscontents[-1]
|
66
|
-
end
|
67
|
-
v['recipient'] = o[2]
|
68
|
-
recipients += 1
|
69
|
-
else
|
70
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
71
|
-
v['alias'] = o[2]
|
72
|
-
end
|
73
|
-
elsif o[-1] == 'code'
|
74
|
-
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
75
|
-
v['spec'] = o[1]
|
76
|
-
v['diagnosis'] = o[2]
|
77
|
-
else
|
78
|
-
# Other DSN fields defined in RFC3464
|
79
|
-
next unless fieldtable[o[0]]
|
80
|
-
v[fieldtable[o[0]]] = o[2]
|
81
|
-
|
82
|
-
next unless f
|
83
|
-
permessage[fieldtable[o[0]]] = o[2]
|
84
|
-
end
|
85
|
-
else
|
86
|
-
# The line does not begin with a DSN field defined in RFC3464
|
87
|
-
unless e.start_with?(' ')
|
88
|
-
# ----- Transcript of session follows -----
|
89
|
-
# >>> RCPT TO:<destinaion@example.net>
|
90
|
-
# <<< 553 Invalid recipient destinaion@example.net (Mode: normal)
|
91
|
-
if e.start_with?('>>> ')
|
92
|
-
# >>> DATA
|
93
|
-
thecommand = Sisimai::SMTP::Command.find(e)
|
94
|
-
elsif e.start_with?('<<< ')
|
95
|
-
# <<< Response
|
96
|
-
esmtpreply = e[4, e.size - 4]
|
97
|
-
end
|
98
|
-
else
|
99
|
-
# Continued line of the value of Diagnostic-Code field
|
100
|
-
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
101
|
-
next unless e.start_with?(' ')
|
102
|
-
v['diagnosis'] << ' ' << Sisimai::String.sweep(e[1, e.size])
|
103
|
-
readslices[-1] = 'Diagnostic-Code: ' << e
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
return nil unless recipients > 0
|
108
|
-
|
109
|
-
dscontents.each do |e|
|
110
|
-
# Set default values if each value is empty.
|
111
|
-
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
112
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
113
|
-
e['command'] = thecommand || ''
|
114
|
-
if e['command'].empty?
|
115
|
-
e['command'] = 'EHLO' unless esmtpreply.empty?
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
120
|
-
end
|
121
|
-
def description; return 'Bigfoot: http://www.bigfoot.com'; end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
@@ -1,188 +0,0 @@
|
|
1
|
-
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Facebook decodes a bounce email which created by Facebook https://www.facebook.com.
|
3
|
-
# Methods in the module are called from only Sisimai::Message.
|
4
|
-
module Facebook
|
5
|
-
class << self
|
6
|
-
require 'sisimai/lhost'
|
7
|
-
|
8
|
-
Indicators = Sisimai::Lhost.INDICATORS
|
9
|
-
Boundaries = ['Content-Disposition: inline'].freeze
|
10
|
-
StartingOf = { message: ['This message was created automatically by Facebook.'] }.freeze
|
11
|
-
ReFailures = {
|
12
|
-
# http://postmaster.facebook.com/response_codes
|
13
|
-
# NOT TESTD EXCEPT RCP-P2
|
14
|
-
'userunknown' => [
|
15
|
-
'RCP-P1', # The attempted recipient address does not exist.
|
16
|
-
'INT-P1', # The attempted recipient address does not exist.
|
17
|
-
'INT-P3', # The attempted recpient group address does not exist.
|
18
|
-
'INT-P4', # The attempted recipient address does not exist.
|
19
|
-
],
|
20
|
-
'filtered' => [
|
21
|
-
'RCP-P2', # The attempted recipient's preferences prevent messages from being delivered.
|
22
|
-
'RCP-P3', # The attempted recipient's privacy settings blocked the delivery.
|
23
|
-
],
|
24
|
-
'mesgtoobig' => [
|
25
|
-
'MSG-P1', # The message exceeds Facebook's maximum allowed size.
|
26
|
-
'INT-P2', # The message exceeds Facebook's maximum allowed size.
|
27
|
-
],
|
28
|
-
'contenterror' => [
|
29
|
-
'MSG-P2', # The message contains an attachment type that Facebook does not accept.
|
30
|
-
'MSG-P3', # The message contains multiple instances of a header field that can only be present once. Please see RFC 5322, section 3.6 for more information
|
31
|
-
'POL-P6', # The message contains a url that has been blocked by Facebook.
|
32
|
-
'POL-P7', # The message does not comply with Facebook's abuse policies and will not be accepted.
|
33
|
-
],
|
34
|
-
'securityerror' => [
|
35
|
-
'POL-P1', # Your mail server's IP Address is listed on the Spamhaus PBL.
|
36
|
-
'POL-P2', # Facebook will no longer accept mail from your mail server's IP Address.
|
37
|
-
'POL-P5', # The message contains a virus.
|
38
|
-
'POL-P7', # The message does not comply with Facebook's Domain Authentication requirements.
|
39
|
-
],
|
40
|
-
'notaccept' => [
|
41
|
-
'POL-P3', # Facebook is not accepting messages from your mail server. This will persist for 4 to 8 hours.
|
42
|
-
'POL-P4', # Facebook is not accepting messages from your mail server. This will persist for 24 to 48 hours.
|
43
|
-
'POL-T1', # Facebook is not accepting messages from your mail server, but they may be retried later. This will persist for 1 to 2 hours.
|
44
|
-
'POL-T2', # Facebook is not accepting messages from your mail server, but they may be retried later. This will persist for 4 to 8 hours.
|
45
|
-
'POL-T3', # Facebook is not accepting messages from your mail server, but they may be retried later. This will persist for 24 to 48 hours.
|
46
|
-
],
|
47
|
-
'rejected' => [
|
48
|
-
'DNS-P1', # Your SMTP MAIL FROM domain does not exist.
|
49
|
-
'DNS-P2', # Your SMTP MAIL FROM domain does not have an MX record.
|
50
|
-
'DNS-T1', # Your SMTP MAIL FROM domain exists but does not currently resolve.
|
51
|
-
'DNS-P3', # Your mail server does not have a reverse DNS record.
|
52
|
-
'DNS-T2', # You mail server's reverse DNS record does not currently resolve.
|
53
|
-
],
|
54
|
-
'systemerror' => [
|
55
|
-
'CON-T1', # Facebook's mail server currently has too many connections open to allow another one.
|
56
|
-
],
|
57
|
-
'toomanyconn' => [
|
58
|
-
'CON-T3', # Your mail server has opened too many new connections to Facebook's mail servers in a short period of time.
|
59
|
-
],
|
60
|
-
'suspend' => [
|
61
|
-
'RCP-T4', # The attempted recipient address is currently deactivated. The user may or may not reactivate it.
|
62
|
-
],
|
63
|
-
'undefined' => [
|
64
|
-
'RCP-T1', # The attempted recipient address is not currently available due to an internal system issue. This is a temporary condition.
|
65
|
-
'MSG-T1', # The number of recipients on the message exceeds Facebook's allowed maximum.
|
66
|
-
'CON-T2', # Your mail server currently has too many connections open to Facebook's mail servers.
|
67
|
-
'CON-T4', # Your mail server has exceeded the maximum number of recipients for its current connection.
|
68
|
-
],
|
69
|
-
}.freeze
|
70
|
-
|
71
|
-
# @abstract Decodes the bounce message from Facebook
|
72
|
-
# @param [Hash] mhead Message headers of a bounce email
|
73
|
-
# @param [String] mbody Message body of a bounce email
|
74
|
-
# @return [Hash] Bounce data list and message/rfc822 part
|
75
|
-
# @return [Nil] it failed to decode or the arguments are missing
|
76
|
-
def inquire(mhead, mbody)
|
77
|
-
return nil unless mhead['from'] == 'Facebook <mailer-daemon@mx.facebook.com>'
|
78
|
-
return nil unless mhead['subject'] == 'Sorry, your message could not be delivered'
|
79
|
-
|
80
|
-
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
81
|
-
permessage = {} # (Hash) Store values of each Per-Message field
|
82
|
-
|
83
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
84
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
85
|
-
bodyslices = emailparts[0].split("\n")
|
86
|
-
readslices = ['']
|
87
|
-
readcursor = 0 # (Integer) Points the current cursor position
|
88
|
-
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
89
|
-
fbresponse = '' # (String) Response code from Facebook
|
90
|
-
v = nil
|
91
|
-
|
92
|
-
while e = bodyslices.shift do
|
93
|
-
# Read error messages and delivery status lines from the head of the email to the previous
|
94
|
-
# line of the beginning of the original message.
|
95
|
-
readslices << e # Save the current line for the next loop
|
96
|
-
|
97
|
-
if readcursor == 0
|
98
|
-
# Beginning of the bounce message or message/delivery-status part
|
99
|
-
readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
|
100
|
-
next
|
101
|
-
end
|
102
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
103
|
-
next if e.empty?
|
104
|
-
|
105
|
-
if f = Sisimai::RFC1894.match(e)
|
106
|
-
# "e" matched with any field defined in RFC3464
|
107
|
-
o = Sisimai::RFC1894.field(e) || next
|
108
|
-
v = dscontents[-1]
|
109
|
-
|
110
|
-
if o[-1] == 'addr'
|
111
|
-
# Final-Recipient: rfc822; kijitora@example.jp
|
112
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
113
|
-
if o[0] == 'final-recipient'
|
114
|
-
# Final-Recipient: rfc822; kijitora@example.jp
|
115
|
-
if v['recipient']
|
116
|
-
# There are multiple recipient addresses in the message body.
|
117
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
118
|
-
v = dscontents[-1]
|
119
|
-
end
|
120
|
-
v['recipient'] = o[2]
|
121
|
-
recipients += 1
|
122
|
-
else
|
123
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
124
|
-
v['alias'] = o[2]
|
125
|
-
end
|
126
|
-
elsif o[-1] == 'code'
|
127
|
-
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
128
|
-
v['spec'] = o[1]
|
129
|
-
v['diagnosis'] = o[2]
|
130
|
-
else
|
131
|
-
# Other DSN fields defined in RFC3464
|
132
|
-
next unless fieldtable[o[0]]
|
133
|
-
v[fieldtable[o[0]]] = o[2]
|
134
|
-
|
135
|
-
next unless f
|
136
|
-
permessage[fieldtable[o[0]]] = o[2]
|
137
|
-
end
|
138
|
-
else
|
139
|
-
# Continued line of the value of Diagnostic-Code field
|
140
|
-
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
141
|
-
next unless e.start_with?(' ')
|
142
|
-
v['diagnosis'] << ' ' << e[e.rindex(' ') + 1, e.size]
|
143
|
-
readslices[-1] = 'Diagnostic-Code: ' << e
|
144
|
-
end
|
145
|
-
end
|
146
|
-
return nil unless recipients > 0
|
147
|
-
|
148
|
-
dscontents.each do |e|
|
149
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
150
|
-
|
151
|
-
p0 = e['diagnosis'].index('-') || -1
|
152
|
-
fbresponse = e['diagnosis'][p0 - 3, 6] if p0 > 0
|
153
|
-
|
154
|
-
catch :SESSION do
|
155
|
-
ReFailures.each_key do |r|
|
156
|
-
# Verify each regular expression of session errors
|
157
|
-
ReFailures[r].each do |rr|
|
158
|
-
# Check each regular expression
|
159
|
-
next unless fbresponse == rr
|
160
|
-
e['reason'] = r
|
161
|
-
throw :SESSION
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
# http://postmaster.facebook.com/response_codes
|
167
|
-
# Facebook System Resource Issues
|
168
|
-
# These codes indicate a temporary issue internal to Facebook's
|
169
|
-
# system. Administrators observing these issues are not required to
|
170
|
-
# take any action to correct them.
|
171
|
-
next if e['reason']
|
172
|
-
|
173
|
-
# * INT-Tx
|
174
|
-
#
|
175
|
-
# https://groups.google.com/forum/#!topic/cdmix/eXfi4ddgYLQ
|
176
|
-
# This block has not been tested because we have no email sample
|
177
|
-
# including "INT-T?" error code.
|
178
|
-
next unless fbresponse.start_with?('INT-T')
|
179
|
-
e['reason'] = 'systemerror'
|
180
|
-
end
|
181
|
-
|
182
|
-
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
183
|
-
end
|
184
|
-
def description; return 'Facebook: https://www.facebook.com'; end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|