sisimai 4.20.1 → 4.20.2

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -2
  3. data/Changes +11 -1
  4. data/README-JA.md +135 -202
  5. data/README.md +128 -192
  6. data/fig/sisimai-architecture.png +0 -0
  7. data/lib/sisimai.rb +5 -3
  8. data/lib/sisimai/arf.rb +2 -2
  9. data/lib/sisimai/ced/us/amazonses.rb +5 -5
  10. data/lib/sisimai/ced/us/sendgrid.rb +4 -4
  11. data/lib/sisimai/data.rb +1 -8
  12. data/lib/sisimai/data/json.rb +1 -1
  13. data/lib/sisimai/datetime.rb +1 -1
  14. data/lib/sisimai/mail/maildir.rb +3 -3
  15. data/lib/sisimai/mda.rb +2 -2
  16. data/lib/sisimai/message.rb +7 -3
  17. data/lib/sisimai/message/email.rb +8 -2
  18. data/lib/sisimai/mime.rb +2 -2
  19. data/lib/sisimai/msp/de/einsundeins.rb +2 -2
  20. data/lib/sisimai/msp/de/gmx.rb +2 -2
  21. data/lib/sisimai/msp/jp/biglobe.rb +2 -2
  22. data/lib/sisimai/msp/jp/ezweb.rb +2 -2
  23. data/lib/sisimai/msp/jp/kddi.rb +3 -3
  24. data/lib/sisimai/msp/ru/mailru.rb +3 -3
  25. data/lib/sisimai/msp/ru/yandex.rb +2 -2
  26. data/lib/sisimai/msp/uk/messagelabs.rb +2 -2
  27. data/lib/sisimai/msp/us/amazonses.rb +4 -5
  28. data/lib/sisimai/msp/us/amazonworkmail.rb +2 -2
  29. data/lib/sisimai/msp/us/aol.rb +2 -2
  30. data/lib/sisimai/msp/us/bigfoot.rb +3 -3
  31. data/lib/sisimai/msp/us/facebook.rb +2 -2
  32. data/lib/sisimai/msp/us/google.rb +2 -2
  33. data/lib/sisimai/msp/us/office365.rb +2 -3
  34. data/lib/sisimai/msp/us/outlook.rb +2 -2
  35. data/lib/sisimai/msp/us/receivingses.rb +2 -2
  36. data/lib/sisimai/msp/us/sendgrid.rb +2 -2
  37. data/lib/sisimai/msp/us/verizon.rb +3 -3
  38. data/lib/sisimai/msp/us/yahoo.rb +2 -2
  39. data/lib/sisimai/msp/us/zoho.rb +2 -2
  40. data/lib/sisimai/mta/activehunter.rb +2 -2
  41. data/lib/sisimai/mta/apachejames.rb +3 -3
  42. data/lib/sisimai/mta/courier.rb +3 -3
  43. data/lib/sisimai/mta/domino.rb +2 -2
  44. data/lib/sisimai/mta/exchange2003.rb +4 -4
  45. data/lib/sisimai/mta/exchange2007.rb +2 -2
  46. data/lib/sisimai/mta/exim.rb +8 -4
  47. data/lib/sisimai/mta/imailserver.rb +3 -3
  48. data/lib/sisimai/mta/interscanmss.rb +3 -3
  49. data/lib/sisimai/mta/mailfoundry.rb +2 -2
  50. data/lib/sisimai/mta/mailmarshalsmtp.rb +2 -2
  51. data/lib/sisimai/mta/mcafee.rb +2 -2
  52. data/lib/sisimai/mta/messagingserver.rb +3 -3
  53. data/lib/sisimai/mta/mfilter.rb +2 -2
  54. data/lib/sisimai/mta/mxlogic.rb +3 -3
  55. data/lib/sisimai/mta/notes.rb +3 -3
  56. data/lib/sisimai/mta/opensmtpd.rb +2 -2
  57. data/lib/sisimai/mta/postfix.rb +3 -3
  58. data/lib/sisimai/mta/qmail.rb +3 -3
  59. data/lib/sisimai/mta/sendmail.rb +2 -2
  60. data/lib/sisimai/mta/surfcontrol.rb +2 -2
  61. data/lib/sisimai/mta/userdefined.rb +3 -3
  62. data/lib/sisimai/mta/v5sendmail.rb +3 -3
  63. data/lib/sisimai/mta/x1.rb +2 -2
  64. data/lib/sisimai/mta/x2.rb +2 -2
  65. data/lib/sisimai/mta/x3.rb +2 -2
  66. data/lib/sisimai/mta/x4.rb +3 -3
  67. data/lib/sisimai/mta/x5.rb +3 -3
  68. data/lib/sisimai/reason/rejected.rb +1 -0
  69. data/lib/sisimai/reason/securityerror.rb +7 -2
  70. data/lib/sisimai/reason/toomanyconn.rb +4 -0
  71. data/lib/sisimai/rfc3464.rb +3 -3
  72. data/lib/sisimai/rfc3834.rb +2 -2
  73. data/lib/sisimai/rfc5322.rb +4 -4
  74. data/lib/sisimai/rhost.rb +0 -1
  75. data/lib/sisimai/rhost/exchangeonline.rb +2 -2
  76. data/lib/sisimai/smtp.rb +4 -4
  77. data/lib/sisimai/smtp/error.rb +7 -12
  78. data/lib/sisimai/smtp/reply.rb +1 -1
  79. data/lib/sisimai/string.rb +7 -7
  80. data/lib/sisimai/version.rb +1 -1
  81. data/set-of-emails/maildir/bsd/rfc3834-06.eml +56 -0
  82. metadata +5 -3
data/lib/sisimai/arf.rb CHANGED
@@ -128,7 +128,7 @@ module Sisimai
128
128
  # this specification is set to "1".
129
129
  #
130
130
  hasdivided.each do |e|
131
- if readcursor == 0
131
+ if readcursor.zero?
132
132
  # Beginning of the bounce message or delivery status part
133
133
  if e =~ Re1[:begin]
134
134
  readcursor |= Indicators[:deliverystatus]
@@ -267,7 +267,7 @@ module Sisimai
267
267
  commondata[:diagnosis] += ' ' + arfheaders[:authres]
268
268
  end
269
269
 
270
- if recipients == 0
270
+ if recipients.zero?
271
271
  # Insert pseudo recipient address when there is no valid recipient
272
272
  # address in the message.
273
273
  dscontents[-1]['recipient'] = Sisimai::Address.undisclosed(:r)
@@ -64,7 +64,7 @@ module Sisimai
64
64
 
65
65
  hasdivided.each do |e|
66
66
  # Find JSON string from the message body
67
- next if e.size == 0
67
+ next if e.size.zero?
68
68
  break if e =~ /\A[-]{2}\z/
69
69
  break if e == '__END_OF_EMAIL_MESSAGE__'
70
70
 
@@ -121,12 +121,12 @@ module Sisimai
121
121
  return nil unless argvs.key?('notificationType')
122
122
 
123
123
  require 'sisimai/rfc5322'
124
- dscontents = [Sisimai::CED.DELIVERYSTATUS];
124
+ dscontents = [Sisimai::CED.DELIVERYSTATUS]
125
125
  rfc822head = {} # (Hash) Check flags for headers in RFC822 part
126
126
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
127
127
  labeltable = {
128
- :Bounce => 'bouncedRecipients',
129
- :Complaint => 'complainedRecipients',
128
+ :Bounce => 'bouncedRecipients',
129
+ :Complaint => 'complainedRecipients',
130
130
  }
131
131
  v = nil
132
132
 
@@ -236,7 +236,7 @@ module Sisimai
236
236
  # or "Delivery".
237
237
  return nil
238
238
  end
239
- return nil if recipients == 0
239
+ return nil if recipients.zero?
240
240
 
241
241
  dscontents.each do |e|
242
242
  e['agent'] = Sisimai::CED::US::AmazonSES.smtpagent
@@ -65,16 +65,16 @@ module Sisimai
65
65
 
66
66
  # Generate pseudo message/rfc822 part
67
67
  rfc822head = {
68
- 'to' => argvs['email'],
69
- 'from' => Sisimai::Address.undisclosed('s'),
70
- 'date' => v['date'],
68
+ 'to' => argvs['email'],
69
+ 'from' => Sisimai::Address.undisclosed('s'),
70
+ 'date' => v['date'],
71
71
  }
72
72
  else
73
73
  # The value of $argvs->{'email'} does not seems to an email address
74
74
  return nil
75
75
  end
76
76
 
77
- return nil if recipients == 0
77
+ return nil if recipients.zero?
78
78
  return { 'ds' => dscontents, 'rfc822' => rfc822head }
79
79
  end
80
80
 
data/lib/sisimai/data.rb CHANGED
@@ -152,8 +152,6 @@ module Sisimai
152
152
 
153
153
  messageobj.ds.each do |e|
154
154
  # Create parameters for new() constructor.
155
- o = nil # Sisimai::Data Object
156
- r = nil # Reason text
157
155
  p = {
158
156
  'catch' => messageobj.catch || nil,
159
157
  'lhost' => e['lhost'] || '',
@@ -306,7 +304,7 @@ module Sisimai
306
304
  p['diagnostictype'] ||= 'X-UNIX'
307
305
  else
308
306
  unless p['reason'] =~ /\A(?:feedback|vacation)\z/
309
- p['diagnostictype'] ||= 'SMTP'
307
+ p['diagnostictype'] ||= 'SMTP'
310
308
  end
311
309
  end
312
310
 
@@ -362,7 +360,6 @@ module Sisimai
362
360
  # Bounce message which reason is "feedback" or "vacation" does
363
361
  # not have the value of "deliverystatus".
364
362
  softorhard = nil
365
- textasargv = nil
366
363
 
367
364
  if o.softbounce.to_s.empty?
368
365
  # The value is not set yet
@@ -381,10 +378,6 @@ module Sisimai
381
378
 
382
379
  if o.deliverystatus.empty?
383
380
  # Set pseudo status code
384
- pseudocode = nil # Pseudo delivery status code
385
- getchecked = nil # Permanent error or not
386
- tmpfailure = nil # Temporary error or not
387
-
388
381
  textasargv = sprintf('%s %s', o.replycode, p['diagnosticcode'])
389
382
  textasargv = textasargv.gsub(/\A[ ]/, '')
390
383
 
@@ -27,7 +27,7 @@ module Sisimai
27
27
  require 'oj'
28
28
  jsonstring = Oj.dump(argvs.damn, :mode => :compat)
29
29
  rescue StandardError => ce
30
- warn '***warning: Failed to Oj.dump: ' + ce_to_s
30
+ warn '***warning: Failed to Oj.dump: ' + ce.to_s
31
31
  end
32
32
  end
33
33
 
@@ -203,7 +203,7 @@ module Sisimai
203
203
  elsif cr = argv1.match(/\A(\d+|\d+[.]\d+)?([#{mathconsts}])([#{unitoftime}])?\z/)
204
204
  # 1pd, 1.5pw
205
205
  n = cr[1].to_f || 1
206
- n = 1 if n.to_i == 0
206
+ n = 1 if n.to_i.zero?
207
207
  m = MathematicalConstant[cr[2].to_sym].to_f
208
208
  u = cr[3] || 'd'
209
209
  getseconds = n * m * TimeUnit[u.to_sym].to_f
@@ -58,9 +58,9 @@ module Sisimai
58
58
  emailinode = File.stat(emailindir).ino
59
59
  next if self.inodes.key?(emailinode)
60
60
 
61
- filehandle = File.open(emailindir, 'r:UTF-8')
62
- readbuffer = filehandle.read
63
- filehandle.close
61
+ File.open(emailindir, 'r:UTF-8') do |f|
62
+ readbuffer = f.read
63
+ end
64
64
 
65
65
  self.inodes[emailinode] = 1
66
66
  self.path = emailindir
data/lib/sisimai/mda.rb CHANGED
@@ -94,7 +94,7 @@ module Sisimai
94
94
  def scan(mhead, mbody)
95
95
  return nil unless mhead
96
96
  return nil unless mbody
97
- return nil if mhead.keys.size == 0
97
+ return nil if mhead.keys.size.zero?
98
98
  return nil if mbody.empty?
99
99
 
100
100
  return nil unless mhead['from'] =~ Re0[:from]
@@ -109,7 +109,7 @@ module Sisimai
109
109
  # Check each line with each MDA's symbol regular expression.
110
110
  if agentname0 == ''
111
111
  # Try to match with each regular expression
112
- next unless e.size > 0;
112
+ next unless e.size > 0
113
113
  next unless e =~ Re2
114
114
 
115
115
  Re1.each_key do |f|
@@ -26,6 +26,7 @@ module Sisimai
26
26
  # @param [Hash] argvs Module to be loaded
27
27
  # @options argvs [String] :data Entire email message
28
28
  # @options argvs [Array] :load User defined MTA module list
29
+ # @options argvs [Array] :field Email header names to be captured
29
30
  # @options argvs [Array] :order The order of MTA modules
30
31
  # @options argvs [Code] :hook Reference to callback method
31
32
  # @return [Sisimai::Message] Structured email data or Undef if each
@@ -35,6 +36,7 @@ module Sisimai
35
36
 
36
37
  email = data
37
38
  input = argvs[:input] || 'email'
39
+ field = argvs[:field] || []
38
40
  child = nil
39
41
 
40
42
  if input == 'email'
@@ -61,9 +63,11 @@ module Sisimai
61
63
  return nil
62
64
  end
63
65
 
64
- methodargv = { 'data' => email, 'hook' => argvs[:hook] || nil }
65
- datasource = nil
66
-
66
+ methodargv = {
67
+ 'data' => email,
68
+ 'hook' => argvs[:hook] || nil,
69
+ 'field' => argvs[:field],
70
+ }
67
71
  [:load, :order].each do |e|
68
72
  # Order of MTA, MSP modules
69
73
  next unless argvs.key?(e)
@@ -38,6 +38,7 @@ module Sisimai
38
38
  # @param [Hash] argvs Email data
39
39
  # @options argvs [String] data Entire email message
40
40
  # @options argvs [Array] load User defined MTA module list
41
+ # @options argvs [Array] field Email header names to be captured
41
42
  # @options argvs [Array] order The order of MTA modules
42
43
  # @options argvs [Code] hook Reference to callback method
43
44
  # @return [Hash] Resolved data structure
@@ -66,6 +67,7 @@ module Sisimai
66
67
  headerargv = {}
67
68
  headerargv['extheaders'] = ExtHeaders
68
69
  headerargv['tryonfirst'] = []
70
+ headerargv['extrafield'] = argvs['field'] || []
69
71
  processing['from'] = aftersplit['from']
70
72
  processing['header'] = Sisimai::Message::Email.headers(aftersplit['header'], headerargv)
71
73
 
@@ -214,16 +216,20 @@ module Sisimai
214
216
  allheaders = {}
215
217
  structured = {}
216
218
  extheaders = argvs['extheaders'] || []
219
+ extrafield = argvs['extrafield'] || []
217
220
 
218
221
  HeaderList.each { |e| structured[e] = nil }
219
222
  HeaderList.each { |e| allheaders[e] = true }
220
223
  RFC3834Set.each { |e| allheaders[e] = true }
221
224
  MultiHeads.each_key { |e| structured[e.downcase] = [] }
222
225
  extheaders.each_key { |e| allheaders[e] = true }
226
+ if extrafield.size > 0
227
+ extrafield.each { |e| allheaders[e.downcase] = true }
228
+ end
223
229
 
224
230
  heads.split("\n").each do |e|
225
231
  # Convert email headers to hash
226
- if cv = e.match(/\A([^ ]+?)[:][ ]*(.+?)\z/)
232
+ if cv = e.match(/\A([^ ]+?)[:][ ]*(.*?)\z/)
227
233
  # split the line into a header name and a header content
228
234
  lhs = cv[1]
229
235
  rhs = cv[2]
@@ -447,7 +453,7 @@ module Sisimai
447
453
  if hookmethod.is_a? Proc
448
454
  # Execute hook method
449
455
  begin
450
- p = {
456
+ p = {
451
457
  'datasrc' => 'email',
452
458
  'headers' => mailheader,
453
459
  'message' => bodystring,
data/lib/sisimai/mime.rb CHANGED
@@ -122,7 +122,7 @@ module Sisimai
122
122
  # Decoded using unpack('M') entire body string when the boundary string
123
123
  # or "Content-Transfer-Encoding: quoted-printable" are not included in
124
124
  # the message body.
125
- return argv1.unpack('M').first if boundary00.size == 0
125
+ return argv1.unpack('M').first if boundary00.size.zero?
126
126
  return argv1.unpack('M').first unless argv1 =~ ReE[:'quoted-print']
127
127
 
128
128
  boundary01 = Sisimai::MIME.boundary(heads['content-type'], 1)
@@ -144,7 +144,7 @@ module Sisimai
144
144
  # --=_gy7C4Gpes0RP4V5Bs9cK4o2Us2ZT57b-3OLnRN+4klS8dTmQ
145
145
  # Content-Type: text/plain; charset=iso-8859-15
146
146
  # Content-Transfer-Encoding: quoted-printable
147
- if mimeinside
147
+ if mimeinside
148
148
  # Quoted-Printable encoded text block
149
149
  if e =~ reboundary[:begin]
150
150
  # The next boundary string has appeared
@@ -55,7 +55,7 @@ module Sisimai
55
55
  v = nil
56
56
 
57
57
  hasdivided.each do |e|
58
- if readcursor == 0
58
+ if readcursor.zero?
59
59
  # Beginning of the bounce message or delivery status part
60
60
  if e =~ Re1[:begin]
61
61
  readcursor |= Indicators[:deliverystatus]
@@ -118,7 +118,7 @@ module Sisimai
118
118
  end
119
119
  end
120
120
  end
121
- return nil if recipients == 0
121
+ return nil if recipients.zero?
122
122
  require 'sisimai/string'
123
123
 
124
124
  dscontents.map do |e|
@@ -57,7 +57,7 @@ module Sisimai
57
57
  v = nil
58
58
 
59
59
  hasdivided.each do |e|
60
- if readcursor == 0
60
+ if readcursor.zero?
61
61
  # Beginning of the bounce message or delivery status part
62
62
  if e =~ Re1[:begin]
63
63
  readcursor |= Indicators[:deliverystatus]
@@ -142,7 +142,7 @@ module Sisimai
142
142
  end
143
143
  end
144
144
 
145
- return nil if recipients == 0
145
+ return nil if recipients.zero?
146
146
  require 'sisimai/string'
147
147
  require 'sisimai/smtp/status'
148
148
 
@@ -56,7 +56,7 @@ module Sisimai
56
56
  v = nil
57
57
 
58
58
  hasdivided.each do |e|
59
- if readcursor == 0
59
+ if readcursor.zero?
60
60
  # Beginning of the bounce message or delivery status part
61
61
  if e =~ Re1[:begin]
62
62
  readcursor |= Indicators[:deliverystatus]
@@ -125,7 +125,7 @@ module Sisimai
125
125
  end
126
126
  end
127
127
 
128
- return nil if recipients == 0
128
+ return nil if recipients.zero?
129
129
  require 'sisimai/string'
130
130
 
131
131
  dscontents.map do |e|
@@ -102,7 +102,7 @@ module Sisimai
102
102
  ReFailure.each_key { |a| rxmessages.concat(ReFailure[a]) }
103
103
 
104
104
  hasdivided.each do |e|
105
- if readcursor == 0
105
+ if readcursor.zero?
106
106
  # Beginning of the bounce message or delivery status part
107
107
  if e =~ Re1[:begin]
108
108
  readcursor |= Indicators[:deliverystatus]
@@ -200,7 +200,7 @@ module Sisimai
200
200
  end
201
201
  end
202
202
  end
203
- return nil if recipients == 0
203
+ return nil if recipients.zero?
204
204
 
205
205
  dscontents.map do |e|
206
206
  if e['alterrors'] && e['alterrors'].size > 0
@@ -55,7 +55,7 @@ module Sisimai
55
55
  match += 1 if mhead['from'] =~ Re0[:from]
56
56
  match += 1 if mhead['reply-to'] && mhead['reply-to'] =~ Re0[:'reply-to']
57
57
  match += 1 if mhead['received'].find { |a| a =~ Re0[:received] }
58
- return nil if match == 0
58
+ return nil if match.zero?
59
59
 
60
60
  require 'sisimai/string'
61
61
  require 'sisimai/address'
@@ -69,7 +69,7 @@ module Sisimai
69
69
  v = nil
70
70
 
71
71
  hasdivided.each do |e|
72
- if readcursor == 0
72
+ if readcursor.zero?
73
73
  # Beginning of the bounce message or delivery status part
74
74
  if e =~ Re1[:begin]
75
75
  readcursor |= Indicators[:deliverystatus]
@@ -128,7 +128,7 @@ module Sisimai
128
128
  end
129
129
  end
130
130
 
131
- return nil if recipients == 0
131
+ return nil if recipients.zero?
132
132
  require 'sisimai/smtp/status'
133
133
 
134
134
  dscontents.map do |e|
@@ -95,7 +95,7 @@ module Sisimai
95
95
  v = nil
96
96
 
97
97
  hasdivided.each do |e|
98
- if readcursor == 0
98
+ if readcursor.zero?
99
99
  # Beginning of the bounce message or delivery status part
100
100
  if e =~ Re1[:begin]
101
101
  readcursor |= Indicators[:deliverystatus]
@@ -172,7 +172,7 @@ module Sisimai
172
172
  end
173
173
  end
174
174
 
175
- if recipients == 0
175
+ if recipients.zero?
176
176
  # Fallback for getting recipient addresses
177
177
  if mhead['x-failed-recipients']
178
178
  # X-Failed-Recipients: kijitora@example.jp
@@ -188,7 +188,7 @@ module Sisimai
188
188
  end
189
189
  end
190
190
  end
191
- return nil if recipients == 0
191
+ return nil if recipients.zero?
192
192
 
193
193
  if mhead['received'].size > 0
194
194
  # Get the name of local MTA
@@ -68,7 +68,7 @@ module Sisimai
68
68
  havepassed << e
69
69
  p = havepassed[-2]
70
70
 
71
- if readcursor == 0
71
+ if readcursor.zero?
72
72
  # Beginning of the bounce message or delivery status part
73
73
  if e =~ Re1[:begin]
74
74
  readcursor |= Indicators[:deliverystatus]
@@ -184,7 +184,7 @@ module Sisimai
184
184
 
185
185
  end
186
186
  end
187
- return nil if recipients == 0
187
+ return nil if recipients.zero?
188
188
  require 'sisimai/string'
189
189
 
190
190
  dscontents.map do |e|
@@ -73,7 +73,7 @@ module Sisimai
73
73
  havepassed << e
74
74
  p = havepassed[-2]
75
75
 
76
- if readcursor == 0
76
+ if readcursor.zero?
77
77
  # Beginning of the bounce message or delivery status part
78
78
  if e =~ Re1[:begin]
79
79
  readcursor |= Indicators[:deliverystatus]
@@ -187,7 +187,7 @@ module Sisimai
187
187
  end
188
188
  end
189
189
  end
190
- return nil if recipients == 0
190
+ return nil if recipients.zero?
191
191
  require 'sisimai/string'
192
192
 
193
193
  dscontents.map do |e|
@@ -55,12 +55,11 @@ module Sisimai
55
55
  return nil unless mbody
56
56
 
57
57
  match = 0
58
- xmail = mhead['x-mailer'] || ''
59
-
60
58
  return nil if mhead['x-mailer'] =~ ReE[:'x-mailer']
59
+
61
60
  match += 1 if mhead['x-aws-outgoing']
62
61
  match += 1 if mhead['x-ses-outgoing']
63
- return nil if match == 0
62
+ return nil if match.zero?
64
63
 
65
64
  dscontents = [Sisimai::MSP.DELIVERYSTATUS]
66
65
  hasdivided = mbody.split("\n")
@@ -80,7 +79,7 @@ module Sisimai
80
79
  havepassed << e
81
80
  p = havepassed[-2]
82
81
 
83
- if readcursor == 0
82
+ if readcursor.zero?
84
83
  # Beginning of the bounce message or delivery status part
85
84
  if e =~ Re1[:begin]
86
85
  readcursor |= Indicators[:deliverystatus]
@@ -192,7 +191,7 @@ module Sisimai
192
191
  end
193
192
  end
194
193
 
195
- return nil if recipients == 0
194
+ return nil if recipients.zero?
196
195
  require 'sisimai/string'
197
196
  require 'sisimai/smtp/status'
198
197