sisimai 4.24.1-java → 4.25.0-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sisimai might be problematic. Click here for more details.

Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -2
  3. data/ANALYTICAL-PRECISION +16 -25
  4. data/ChangeLog.md +41 -0
  5. data/Developers.mk +2 -2
  6. data/README-JA.md +13 -13
  7. data/README.md +13 -13
  8. data/lib/sisimai.rb +3 -7
  9. data/lib/sisimai/address.rb +25 -41
  10. data/lib/sisimai/arf.rb +58 -59
  11. data/lib/sisimai/bite.rb +0 -1
  12. data/lib/sisimai/bite/email.rb +7 -7
  13. data/lib/sisimai/bite/email/activehunter.rb +4 -3
  14. data/lib/sisimai/bite/email/amavis.rb +133 -0
  15. data/lib/sisimai/bite/email/amazonses.rb +53 -87
  16. data/lib/sisimai/bite/email/amazonworkmail.rb +51 -57
  17. data/lib/sisimai/bite/email/aol.rb +50 -76
  18. data/lib/sisimai/bite/email/apachejames.rb +2 -2
  19. data/lib/sisimai/bite/email/bigfoot.rb +47 -74
  20. data/lib/sisimai/bite/email/biglobe.rb +8 -9
  21. data/lib/sisimai/bite/email/courier.rb +56 -101
  22. data/lib/sisimai/bite/email/domino.rb +7 -8
  23. data/lib/sisimai/bite/email/einsundeins.rb +4 -5
  24. data/lib/sisimai/bite/email/exchange2003.rb +21 -22
  25. data/lib/sisimai/bite/email/exchange2007.rb +26 -28
  26. data/lib/sisimai/bite/email/exim.rb +48 -47
  27. data/lib/sisimai/bite/email/ezweb.rb +24 -36
  28. data/lib/sisimai/bite/email/facebook.rb +54 -79
  29. data/lib/sisimai/bite/email/fml.rb +10 -10
  30. data/lib/sisimai/bite/email/gmx.rb +6 -6
  31. data/lib/sisimai/bite/email/google.rb +12 -13
  32. data/lib/sisimai/bite/email/gsuite.rb +80 -108
  33. data/lib/sisimai/bite/email/imailserver.rb +16 -16
  34. data/lib/sisimai/bite/email/interscanmss.rb +4 -6
  35. data/lib/sisimai/bite/email/kddi.rb +9 -11
  36. data/lib/sisimai/bite/email/mailfoundry.rb +2 -2
  37. data/lib/sisimai/bite/email/mailmarshalsmtp.rb +2 -2
  38. data/lib/sisimai/bite/email/mailru.rb +12 -13
  39. data/lib/sisimai/bite/email/mcafee.rb +31 -25
  40. data/lib/sisimai/bite/email/messagelabs.rb +48 -87
  41. data/lib/sisimai/bite/email/messagingserver.rb +9 -10
  42. data/lib/sisimai/bite/email/mfilter.rb +16 -16
  43. data/lib/sisimai/bite/email/mxlogic.rb +11 -11
  44. data/lib/sisimai/bite/email/notes.rb +5 -6
  45. data/lib/sisimai/bite/email/office365.rb +25 -42
  46. data/lib/sisimai/bite/email/opensmtpd.rb +8 -8
  47. data/lib/sisimai/bite/email/outlook.rb +49 -67
  48. data/lib/sisimai/bite/email/postfix.rb +78 -112
  49. data/lib/sisimai/bite/email/qmail.rb +23 -23
  50. data/lib/sisimai/bite/email/receivingses.rb +53 -86
  51. data/lib/sisimai/bite/email/sendgrid.rb +65 -84
  52. data/lib/sisimai/bite/email/sendmail.rb +89 -117
  53. data/lib/sisimai/bite/email/surfcontrol.rb +15 -18
  54. data/lib/sisimai/bite/email/userdefined.rb +1 -1
  55. data/lib/sisimai/bite/email/v5sendmail.rb +3 -4
  56. data/lib/sisimai/bite/email/verizon.rb +7 -8
  57. data/lib/sisimai/bite/email/x1.rb +2 -2
  58. data/lib/sisimai/bite/email/x2.rb +2 -2
  59. data/lib/sisimai/bite/email/x3.rb +3 -3
  60. data/lib/sisimai/bite/email/x4.rb +22 -22
  61. data/lib/sisimai/bite/email/x5.rb +40 -49
  62. data/lib/sisimai/bite/email/yahoo.rb +3 -3
  63. data/lib/sisimai/bite/email/yandex.rb +54 -82
  64. data/lib/sisimai/bite/email/zoho.rb +6 -6
  65. data/lib/sisimai/bite/json/amazonses.rb +20 -20
  66. data/lib/sisimai/bite/json/sendgrid.rb +2 -2
  67. data/lib/sisimai/data.rb +27 -40
  68. data/lib/sisimai/datetime.rb +146 -162
  69. data/lib/sisimai/mda.rb +30 -31
  70. data/lib/sisimai/message/email.rb +83 -123
  71. data/lib/sisimai/message/json.rb +2 -4
  72. data/lib/sisimai/mime.rb +31 -34
  73. data/lib/sisimai/order/email.rb +23 -22
  74. data/lib/sisimai/reason.rb +61 -61
  75. data/lib/sisimai/reason/blocked.rb +139 -135
  76. data/lib/sisimai/reason/contenterror.rb +11 -10
  77. data/lib/sisimai/reason/exceedlimit.rb +4 -4
  78. data/lib/sisimai/reason/expired.rb +20 -20
  79. data/lib/sisimai/reason/filtered.rb +19 -18
  80. data/lib/sisimai/reason/hasmoved.rb +3 -3
  81. data/lib/sisimai/reason/hostunknown.rb +19 -19
  82. data/lib/sisimai/reason/mailboxfull.rb +49 -49
  83. data/lib/sisimai/reason/mailererror.rb +16 -16
  84. data/lib/sisimai/reason/mesgtoobig.rb +17 -17
  85. data/lib/sisimai/reason/networkerror.rb +19 -19
  86. data/lib/sisimai/reason/norelaying.rb +16 -16
  87. data/lib/sisimai/reason/notaccept.rb +9 -10
  88. data/lib/sisimai/reason/onhold.rb +1 -1
  89. data/lib/sisimai/reason/policyviolation.rb +21 -20
  90. data/lib/sisimai/reason/rejected.rb +53 -53
  91. data/lib/sisimai/reason/securityerror.rb +29 -29
  92. data/lib/sisimai/reason/spamdetected.rb +127 -127
  93. data/lib/sisimai/reason/suspend.rb +17 -17
  94. data/lib/sisimai/reason/systemerror.rb +22 -21
  95. data/lib/sisimai/reason/systemfull.rb +6 -6
  96. data/lib/sisimai/reason/toomanyconn.rb +19 -18
  97. data/lib/sisimai/reason/userunknown.rb +122 -121
  98. data/lib/sisimai/reason/vacation.rb +8 -8
  99. data/lib/sisimai/reason/virusdetected.rb +8 -8
  100. data/lib/sisimai/rfc1894.rb +142 -0
  101. data/lib/sisimai/rfc3464.rb +70 -70
  102. data/lib/sisimai/rfc3834.rb +15 -15
  103. data/lib/sisimai/rfc5322.rb +20 -36
  104. data/lib/sisimai/rhost.rb +1 -0
  105. data/lib/sisimai/rhost/exchangeonline.rb +31 -33
  106. data/lib/sisimai/rhost/franceptt.rb +23 -23
  107. data/lib/sisimai/rhost/godaddy.rb +28 -28
  108. data/lib/sisimai/rhost/googleapps.rb +39 -41
  109. data/lib/sisimai/rhost/kddi.rb +3 -3
  110. data/lib/sisimai/rhost/tencentqq.rb +51 -0
  111. data/lib/sisimai/smtp/error.rb +14 -21
  112. data/lib/sisimai/smtp/reply.rb +14 -13
  113. data/lib/sisimai/smtp/status.rb +178 -179
  114. data/lib/sisimai/string.rb +13 -12
  115. data/lib/sisimai/version.rb +1 -1
  116. data/set-of-emails/README.md +1 -5
  117. data/set-of-emails/maildir/bsd/arf-23.eml +49 -0
  118. data/set-of-emails/maildir/bsd/email-amavis-01.eml +78 -0
  119. data/set-of-emails/maildir/bsd/email-amavis-02.eml +78 -0
  120. data/set-of-emails/maildir/bsd/email-exchange2007-04.eml +146 -0
  121. data/set-of-emails/maildir/bsd/email-exim-60.eml +94 -0
  122. data/set-of-emails/maildir/bsd/email-ezweb-08.eml +49 -0
  123. data/set-of-emails/maildir/bsd/email-google-19.eml +67 -0
  124. data/set-of-emails/maildir/bsd/email-mcafee-05.eml +74 -0
  125. data/set-of-emails/maildir/bsd/email-messagingserver-12.eml +99 -0
  126. data/set-of-emails/maildir/bsd/email-postfix-46.eml +81 -0
  127. data/set-of-emails/maildir/bsd/email-postfix-47.eml +79 -0
  128. data/set-of-emails/maildir/bsd/email-postfix-48.eml +79 -0
  129. data/set-of-emails/maildir/bsd/email-postfix-49.eml +141 -0
  130. data/set-of-emails/maildir/bsd/email-postfix-50.eml +143 -0
  131. data/set-of-emails/maildir/bsd/email-postfix-51.eml +73 -0
  132. data/set-of-emails/maildir/bsd/email-postfix-52.eml +79 -0
  133. data/set-of-emails/maildir/bsd/email-postfix-53.eml +76 -0
  134. data/set-of-emails/maildir/bsd/email-postfix-54.eml +73 -0
  135. data/set-of-emails/maildir/bsd/email-postfix-55.eml +74 -0
  136. data/set-of-emails/maildir/bsd/email-postfix-56.eml +78 -0
  137. data/set-of-emails/maildir/bsd/email-qmail-10.eml +50 -0
  138. data/set-of-emails/maildir/bsd/email-x2-05.eml +38 -0
  139. data/set-of-emails/maildir/bsd/rhost-google-apps-02.eml +88 -0
  140. data/set-of-emails/maildir/bsd/rhost-tencentqq-01.eml +84 -0
  141. data/set-of-emails/maildir/bsd/rhost-tencentqq-02.eml +84 -0
  142. data/set-of-emails/maildir/bsd/rhost-tencentqq-03.eml +81 -0
  143. data/set-of-emails/maildir/dos/email-amavis-01.eml +78 -0
  144. data/set-of-emails/maildir/dos/email-apachejames-01.eml +1 -2
  145. data/set-of-emails/maildir/dos/email-messagelabs-01.eml +67 -50
  146. data/set-of-emails/maildir/dos/email-x4-01.eml +31 -76
  147. data/set-of-emails/maildir/dos/rhost-tencentqq-01.eml +84 -0
  148. data/set-of-emails/maildir/mac/email-amavis-01.eml +1 -4
  149. data/set-of-emails/maildir/mac/email-apachejames-01.eml +1 -9
  150. data/set-of-emails/maildir/mac/email-messagelabs-01.eml +1 -9
  151. data/set-of-emails/maildir/mac/email-x4-01.eml +1 -5
  152. data/set-of-emails/maildir/mac/rhost-tencentqq-01.eml +1 -4
  153. metadata +35 -4
  154. data/set-of-emails/logo/horizontalversions.png +0 -0
  155. data/set-of-emails/logo/icon.png +0 -0
@@ -19,7 +19,7 @@ module Sisimai::Bite::Email
19
19
  # X-YMail-JAS: Pb65aU4VM1mei...
20
20
  # X-YMail-OSG: bTIbpDEVM1lHz...
21
21
  # X-Originating-IP: [192.0.2.9]
22
- def headerlist; return ['X-YMailISG']; end
22
+ def headerlist; return %w[x-ymailisg]; end
23
23
 
24
24
  # Parse bounce messages from Yahoo! MAIL
25
25
  # @param [Hash] mhead Message headers of a bounce email
@@ -62,7 +62,7 @@ module Sisimai::Bite::Email
62
62
  end
63
63
 
64
64
  if readcursor & Indicators[:'message-rfc822'] > 0
65
- # After "message/rfc822"
65
+ # Inside of the original message part
66
66
  if e.empty?
67
67
  blanklines += 1
68
68
  break if blanklines > 1
@@ -70,7 +70,7 @@ module Sisimai::Bite::Email
70
70
  end
71
71
  rfc822list << e
72
72
  else
73
- # Before "message/rfc822"
73
+ # Error message part
74
74
  next if (readcursor & Indicators[:deliverystatus]) == 0
75
75
  next if e.empty?
76
76
 
@@ -22,7 +22,7 @@ module Sisimai::Bite::Email
22
22
  # X-Yandex-Forward: 10104c00ad0726da5f37374723b1e0c8
23
23
  # X-Yandex-Queue-ID: 367D79E130D
24
24
  # X-Yandex-Sender: rfc822; shironeko@yandex.example.com
25
- def headerlist; return ['X-Yandex-Uniq']; end
25
+ def headerlist; return %w[x-yandex-uniq]; end
26
26
 
27
27
  # Parse bounce messages from Yandex.Mail
28
28
  # @param [Hash] mhead Message headers of a bounce email
@@ -39,6 +39,10 @@ module Sisimai::Bite::Email
39
39
  return nil unless mhead['x-yandex-uniq']
40
40
  return nil unless mhead['from'] == 'mailer-daemon@yandex.ru'
41
41
 
42
+ require 'sisimai/rfc1894'
43
+ fieldtable = Sisimai::RFC1894.FIELDTABLE
44
+ permessage = {} # (Hash) Store values of each Per-Message field
45
+
42
46
  dscontents = [Sisimai::Bite.DELIVERYSTATUS]
43
47
  hasdivided = mbody.split("\n")
44
48
  havepassed = ['']
@@ -47,11 +51,6 @@ module Sisimai::Bite::Email
47
51
  readcursor = 0 # (Integer) Points the current cursor position
48
52
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
49
53
  commandset = [] # (Array) ``in reply to * command'' list
50
- connvalues = 0 # (Integer) Flag, 1 if all the value of connheader have been set
51
- connheader = {
52
- 'date' => '', # The value of Arrival-Date header
53
- 'lhost' => '', # The value of Reporting-MTA header
54
- }
55
54
  v = nil
56
55
 
57
56
  while e = hasdivided.shift do
@@ -60,7 +59,7 @@ module Sisimai::Bite::Email
60
59
  p = havepassed[-2]
61
60
 
62
61
  if readcursor == 0
63
- # Beginning of the bounce message or delivery status part
62
+ # Beginning of the bounce message or message/delivery-status part
64
63
  if e.start_with?(StartingOf[:message][0])
65
64
  readcursor |= Indicators[:deliverystatus]
66
65
  next
@@ -68,7 +67,7 @@ module Sisimai::Bite::Email
68
67
  end
69
68
 
70
69
  if (readcursor & Indicators[:'message-rfc822']) == 0
71
- # Beginning of the original message part
70
+ # Beginning of the original message part(message/rfc822)
72
71
  if e.start_with?(StartingOf[:rfc822][0])
73
72
  readcursor |= Indicators[:'message-rfc822']
74
73
  next
@@ -76,7 +75,7 @@ module Sisimai::Bite::Email
76
75
  end
77
76
 
78
77
  if readcursor & Indicators[:'message-rfc822'] > 0
79
- # After "message/rfc822"
78
+ # message/rfc822 OR text/rfc822-headers part
80
79
  if e.empty?
81
80
  blanklines += 1
82
81
  break if blanklines > 1
@@ -84,98 +83,71 @@ module Sisimai::Bite::Email
84
83
  end
85
84
  rfc822list << e
86
85
  else
87
- # Before "message/rfc822"
86
+ # message/delivery-status part
88
87
  next if (readcursor & Indicators[:deliverystatus]) == 0
89
88
  next if e.empty?
90
89
 
91
- if connvalues == connheader.keys.size
92
- # Final-Recipient: rfc822; kijitora@example.jp
93
- # Original-Recipient: rfc822;kijitora@example.jp
94
- # Action: failed
95
- # Status: 5.1.1
96
- # Remote-MTA: dns; mx.example.jp
97
- # Diagnostic-Code: smtp; 550 5.1.1 <kijitora@example.jp>... User Unknown
98
- #
99
- # --367D79E130D.1417885948/forward1h.mail.yandex.net
100
- # Content-Description: Undelivered Message
101
- # Content-Type: message/rfc822
90
+ if f = Sisimai::RFC1894.match(e)
91
+ # "e" matched with any field defined in RFC3464
92
+ next unless o = Sisimai::RFC1894.field(e)
102
93
  v = dscontents[-1]
103
94
 
104
- if cv = e.match(/\AFinal-Recipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
95
+ if o[-1] == 'addr'
105
96
  # Final-Recipient: rfc822; kijitora@example.jp
106
- if v['recipient']
107
- # There are multiple recipient addresses in the message body.
108
- dscontents << Sisimai::Bite.DELIVERYSTATUS
109
- v = dscontents[-1]
97
+ # X-Actual-Recipient: rfc822; kijitora@example.co.jp
98
+ if o[0] == 'final-recipient'
99
+ # Final-Recipient: rfc822; kijitora@example.jp
100
+ if v['recipient']
101
+ # There are multiple recipient addresses in the message body.
102
+ dscontents << Sisimai::Bite.DELIVERYSTATUS
103
+ v = dscontents[-1]
104
+ end
105
+ v['recipient'] = o[2]
106
+ recipients += 1
107
+ else
108
+ # X-Actual-Recipient: rfc822; kijitora@example.co.jp
109
+ v['alias'] = o[2]
110
110
  end
111
- v['recipient'] = cv[1]
112
- recipients += 1
113
-
114
- elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
115
- # Action: failed
116
- v['action'] = cv[1]
117
-
118
- elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
119
- # Status:5.2.0
120
- v['status'] = cv[1]
121
-
122
- elsif cv = e.match(/\ARemote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
123
- # Remote-MTA: DNS; mx.example.jp
124
- v['rhost'] = cv[1].downcase
111
+ elsif o[-1] == 'code'
112
+ # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
113
+ v['spec'] = o[1]
114
+ v['diagnosis'] = o[2]
125
115
  else
126
- # Get error message
127
- if cv = e.match(/\ADiagnostic-Code:[ ]*(.+?);[ ]*(.+)\z/)
128
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
129
- v['spec'] = cv[1].upcase
130
- v['diagnosis'] = cv[2]
131
-
132
- elsif p.start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
133
- # Continued line of the value of Diagnostic-Code header
134
- v['diagnosis'] << ' ' << cv[1]
135
- havepassed[-1] = 'Diagnostic-Code: ' << e
136
- end
116
+ # Other DSN fields defined in RFC3464
117
+ next unless fieldtable.key?(o[0])
118
+ v[fieldtable[o[0]]] = o[2]
119
+
120
+ next unless f == 1
121
+ permessage[fieldtable[o[0]]] = o[2]
137
122
  end
138
123
  else
139
- # Content-Type: message/delivery-status
140
- #
141
- # Reporting-MTA: dns; forward1h.mail.yandex.net
142
- # X-Yandex-Queue-ID: 367D79E130D
143
- # X-Yandex-Sender: rfc822; shironeko@yandex.example.com
144
- # Arrival-Date: Sat, 6 Dec 2014 20:12:27 +0300 (MSK)
145
- if cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
146
- # Reporting-MTA: dns; mx.example.jp
147
- next unless connheader['lhost'].empty?
148
- connheader['lhost'] = cv[1].downcase
149
- connvalues += 1
150
-
151
- elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
152
- # Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
153
- next unless connheader['date'].empty?
154
- connheader['date'] = cv[1]
155
- connvalues += 1
124
+ # The line does not begin with a DSN field defined in RFC3464
125
+ if cv = e.match(/[ \t][(]in reply to .*([A-Z]{4}).*/)
126
+ # 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
127
+ commandset << cv[1]
128
+
129
+ elsif cv = e.match(/([A-Z]{4})[ \t]*.*command[)]\z/)
130
+ # to MAIL command)
131
+ commandset << cv[1]
156
132
  else
157
- # <kijitora@example.jp>: host mx.example.jp[192.0.2.153] said: 550
158
- # 5.1.1 <kijitora@example.jp>... User Unknown (in reply to RCPT TO
159
- # command)
160
- if cv = e.match(/[ \t][(]in reply to .*([A-Z]{4}).*/)
161
- # 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
162
- commandset << cv[1]
163
-
164
- elsif cv = e.match(/([A-Z]{4})[ \t]*.*command[)]\z/)
165
- # to MAIL command)
166
- commandset << cv[1]
167
- end
133
+ # Continued line of the value of Diagnostic-Code field
134
+ next unless p.start_with?('Diagnostic-Code:')
135
+ next unless cv = e.match(/\A[ \t]+(.+)\z/)
136
+ v['diagnosis'] << ' ' << cv[1]
137
+ havepassed[-1] = 'Diagnostic-Code: ' << e
168
138
  end
169
139
  end
170
- end
140
+ end # End of message/delivery-status
171
141
  end
172
142
  return nil unless recipients > 0
173
143
 
174
144
  dscontents.each do |e|
175
145
  # Set default values if each value is empty.
176
- connheader.each_key { |a| e[a] ||= connheader[a] || '' }
146
+ e['lhost'] ||= permessage['rhost']
147
+ permessage.each_key { |a| e[a] ||= permessage[a] || '' }
148
+
177
149
  e['command'] = commandset.shift || ''
178
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].gsub(/\\n/, ''))
150
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
179
151
  e['agent'] = self.smtpagent
180
152
  end
181
153
 
@@ -11,7 +11,7 @@ module Sisimai::Bite::Email
11
11
  message: ['This message was created automatically by mail delivery'],
12
12
  rfc822: ['from mail.zoho.com by mx.zohomail.com'],
13
13
  }.freeze
14
- MessagesOf = { expired: ['Host not reachable'] }.freeze
14
+ MessagesOf = { 'expired' => ['Host not reachable'] }.freeze
15
15
 
16
16
  def description; return 'Zoho Mail: https://www.zoho.com'; end
17
17
  def smtpagent; return Sisimai::Bite.smtpagent(self); end
@@ -19,7 +19,7 @@ module Sisimai::Bite::Email
19
19
  # X-ZohoMail: Si CHF_MF_NL SS_10 UW48 UB48 FMWL UW48 UB48 SGR3_1_09124_42
20
20
  # X-Zoho-Virus-Status: 2
21
21
  # X-Mailer: Zoho Mail
22
- def headerlist; return ['X-ZohoMail']; end
22
+ def headerlist; return %w[x-zohomail]; end
23
23
 
24
24
  # Parse bounce messages from Zoho Mail
25
25
  # @param [Hash] mhead Message headers of a bounce email
@@ -69,7 +69,7 @@ module Sisimai::Bite::Email
69
69
  end
70
70
 
71
71
  if readcursor & Indicators[:'message-rfc822'] > 0
72
- # After "message/rfc822"
72
+ # Inside of the original message part
73
73
  if e.empty?
74
74
  blanklines += 1
75
75
  break if blanklines > 1
@@ -77,7 +77,7 @@ module Sisimai::Bite::Email
77
77
  end
78
78
  rfc822list << e
79
79
  else
80
- # Before "message/rfc822"
80
+ # Error message part
81
81
  next if (readcursor & Indicators[:deliverystatus]) == 0
82
82
  next if e.empty?
83
83
 
@@ -133,12 +133,12 @@ module Sisimai::Bite::Email
133
133
 
134
134
  dscontents.each do |e|
135
135
  e['agent'] = self.smtpagent
136
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].gsub(/\\n/, ' '))
136
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
137
137
 
138
138
  MessagesOf.each_key do |r|
139
139
  # Verify each regular expression of session errors
140
140
  next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
141
- e['reason'] = r.to_s
141
+ e['reason'] = r
142
142
  break
143
143
  end
144
144
  end
@@ -9,17 +9,17 @@ module Sisimai::Bite::JSON
9
9
 
10
10
  # https://docs.aws.amazon.com/en_us/ses/latest/DeveloperGuide/notification-contents.html
11
11
  BounceType = {
12
- :Permanent => {
13
- :General => '',
14
- :NoEmail => '',
15
- :Suppressed => '',
12
+ 'Permanent' => {
13
+ 'General' => '',
14
+ 'NoEmail' => '',
15
+ 'Suppressed' => '',
16
16
  },
17
- :Transient => {
18
- :General => '',
19
- :MailboxFull => 'mailboxfull',
20
- :MessageTooLarge => 'mesgtoobig',
21
- :ContentRejected => '',
22
- :AttachmentRejected => '',
17
+ 'Transient' => {
18
+ 'General' => '',
19
+ 'MailboxFull' => 'mailboxfull',
20
+ 'MessageTooLarge' => 'mesgtoobig',
21
+ 'ContentRejected' => '',
22
+ 'AttachmentRejected' => '',
23
23
  },
24
24
  }.freeze
25
25
 
@@ -54,12 +54,12 @@ module Sisimai::Bite::JSON
54
54
  break if e == '__END_OF_EMAIL_MESSAGE__'
55
55
 
56
56
  # The line starts with " ", continued from !\n.
57
- e = e.lstrip if foldedline
57
+ e.lstrip! if foldedline
58
58
  foldedline = false
59
59
 
60
60
  if e.end_with?('!')
61
61
  # ... long long line ...![\n]
62
- e = e.chomp('!')
62
+ e.chomp!('!')
63
63
  foldedline = true
64
64
  end
65
65
  jsonstring << e
@@ -107,15 +107,15 @@ module Sisimai::Bite::JSON
107
107
  rfc822head = {} # (Hash) Check flags for headers in RFC822 part
108
108
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
109
109
  labeltable = {
110
- :Bounce => 'bouncedRecipients',
111
- :Complaint => 'complainedRecipients',
110
+ 'Bounce' => 'bouncedRecipients',
111
+ 'Complaint' => 'complainedRecipients',
112
112
  }
113
113
  v = nil
114
114
 
115
115
  if %w[Bounce Complaint].index(argvs['notificationType'])
116
116
  # { "notificationType":"Bounce", "bounce": { "bounceType":"Permanent",...
117
117
  o = argvs[argvs['notificationType'].downcase].dup
118
- r = o[labeltable[argvs['notificationType'].to_sym]] || []
118
+ r = o[labeltable[argvs['notificationType']]] || []
119
119
 
120
120
  while e = r.shift do
121
121
  # 'bouncedRecipients' => [ { 'emailAddress' => 'bounce@si...' }, ... ]
@@ -152,13 +152,13 @@ module Sisimai::Bite::JSON
152
152
  # 'reportingMTA' => 'dsn; a27-23.smtp-out.us-west-2.amazonses.com',
153
153
  if cv = o['reportingMTA'].match(/\Adsn;[ ](.+)\z/) then v['lhost'] = cv[1] end
154
154
 
155
- if BounceType.key?(o['bounceType'].to_sym) &&
156
- BounceType[o['bounceType'].to_sym].key?(o['bounceSubType'].to_sym)
155
+ if BounceType.key?(o['bounceType']) &&
156
+ BounceType[o['bounceType']].key?(o['bounceSubType'])
157
157
  # 'bounce' => {
158
158
  # 'bounceType' => 'Permanent',
159
159
  # 'bounceSubType' => 'General'
160
160
  # },
161
- v['reason'] = BounceType[o['bounceType'].to_sym][o['bounceSubType'].to_sym]
161
+ v['reason'] = BounceType[o['bounceType']][o['bounceSubType']]
162
162
  end
163
163
  else
164
164
  # 'complainedRecipients' => [ {
@@ -197,8 +197,8 @@ module Sisimai::Bite::JSON
197
197
  v['recipient'] = e
198
198
  v['lhost'] = o['reportingMTA'] || ''
199
199
  v['diagnosis'] = o['smtpResponse'] || ''
200
- v['status'] = Sisimai::SMTP::Status.find(v['diagnosis'])
201
- v['replycode'] = Sisimai::SMTP::Reply.find(v['diagnosis'])
200
+ v['status'] = Sisimai::SMTP::Status.find(v['diagnosis']) || ''
201
+ v['replycode'] = Sisimai::SMTP::Reply.find(v['diagnosis']) || ''
202
202
  v['reason'] = 'delivered'
203
203
  v['action'] = 'deliverable'
204
204
 
@@ -103,8 +103,8 @@ module Sisimai::Bite::JSON
103
103
  v['status'] = statuscode
104
104
  end
105
105
 
106
- v['status'] ||= Sisimai::SMTP::Status.find(diagnostic)
107
- v['replycode'] ||= Sisimai::SMTP::Reply.find(diagnostic)
106
+ v['status'] ||= Sisimai::SMTP::Status.find(diagnostic) || ''
107
+ v['replycode'] ||= Sisimai::SMTP::Reply.find(diagnostic) || ''
108
108
  v['diagnosis'] = argvs['reason'] || ''
109
109
  v['agent'] = self.smtpagent
110
110
 
data/lib/sisimai/data.rb CHANGED
@@ -41,7 +41,6 @@ module Sisimai
41
41
  RetryIndex = Sisimai::Reason.retry
42
42
  RFC822Head = Sisimai::RFC5322.HEADERFIELDS(:all)
43
43
  AddrHeader = { addresser: RFC822Head[:addresser], recipient: RFC822Head[:recipient] }.freeze
44
- ActionHead = { failure: 'failed', expired: 'delayed' }.freeze
45
44
 
46
45
  # Constructor of Sisimai::Data
47
46
  # @param [Hash] argvs Data
@@ -79,7 +78,7 @@ module Sisimai
79
78
  @feedbacktype = argvs['feedbacktype'] || ''
80
79
  @action = argvs['action'] || ''
81
80
  @replycode = argvs['replycode'] || ''
82
- @replycode = Sisimai::SMTP::Reply.find(argvs['diagnosticcode']) if @replycode.empty?
81
+ @replycode = Sisimai::SMTP::Reply.find(argvs['diagnosticcode']).to_s if @replycode.empty?
83
82
  @softbounce = argvs['softbounce'] || ''
84
83
  end
85
84
 
@@ -154,11 +153,11 @@ module Sisimai
154
153
  # Detect email address from message/rfc822 part
155
154
  fieldorder[:addresser].each do |f|
156
155
  # Check each header in message/rfc822 part
157
- h = f.downcase
158
- next unless rfc822data.key?(h)
159
- next if rfc822data[h].empty?
156
+ next unless rfc822data.key?(f)
157
+ next unless rfc822data[f]
158
+ next if rfc822data[f].empty?
160
159
 
161
- j = Sisimai::Address.find(rfc822data[h]) || []
160
+ j = Sisimai::Address.find(rfc822data[f]) || []
162
161
  next if j.empty?
163
162
  p['addresser'] = j[0]
164
163
  break
@@ -183,8 +182,8 @@ module Sisimai
183
182
  # Date information did not exist in message/delivery-status part,...
184
183
  RFC822Head[:date].each do |f|
185
184
  # Get the value of Date header or other date related header.
186
- next unless rfc822data[f.downcase]
187
- datevalues << rfc822data[f.downcase]
185
+ next unless rfc822data[f]
186
+ datevalues << rfc822data[f]
188
187
  end
189
188
 
190
189
  # Set "date" getting from the value of "Date" in the bounce message
@@ -227,23 +226,25 @@ module Sisimai
227
226
  %w[rhost lhost].each do |v|
228
227
  p[v].delete!('[]()') # Remove square brackets and curly brackets from the host variable
229
228
  p[v].sub!(/\A.+=/, '') # Remove string before "="
230
- p[v].chomp!("\r") # Remove CR at the end of the value
229
+ p[v].chomp!("\r") if p[v].end_with?("\r") # Remove CR at the end of the value
231
230
 
232
231
  # Check space character in each value and get the first element
233
232
  p[v] = p[v].split(' ', 2).shift if p[v].include?(' ')
234
- p[v].chomp!('.') # Remove "." at the end of the value
233
+ p[v].chomp!('.') if p[v].end_with?('.') # Remove "." at the end of the value
235
234
  end
236
235
 
237
236
  # Subject: header of the original message
238
237
  p['subject'] = rfc822data['subject'] || ''
239
- p['subject'] = p['subject'].scrub('?').chomp("\r")
238
+ p['subject'].scrub!('?')
239
+ p['subject'].chomp!("\r") if p['subject'].end_with?("\r");
240
240
 
241
241
  # The value of "List-Id" header
242
242
  p['listid'] = rfc822data['list-id'] || ''
243
243
  unless p['listid'].empty?
244
244
  # Get the value of List-Id header like "List name <list-id@example.org>"
245
245
  if cv = p['listid'].match(/\A.*([<].+[>]).*\z/) then p['listid'] = cv[1] end
246
- p['listid'] = p['listid'].delete('<>').chomp("\r")
246
+ p['listid'].delete!('<>')
247
+ p['listid'].chomp!("\r") if p['listid'].end_with?("\r")
247
248
  p['listid'] = '' if p['listid'].include?(' ')
248
249
  end
249
250
 
@@ -266,13 +267,13 @@ module Sisimai
266
267
  vm = 0
267
268
  re = nil
268
269
 
269
- unless vs.empty?
270
+ if vs
270
271
  # How many times does the D.S.N. appeared
271
272
  vm += p['diagnosticcode'].scan(/\b#{vs}\b/).size
272
273
  p['deliverystatus'] = vs if vs =~ /\A[45][.][1-9][.][1-9]\z/
273
274
  end
274
275
 
275
- unless vr.empty?
276
+ if vr
276
277
  # How many times does the SMTP reply code appeared
277
278
  vm += p['diagnosticcode'].scan(/\b#{vr}\b/).size
278
279
  p['replycode'] ||= vr
@@ -292,26 +293,13 @@ module Sisimai
292
293
  end
293
294
  end
294
295
  p['diagnostictype'] ||= 'X-UNIX' if p['reason'] == 'mailererror'
295
- p['diagnostictype'] ||= 'SMTP' unless %w[feedback vacation].index(p['reason'])
296
+ p['diagnostictype'] ||= 'SMTP' unless %w[feedback vacation].include?(p['reason'])
296
297
 
297
298
  # Check the value of SMTP command
298
- p['smtpcommand'] = '' unless %w[EHLO HELO MAIL RCPT DATA QUIT].index(p['smtpcommand'])
299
-
300
- # Check the value of "action"
301
- if p['action'].size > 0
302
- # Action: expanded (to multi-recipient alias)
303
- if cv = p['action'].match(/\A(.+?) .+/) then p['action'] = cv[1] end
304
-
305
- unless %w[failed delayed delivered relayed expanded].index(p['action'])
306
- # The value of "action" is not in the following values:
307
- # "failed" / "delayed" / "delivered" / "relayed" / "expanded"
308
- ActionHead.each_key do |q|
309
- next unless p['action'] == q.to_s
310
- p['action'] = ActionHead[q]
311
- break
312
- end
313
- end
314
- else
299
+ p['smtpcommand'] = '' unless %w[EHLO HELO MAIL RCPT DATA QUIT].include?(p['smtpcommand'])
300
+
301
+ if p['action'].empty?
302
+ # Check the value of "action"
315
303
  if p['reason'] == 'expired'
316
304
  # Action: delayed
317
305
  p['action'] = 'delayed'
@@ -324,7 +312,7 @@ module Sisimai
324
312
  o = Sisimai::Data.new(p)
325
313
  next unless o.recipient
326
314
 
327
- if o.reason.empty? || RetryIndex.index(o.reason)
315
+ if o.reason.empty? || RetryIndex.key?(o.reason)
328
316
  # Decide the reason of email bounce
329
317
  r = ''
330
318
  r = Sisimai::Rhost.get(o) if Sisimai::Rhost.match(o.rhost) # Remote host dependent error
@@ -333,7 +321,7 @@ module Sisimai
333
321
  o.reason = r
334
322
  end
335
323
 
336
- if %w[delivered feedback vacation].index(o.reason)
324
+ if %w[delivered feedback vacation].include?(o.reason)
337
325
  # The value of reason is "vacation" or "feedback"
338
326
  o.softbounce = -1
339
327
  o.replycode = '' unless o.reason == 'delivered'
@@ -344,9 +332,8 @@ module Sisimai
344
332
 
345
333
  if o.softbounce.to_s.empty?
346
334
  # The value is not set yet
347
- textasargv = (p['deliverystatus'] + ' ' + p['diagnosticcode']).lstrip
348
- softorhard = Sisimai::SMTP::Error.soft_or_hard(o.reason, textasargv)
349
-
335
+ textasargv = (p['deliverystatus'] + ' ' + p['diagnosticcode']).lstrip
336
+ softorhard = Sisimai::SMTP::Error.soft_or_hard(o.reason, textasargv) || ''
350
337
  o.softbounce = if softorhard.size > 0
351
338
  # Returned value is "soft" or "hard"
352
339
  (softorhard == 'soft') ? 1 : 0
@@ -363,7 +350,7 @@ module Sisimai
363
350
  tmpfailure = getchecked.nil? ? false : (getchecked ? false : true)
364
351
  pseudocode = Sisimai::SMTP::Status.code(o.reason, tmpfailure)
365
352
 
366
- unless pseudocode.empty?
353
+ if pseudocode
367
354
  # Set the value of "deliverystatus" and "softbounce"
368
355
  o.deliverystatus = pseudocode
369
356
 
@@ -399,7 +386,7 @@ module Sisimai
399
386
  def damn
400
387
  data = {}
401
388
  @@rwaccessors.each do |e|
402
- next if %w[addresser recipient timestamp].index(e.to_s)
389
+ next if %w[addresser recipient timestamp].include?(e.to_s)
403
390
  data[e.to_s] = self.send(e) || ''
404
391
  end
405
392
  data['addresser'] = self.addresser.address
@@ -414,7 +401,7 @@ module Sisimai
414
401
  # @return [String, Nil] Dumped data or nil if the value of the first
415
402
  # argument is neither "json" nor "yaml"
416
403
  def dump(type = 'json')
417
- return nil unless %w[json yaml].index(type)
404
+ return nil unless %w[json yaml].include?(type)
418
405
  referclass = 'Sisimai::Data::' << type.upcase
419
406
 
420
407
  begin