sisimai 5.0.3 → 5.2.0
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/codecovio.yml +3 -1
- data/.github/workflows/rake-test.yml +7 -3
- data/ChangeLog.md +136 -0
- data/Makefile +4 -2
- data/README-JA.md +32 -22
- data/README.md +31 -21
- data/lib/sisimai/arf.rb +124 -213
- data/lib/sisimai/fact/json.rb +2 -2
- data/lib/sisimai/fact/yaml.rb +2 -2
- data/lib/sisimai/fact.rb +208 -173
- data/lib/sisimai/lda.rb +98 -0
- data/lib/sisimai/lhost/activehunter.rb +5 -4
- data/lib/sisimai/lhost/amazonses.rb +189 -305
- data/lib/sisimai/lhost/apachejames.rb +52 -55
- data/lib/sisimai/lhost/biglobe.rb +5 -6
- data/lib/sisimai/lhost/courier.rb +14 -12
- data/lib/sisimai/lhost/domino.rb +29 -29
- data/lib/sisimai/lhost/dragonfly.rb +113 -0
- data/lib/sisimai/lhost/einsundeins.rb +7 -8
- data/lib/sisimai/lhost/exchange2003.rb +10 -11
- data/lib/sisimai/lhost/exchange2007.rb +115 -104
- data/lib/sisimai/lhost/exim.rb +236 -246
- data/lib/sisimai/lhost/ezweb.rb +47 -55
- data/lib/sisimai/lhost/fml.rb +6 -7
- data/lib/sisimai/lhost/gmail.rb +36 -32
- data/lib/sisimai/lhost/gmx.rb +8 -20
- data/lib/sisimai/lhost/googlegroups.rb +13 -12
- data/lib/sisimai/lhost/googleworkspace.rb +94 -0
- data/lib/sisimai/lhost/imailserver.rb +11 -19
- data/lib/sisimai/lhost/interscanmss.rb +6 -5
- data/lib/sisimai/lhost/kddi.rb +7 -8
- data/lib/sisimai/lhost/mailfoundry.rb +6 -9
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +6 -6
- data/lib/sisimai/lhost/messagingserver.rb +19 -17
- data/lib/sisimai/lhost/mfilter.rb +8 -7
- data/lib/sisimai/lhost/notes.rb +6 -8
- data/lib/sisimai/lhost/opensmtpd.rb +11 -9
- data/lib/sisimai/lhost/postfix.rb +29 -31
- data/lib/sisimai/lhost/qmail.rb +136 -112
- data/lib/sisimai/lhost/sendmail.rb +23 -22
- data/lib/sisimai/lhost/v5sendmail.rb +93 -64
- data/lib/sisimai/lhost/verizon.rb +6 -6
- data/lib/sisimai/lhost/x1.rb +4 -4
- data/lib/sisimai/lhost/x2.rb +4 -5
- data/lib/sisimai/lhost/x3.rb +5 -5
- data/lib/sisimai/lhost/x6.rb +4 -4
- data/lib/sisimai/lhost/zoho.rb +6 -6
- data/lib/sisimai/lhost.rb +21 -24
- data/lib/sisimai/mail/maildir.rb +1 -1
- data/lib/sisimai/mail/stdin.rb +1 -1
- data/lib/sisimai/message.rb +100 -153
- data/lib/sisimai/order.rb +22 -77
- data/lib/sisimai/reason/authfailure.rb +1 -4
- data/lib/sisimai/reason/badreputation.rb +3 -3
- 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 +3 -3
- data/lib/sisimai/reason/notaccept.rb +2 -3
- data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
- data/lib/sisimai/reason/rejected.rb +2 -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 +82 -78
- 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 +224 -345
- data/lib/sisimai/rfc3834.rb +3 -3
- 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 +95 -0
- data/lib/sisimai/rhost/cox.rb +84 -34
- data/lib/sisimai/rhost/facebook.rb +100 -0
- data/lib/sisimai/rhost/franceptt.rb +87 -83
- data/lib/sisimai/rhost/godaddy.rb +208 -45
- data/lib/sisimai/rhost/google.rb +22 -22
- data/lib/sisimai/rhost/gsuite.rb +42 -0
- data/lib/sisimai/rhost/iua.rb +5 -5
- data/lib/sisimai/rhost/kddi.rb +9 -7
- data/lib/sisimai/rhost/messagelabs.rb +37 -0
- data/lib/sisimai/rhost/microsoft.rb +60 -54
- data/lib/sisimai/rhost/mimecast.rb +44 -31
- data/lib/sisimai/rhost/nttdocomo.rb +5 -4
- data/lib/sisimai/rhost/outlook.rb +36 -0
- data/lib/sisimai/rhost/spectrum.rb +102 -41
- data/lib/sisimai/rhost/tencent.rb +48 -26
- data/lib/sisimai/rhost/yahooinc.rb +111 -0
- data/lib/sisimai/rhost.rb +65 -42
- data/lib/sisimai/smtp/command.rb +31 -21
- data/lib/sisimai/smtp/failure.rb +103 -0
- data/lib/sisimai/smtp/reply.rb +29 -24
- data/lib/sisimai/smtp/status.rb +36 -19
- data/lib/sisimai/smtp/transcript.rb +18 -18
- data/lib/sisimai/string.rb +0 -46
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +0 -6
- data/set-of-emails/maildir/bsd/lhost-dragonfly-01.eml +36 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-02.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-03.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-04.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-05.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-06.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-07.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-08.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-09.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-10.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-11.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-12.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-13.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-14.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-15.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-16.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-17.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-18.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-19.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-20.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-21.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-22.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-23.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-24.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-25.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-26.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-27.eml +47 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-28.eml +47 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-29.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-30.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-10.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-11.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-12.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-13.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-14.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-15.eml +63 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-16.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-17.eml +63 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
- data/set-of-emails/maildir/bsd/lhost-qmail-11.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-12.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-13.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-14.eml +34 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-15.eml +30 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-16.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-17.eml +38 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-18.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-19.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-20.eml +46 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-21.eml +41 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-22.eml +42 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-23.eml +43 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-24.eml +43 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-25.eml +54 -0
- 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-apple-01.eml +79 -0
- data/set-of-emails/maildir/bsd/rhost-apple-02.eml +81 -0
- data/set-of-emails/maildir/bsd/rhost-apple-03.eml +75 -0
- data/set-of-emails/maildir/bsd/rhost-apple-04.eml +74 -0
- 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/bsd/rhost-yahooinc-01.eml +80 -0
- data/set-of-emails/maildir/bsd/rhost-yahooinc-02.eml +83 -0
- data/set-of-emails/maildir/bsd/rhost-yahooinc-03.eml +125 -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 +136 -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 -119
- 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
@@ -1,188 +0,0 @@
|
|
1
|
-
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Facebook parses a bounce email which created by Facebook. Methods in the module
|
3
|
-
# 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
|
-
# Parse bounce messages 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 parse 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
|
-
|
data/lib/sisimai/lhost/gsuite.rb
DELETED
@@ -1,194 +0,0 @@
|
|
1
|
-
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::GSuite parses a bounce email which created by G Suite. Methods in the module are
|
3
|
-
# called from only Sisimai::Message.
|
4
|
-
module GSuite
|
5
|
-
class << self
|
6
|
-
require 'sisimai/lhost'
|
7
|
-
|
8
|
-
Indicators = Sisimai::Lhost.INDICATORS
|
9
|
-
Boundaries = ['Content-Type: message/rfc822', 'Content-Type: text/rfc822-headers'].freeze
|
10
|
-
MarkingsOf = {
|
11
|
-
message: ['** '],
|
12
|
-
error: ['The response was:', 'The response from the remote server was:'],
|
13
|
-
}.freeze
|
14
|
-
MessagesOf = {
|
15
|
-
'userunknown' => ["because the address couldn't be found. Check for typos or unnecessary spaces and try again."],
|
16
|
-
'notaccept' => ['Null MX'],
|
17
|
-
'networkerror' => [' had no relevant answers.', ' responded with code NXDOMAIN'],
|
18
|
-
}.freeze
|
19
|
-
|
20
|
-
# Parse bounce messages from G Suite (Transfer from G Suite to a destinaion host)
|
21
|
-
# @param [Hash] mhead Message headers of a bounce email
|
22
|
-
# @param [String] mbody Message body of a bounce email
|
23
|
-
# @return [Hash] Bounce data list and message/rfc822 part
|
24
|
-
# @return [Nil] it failed to parse or the arguments are missing
|
25
|
-
def inquire(mhead, mbody)
|
26
|
-
return nil unless mhead['from'].end_with?('<mailer-daemon@googlemail.com>')
|
27
|
-
return nil unless mhead['subject'].start_with?('Delivery Status Notification')
|
28
|
-
return nil unless mhead['x-gm-message-state']
|
29
|
-
|
30
|
-
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
31
|
-
permessage = {} # (Hash) Store values of each Per-Message field
|
32
|
-
|
33
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
34
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
35
|
-
bodyslices = emailparts[0].split("\n")
|
36
|
-
readcursor = 0 # (Integer) Points the current cursor position
|
37
|
-
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
38
|
-
endoferror = false # (Integer) Flag for a blank line after error messages
|
39
|
-
anotherset = {} # (Hash) Another error information
|
40
|
-
emptylines = 0 # (Integer) The number of empty lines
|
41
|
-
v = nil
|
42
|
-
|
43
|
-
while e = bodyslices.shift do
|
44
|
-
# Read error messages and delivery status lines from the head of the email to the previous
|
45
|
-
# line of the beginning of the original message.
|
46
|
-
if readcursor == 0
|
47
|
-
# Beginning of the bounce message or message/delivery-status part
|
48
|
-
readcursor |= Indicators[:deliverystatus] if MarkingsOf[:message].any? { |a| e.start_with?(a) }
|
49
|
-
end
|
50
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
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
|
-
if fieldtable[o[0]] == 'lhost'
|
83
|
-
# Do not set an email address as a hostname in "lhost" value
|
84
|
-
v['lhost'] = '' if v['lhost'].include?('@')
|
85
|
-
end
|
86
|
-
|
87
|
-
next unless f
|
88
|
-
permessage[fieldtable[o[0]]] = o[2]
|
89
|
-
end
|
90
|
-
else
|
91
|
-
# The line does not begin with a DSN field defined in RFC3464 Append error messages continued
|
92
|
-
# from the previous line
|
93
|
-
if endoferror == false && v && ! v['diagnosis'].to_s.empty?
|
94
|
-
endoferror ||= true if e.empty?
|
95
|
-
|
96
|
-
next if endoferror
|
97
|
-
next unless e.start_with?(' ')
|
98
|
-
v['diagnosis'] << e
|
99
|
-
|
100
|
-
elsif MarkingsOf[:error].any? { |a| e.start_with?(a) }
|
101
|
-
# Detect SMTP session error or connection error
|
102
|
-
# The response from the remote server was:
|
103
|
-
anotherset['diagnosis'] << ' ' << e
|
104
|
-
else
|
105
|
-
# ** Address not found **
|
106
|
-
#
|
107
|
-
# Your message wasn't delivered to * because the address couldn't be found.
|
108
|
-
# Check for typos or unnecessary spaces and try again.
|
109
|
-
#
|
110
|
-
# The response from the remote server was:
|
111
|
-
# 550 #5.1.0 Address rejected.
|
112
|
-
next if e.start_with?('Content-Type:')
|
113
|
-
if anotherset['diagnosis']
|
114
|
-
# Continued error messages from the previous line like "550 #5.1.0 Address rejected."
|
115
|
-
next if emptylines > 5
|
116
|
-
if e.empty?
|
117
|
-
# Count and next()
|
118
|
-
emptylines += 1
|
119
|
-
next
|
120
|
-
end
|
121
|
-
anotherset['diagnosis'] << ' ' << e
|
122
|
-
else
|
123
|
-
# ** Address not found **
|
124
|
-
#
|
125
|
-
# Your message wasn't delivered to * because the address couldn't be found.
|
126
|
-
# Check for typos or unnecessary spaces and try again.
|
127
|
-
next if e.empty?
|
128
|
-
next unless MarkingsOf[:message].any? { |a| e.start_with?(a) }
|
129
|
-
anotherset['diagnosis'] = e
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
return nil unless recipients > 0
|
135
|
-
|
136
|
-
dscontents.each do |e|
|
137
|
-
# Set default values if each value is empty.
|
138
|
-
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
139
|
-
|
140
|
-
if anotherset['diagnosis']
|
141
|
-
# Copy alternative error message
|
142
|
-
e['diagnosis'] = anotherset['diagnosis'] unless e['diagnosis']
|
143
|
-
|
144
|
-
if e['diagnosis'].include?(' ') == false && e['diagnosis'].to_i > 0
|
145
|
-
e['diagnosis'] = anotherset['diagnosis']
|
146
|
-
else
|
147
|
-
# More detailed error message is in "anotherset"
|
148
|
-
as = nil # status
|
149
|
-
ar = nil # replycode
|
150
|
-
|
151
|
-
e['status'] ||= ''
|
152
|
-
e['replycode'] ||= ''
|
153
|
-
|
154
|
-
if e['status'] == '' || e['status'].start_with?('4.0.0', '5.0.0')
|
155
|
-
# Check the value of D.S.N. in anotherset
|
156
|
-
as = Sisimai::SMTP::Status.find(anotherset['diagnosis'])
|
157
|
-
if as && as[-3, 3] != '0.0'
|
158
|
-
# The D.S.N. is neither an empty nor *.0.0
|
159
|
-
e['status'] = as
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
if e['replycode'].empty? || e['replycode'].start_with?('400', '500')
|
164
|
-
# Check the value of SMTP reply code in anotherset
|
165
|
-
ar = Sisimai::SMTP::Reply.find(anotherset['diagnosis'])
|
166
|
-
if ar && ar[-2, 2].to_i != 0
|
167
|
-
# The SMTP reply code is neither an empty nor *00
|
168
|
-
e['replycode'] = ar
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
if (as || ar) && (anotherset['diagnosis'].size > e['diagnosis'].size)
|
173
|
-
# Update the error message in e['diagnosis']
|
174
|
-
e['diagnosis'] = anotherset['diagnosis']
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
180
|
-
MessagesOf.each_key do |r|
|
181
|
-
# Guess an reason of the bounce
|
182
|
-
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
183
|
-
e['reason'] = r
|
184
|
-
break
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
189
|
-
end
|
190
|
-
def description; return 'G Suite: https://gsuite.google.com'; end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
data/lib/sisimai/lhost/mailru.rb
DELETED
@@ -1,214 +0,0 @@
|
|
1
|
-
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::MailRu parses a bounce email which created by @mail.ru. Methods in the module are
|
3
|
-
# called from only Sisimai::Message.
|
4
|
-
module MailRu
|
5
|
-
class << self
|
6
|
-
# Based on Sisimai::Lhost::Exim
|
7
|
-
require 'sisimai/lhost'
|
8
|
-
|
9
|
-
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
-
Boundaries = ['------ This is a copy of the message, including all the headers. ------'].freeze
|
11
|
-
StartingOf = { message: ['This message was created automatically by mail delivery software.'] }.freeze
|
12
|
-
ReCommands = [
|
13
|
-
%r/SMTP error from remote (?:mail server|mailer) after ([A-Za-z]{4})/,
|
14
|
-
%r/SMTP error from remote (?:mail server|mailer) after end of ([A-Za-z]{4})/,
|
15
|
-
].freeze
|
16
|
-
MessagesOf = {
|
17
|
-
'expired' => [
|
18
|
-
'retry timeout exceeded',
|
19
|
-
'No action is required on your part',
|
20
|
-
],
|
21
|
-
'userunknown' => ['user not found'],
|
22
|
-
'hostunknown' => [
|
23
|
-
'all host address lookups failed permanently',
|
24
|
-
'all relevant MX records point to non-existent hosts',
|
25
|
-
'Unrouteable address',
|
26
|
-
],
|
27
|
-
'mailboxfull' => ['mailbox is full', 'error: quota exceed'],
|
28
|
-
'notaccept' => [
|
29
|
-
'an MX or SRV record indicated no SMTP service',
|
30
|
-
'no host found for existing SMTP connection',
|
31
|
-
],
|
32
|
-
'syntaxerror' => [
|
33
|
-
'angle-brackets nested too deep',
|
34
|
-
'expected word or "<"',
|
35
|
-
'domain missing in source-routed address',
|
36
|
-
'malformed address:',
|
37
|
-
],
|
38
|
-
'systemerror' => [
|
39
|
-
'delivery to file forbidden',
|
40
|
-
'delivery to pipe forbidden',
|
41
|
-
'local delivery failed',
|
42
|
-
'LMTP error after ',
|
43
|
-
],
|
44
|
-
'contenterror' => ['Too many "Received" headers'],
|
45
|
-
}.freeze
|
46
|
-
|
47
|
-
# Parse bounce messages from @mail.ru
|
48
|
-
# @param [Hash] mhead Message headers of a bounce email
|
49
|
-
# @param [String] mbody Message body of a bounce email
|
50
|
-
# @return [Hash] Bounce data list and message/rfc822 part
|
51
|
-
# @return [Nil] it failed to parse or the arguments are missing
|
52
|
-
def inquire(mhead, mbody)
|
53
|
-
mfrom = mhead['from'].downcase
|
54
|
-
msgid = mhead['message-id'] ? mhead['message-id'].downcase : ''
|
55
|
-
match = 0
|
56
|
-
match += 1 if mfrom.include?('mailer-daemon@') && mfrom.include?('mail.ru')
|
57
|
-
match += 1 if msgid.end_with?('.mail.ru>', 'smailru.net>')
|
58
|
-
match += 1 if [
|
59
|
-
'Delivery Status Notification',
|
60
|
-
'Mail delivery failed',
|
61
|
-
'Mail failure',
|
62
|
-
'Message frozen',
|
63
|
-
'Warning: message ',
|
64
|
-
'error(s) in forwarding or filtering'].any? { |a| mhead['subject'].include?(a) }
|
65
|
-
return nil unless match > 2
|
66
|
-
|
67
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
68
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
69
|
-
bodyslices = emailparts[0].split("\n")
|
70
|
-
readcursor = 0 # (Integer) Points the current cursor position
|
71
|
-
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
72
|
-
v = nil
|
73
|
-
|
74
|
-
while e = bodyslices.shift do
|
75
|
-
# Read error messages and delivery status lines from the head of the email to the previous
|
76
|
-
# line of the beginning of the original message.
|
77
|
-
if readcursor == 0
|
78
|
-
# Beginning of the bounce message or delivery status part
|
79
|
-
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
80
|
-
next
|
81
|
-
end
|
82
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
83
|
-
next if e.empty?
|
84
|
-
|
85
|
-
# Это письмо создано автоматически
|
86
|
-
# сервером Mail.Ru, # отвечать на него не
|
87
|
-
# нужно.
|
88
|
-
#
|
89
|
-
# К сожалению, Ваше письмо не может
|
90
|
-
# быть# доставлено одному или нескольким
|
91
|
-
# получателям:
|
92
|
-
#
|
93
|
-
# **********************
|
94
|
-
#
|
95
|
-
# This message was created automatically by mail delivery software.
|
96
|
-
#
|
97
|
-
# A message that you sent could not be delivered to one or more of its
|
98
|
-
# recipients. This is a permanent error. The following address(es) failed:
|
99
|
-
#
|
100
|
-
# kijitora@example.jp
|
101
|
-
# SMTP error from remote mail server after RCPT TO:<kijitora@example.jp>:
|
102
|
-
# host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
|
103
|
-
v = dscontents[-1]
|
104
|
-
|
105
|
-
if e.start_with?(' ') && e.include?(' ') == false && e.index('@') > 1
|
106
|
-
# kijitora@example.jp
|
107
|
-
if v['recipient']
|
108
|
-
# There are multiple recipient addresses in the message body.
|
109
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
110
|
-
v = dscontents[-1]
|
111
|
-
end
|
112
|
-
v['recipient'] = e[2, e.size]
|
113
|
-
recipients += 1
|
114
|
-
|
115
|
-
elsif dscontents.size == recipients
|
116
|
-
# Error message
|
117
|
-
next if e.empty?
|
118
|
-
v['diagnosis'] ||= ''
|
119
|
-
v['diagnosis'] << e + ' '
|
120
|
-
else
|
121
|
-
# Error message when email address above does not include '@'
|
122
|
-
# and domain part.
|
123
|
-
next unless e.start_with?(' ')
|
124
|
-
v['alterrors'] ||= ''
|
125
|
-
v['alterrors'] << e + ' '
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
unless recipients > 0
|
130
|
-
# Fallback for getting recipient addresses
|
131
|
-
if mhead['x-failed-recipients']
|
132
|
-
# X-Failed-Recipients: kijitora@example.jp
|
133
|
-
rcptinhead = mhead['x-failed-recipients'].split(',')
|
134
|
-
rcptinhead.each { |a| a.delete(' ') }
|
135
|
-
recipients = rcptinhead.size
|
136
|
-
|
137
|
-
while e = rcptinhead.shift do
|
138
|
-
# Insert each recipient address into dscontents
|
139
|
-
dscontents[-1]['recipient'] = e
|
140
|
-
next if dscontents.size == recipients
|
141
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
return nil unless recipients > 0
|
146
|
-
|
147
|
-
# Get the name of the local MTA
|
148
|
-
# Received: from marutamachi.example.org (c192128.example.net [192.0.2.128])
|
149
|
-
receivedby = mhead['received'] || []
|
150
|
-
recvdtoken = Sisimai::RFC5322.received(receivedby[-1])
|
151
|
-
|
152
|
-
dscontents.each do |e|
|
153
|
-
# Check the error message, the rhost, the lhost, and the smtp command.
|
154
|
-
unless e['alterrors'].to_s.empty?
|
155
|
-
# Copy alternative error message
|
156
|
-
e['diagnosis'] ||= e['alterrors']
|
157
|
-
if e['diagnosis'].start_with?('-') || e['diagnosis'].end_with?('__')
|
158
|
-
# Override the value of diagnostic code message
|
159
|
-
e['diagnosis'] = e['alterrors'] unless e['alterrors'].empty?
|
160
|
-
end
|
161
|
-
e.delete('alterrors')
|
162
|
-
end
|
163
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
|
164
|
-
p1 = e['diagnosis'].rindex('__') || -1
|
165
|
-
e['diagnosis'] = e['diagnosis'][0, p1 - 1] if p1 > 2
|
166
|
-
|
167
|
-
unless e['rhost']
|
168
|
-
# Get the remote host name
|
169
|
-
# host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
|
170
|
-
p1 = e['diagnosis'].index('host ') || -1
|
171
|
-
p2 = e['diagnosis'].index(' ', p1 + 5) || -1
|
172
|
-
e['rhost'] = e['diagnosis'][p1 + 5, p2 - p1 - 5] if p1 > -1
|
173
|
-
e['rhost'] ||= recvdtoken[1]
|
174
|
-
end
|
175
|
-
e['lhost'] ||= recvdtoken[0]
|
176
|
-
|
177
|
-
unless e['command']
|
178
|
-
# Get the SMTP command name for the session
|
179
|
-
ReCommands.each do |r|
|
180
|
-
# Verify each regular expression of SMTP commands
|
181
|
-
if cv = e['diagnosis'].match(r)
|
182
|
-
e['command'] = cv[1].upcase
|
183
|
-
break
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
# Detect the reason of bounce
|
188
|
-
if %w[HELO EHLO].index(e['command'])
|
189
|
-
# HELO | Connected to 192.0.2.135 but my name was rejected.
|
190
|
-
e['reason'] = 'blocked'
|
191
|
-
|
192
|
-
elsif e['command'] == 'MAIL'
|
193
|
-
# MAIL | Connected to 192.0.2.135 but sender was rejected.
|
194
|
-
e['reason'] = 'rejected'
|
195
|
-
else
|
196
|
-
# Verify each regular expression of session errors
|
197
|
-
MessagesOf.each_key do |r|
|
198
|
-
# Check each regular expression
|
199
|
-
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
200
|
-
e['reason'] = r
|
201
|
-
break
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
e['command'] ||= ''
|
206
|
-
end
|
207
|
-
|
208
|
-
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
209
|
-
end
|
210
|
-
def description; return '@mail.ru: https://mail.ru'; end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|