sisimai 4.25.3-java → 4.25.4-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 (123) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -0
  4. data/ANALYTICAL-PRECISION +2 -4
  5. data/CONTRIBUTING +4 -0
  6. data/ChangeLog.md +39 -0
  7. data/Developers.mk +1 -72
  8. data/Makefile +4 -0
  9. data/README-JA.md +3 -0
  10. data/README.md +5 -2
  11. data/lib/sisimai.rb +4 -3
  12. data/lib/sisimai/arf.rb +6 -6
  13. data/lib/sisimai/bite.rb +8 -3
  14. data/lib/sisimai/bite/email.rb +7 -50
  15. data/lib/sisimai/bite/json.rb +5 -25
  16. data/lib/sisimai/data.rb +1 -1
  17. data/lib/sisimai/lhost.rb +101 -0
  18. data/lib/sisimai/{bite/email → lhost}/activehunter.rb +10 -10
  19. data/lib/sisimai/{bite/email → lhost}/amavis.rb +9 -9
  20. data/lib/sisimai/lhost/amazonses.rb +403 -0
  21. data/lib/sisimai/{bite/email → lhost}/amazonworkmail.rb +9 -9
  22. data/lib/sisimai/{bite/email → lhost}/aol.rb +10 -10
  23. data/lib/sisimai/{bite/email → lhost}/apachejames.rb +10 -10
  24. data/lib/sisimai/{bite/email → lhost}/bigfoot.rb +9 -9
  25. data/lib/sisimai/{bite/email → lhost}/biglobe.rb +10 -10
  26. data/lib/sisimai/{bite/email → lhost}/courier.rb +10 -10
  27. data/lib/sisimai/{bite/email → lhost}/domino.rb +9 -9
  28. data/lib/sisimai/{bite/email → lhost}/einsundeins.rb +10 -10
  29. data/lib/sisimai/{bite/email → lhost}/exchange2003.rb +9 -9
  30. data/lib/sisimai/{bite/email → lhost}/exchange2007.rb +9 -9
  31. data/lib/sisimai/{bite/email → lhost}/exim.rb +10 -10
  32. data/lib/sisimai/{bite/email → lhost}/ezweb.rb +9 -9
  33. data/lib/sisimai/{bite/email → lhost}/facebook.rb +9 -9
  34. data/lib/sisimai/{bite/email → lhost}/fml.rb +10 -10
  35. data/lib/sisimai/{bite/email → lhost}/gmx.rb +10 -10
  36. data/lib/sisimai/{bite/email → lhost}/google.rb +14 -14
  37. data/lib/sisimai/{bite/email → lhost}/gsuite.rb +10 -10
  38. data/lib/sisimai/{bite/email → lhost}/imailserver.rb +10 -10
  39. data/lib/sisimai/{bite/email → lhost}/interscanmss.rb +9 -9
  40. data/lib/sisimai/{bite/email → lhost}/kddi.rb +10 -10
  41. data/lib/sisimai/{bite/email → lhost}/mailfoundry.rb +9 -9
  42. data/lib/sisimai/{bite/email → lhost}/mailmarshalsmtp.rb +9 -9
  43. data/lib/sisimai/{bite/email → lhost}/mailru.rb +11 -11
  44. data/lib/sisimai/{bite/email → lhost}/mcafee.rb +9 -9
  45. data/lib/sisimai/{bite/email → lhost}/messagelabs.rb +9 -9
  46. data/lib/sisimai/{bite/email → lhost}/messagingserver.rb +9 -9
  47. data/lib/sisimai/{bite/email → lhost}/mfilter.rb +9 -9
  48. data/lib/sisimai/{bite/email → lhost}/mxlogic.rb +10 -10
  49. data/lib/sisimai/{bite/email → lhost}/notes.rb +9 -9
  50. data/lib/sisimai/{bite/email → lhost}/office365.rb +10 -10
  51. data/lib/sisimai/{bite/email → lhost}/opensmtpd.rb +9 -9
  52. data/lib/sisimai/{bite/email → lhost}/outlook.rb +9 -9
  53. data/lib/sisimai/{bite/email → lhost}/postfix.rb +9 -9
  54. data/lib/sisimai/{bite/email → lhost}/qmail.rb +9 -9
  55. data/lib/sisimai/{bite/email → lhost}/receivingses.rb +11 -11
  56. data/lib/sisimai/{bite/email → lhost}/sendgrid.rb +120 -11
  57. data/lib/sisimai/{bite/email → lhost}/sendmail.rb +9 -9
  58. data/lib/sisimai/{bite/email → lhost}/surfcontrol.rb +9 -9
  59. data/lib/sisimai/{bite/email → lhost}/userdefined.rb +9 -9
  60. data/lib/sisimai/{bite/email → lhost}/v5sendmail.rb +10 -10
  61. data/lib/sisimai/{bite/email → lhost}/verizon.rb +11 -11
  62. data/lib/sisimai/{bite/email → lhost}/x1.rb +9 -9
  63. data/lib/sisimai/{bite/email → lhost}/x2.rb +9 -9
  64. data/lib/sisimai/{bite/email → lhost}/x3.rb +9 -9
  65. data/lib/sisimai/{bite/email → lhost}/x4.rb +10 -10
  66. data/lib/sisimai/{bite/email → lhost}/x5.rb +9 -9
  67. data/lib/sisimai/{bite/email → lhost}/yahoo.rb +9 -9
  68. data/lib/sisimai/{bite/email → lhost}/yandex.rb +10 -10
  69. data/lib/sisimai/{bite/email → lhost}/zoho.rb +10 -10
  70. data/lib/sisimai/mda.rb +1 -1
  71. data/lib/sisimai/message.rb +535 -28
  72. data/lib/sisimai/message/email.rb +3 -454
  73. data/lib/sisimai/message/json.rb +3 -177
  74. data/lib/sisimai/order.rb +238 -4
  75. data/lib/sisimai/order/email.rb +5 -190
  76. data/lib/sisimai/order/json.rb +3 -39
  77. data/lib/sisimai/reason.rb +1 -1
  78. data/lib/sisimai/reason/norelaying.rb +1 -1
  79. data/lib/sisimai/reason/userunknown.rb +1 -1
  80. data/lib/sisimai/reason/virusdetected.rb +1 -0
  81. data/lib/sisimai/rfc1894.rb +2 -2
  82. data/lib/sisimai/rfc3464.rb +13 -13
  83. data/lib/sisimai/rfc3834.rb +3 -3
  84. data/lib/sisimai/rfc5322.rb +1 -1
  85. data/lib/sisimai/rhost.rb +5 -4
  86. data/lib/sisimai/rhost/exchangeonline.rb +1 -1
  87. data/lib/sisimai/rhost/franceptt.rb +1 -1
  88. data/lib/sisimai/rhost/godaddy.rb +1 -1
  89. data/lib/sisimai/rhost/iua.rb +39 -0
  90. data/lib/sisimai/version.rb +1 -1
  91. data/set-of-emails/README.md +0 -1
  92. data/set-of-emails/maildir/bsd/email-gsuite-13.eml +261 -0
  93. data/set-of-emails/maildir/bsd/email-postfix-62.eml +105 -0
  94. data/set-of-emails/maildir/bsd/email-postfix-63.eml +85 -0
  95. data/set-of-emails/maildir/bsd/rhost-iua-01.eml +70 -0
  96. metadata +75 -94
  97. data/fig/sisimai-architecture.png +0 -0
  98. data/lib/sisimai/bite/email/amazonses.rb +0 -186
  99. data/lib/sisimai/bite/json/amazonses.rb +0 -242
  100. data/lib/sisimai/bite/json/sendgrid.rb +0 -123
  101. data/set-of-emails/jsonobj/json-amazonses-01.json +0 -1
  102. data/set-of-emails/jsonobj/json-amazonses-02.json +0 -11
  103. data/set-of-emails/jsonobj/json-amazonses-03.json +0 -1
  104. data/set-of-emails/jsonobj/json-amazonses-04.json +0 -1
  105. data/set-of-emails/jsonobj/json-amazonses-05.json +0 -1
  106. data/set-of-emails/jsonobj/json-amazonses-06.json +0 -1
  107. data/set-of-emails/jsonobj/json-sendgrid-01.json +0 -1
  108. data/set-of-emails/jsonobj/json-sendgrid-02.json +0 -1
  109. data/set-of-emails/jsonobj/json-sendgrid-03.json +0 -1
  110. data/set-of-emails/jsonobj/json-sendgrid-04.json +0 -1
  111. data/set-of-emails/jsonobj/json-sendgrid-05.json +0 -1
  112. data/set-of-emails/jsonobj/json-sendgrid-06.json +0 -1
  113. data/set-of-emails/jsonobj/json-sendgrid-07.json +0 -1
  114. data/set-of-emails/jsonobj/json-sendgrid-08.json +0 -1
  115. data/set-of-emails/jsonobj/json-sendgrid-09.json +0 -1
  116. data/set-of-emails/jsonobj/json-sendgrid-10.json +0 -1
  117. data/set-of-emails/jsonobj/json-sendgrid-11.json +0 -1
  118. data/set-of-emails/jsonobj/json-sendgrid-12.json +0 -1
  119. data/set-of-emails/jsonobj/json-sendgrid-13.json +0 -1
  120. data/set-of-emails/jsonobj/json-sendgrid-14.json +0 -1
  121. data/set-of-emails/jsonobj/json-sendgrid-15.json +0 -1
  122. data/set-of-emails/jsonobj/json-sendgrid-16.json +0 -1
  123. data/set-of-emails/jsonobj/json-sendgrid-17.json +0 -1
@@ -6,24 +6,7 @@ module Sisimai
6
6
  # of "new" method is not a bounce email, the method returns nil.
7
7
  class Email
8
8
  # Imported from p5-Sisimail/lib/Sisimai/Message/Email.pm
9
- require 'sisimai/arf'
10
- require 'sisimai/mime'
11
- require 'sisimai/rfc3834'
12
- require 'sisimai/order/email'
13
-
14
- @@ToBeLoaded = []
15
- @@TryOnFirst = []
16
-
17
- BorderLine = '__MIME_ENCODED_BOUNDARY__'
18
- EndOfEmail = Sisimai::String.EOM
19
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
20
- RFC3834Set = Sisimai::RFC3834.headerlist
21
- HeaderList = %w[from to date subject content-type reply-to message-id
22
- received content-transfer-encoding return-path x-mailer]
23
- IsMultiple = { 'received' => true }
24
- DefaultSet = Sisimai::Order::Email.another
25
- SubjectTab = Sisimai::Order::Email.by('subject')
26
- ExtHeaders = Sisimai::Order::Email.headers
9
+ require 'sisimai/message'
27
10
 
28
11
  # Make data structure from the email message(a body part and headers)
29
12
  # @param [Hash] argvs Email data
@@ -34,443 +17,9 @@ module Sisimai
34
17
  # @options argvs [Code] hook Reference to callback method
35
18
  # @return [Hash] Resolved data structure
36
19
  def self.make(argvs)
37
- email = argvs['data']
38
-
39
- hookmethod = argvs['hook'] || nil
40
- processing = {
41
- 'from' => '', # From_ line
42
- 'header' => {}, # Email header
43
- 'rfc822' => '', # Original message part
44
- 'ds' => [], # Parsed data, Delivery Status
45
- 'catch' => nil, # Data parsed by callback method
46
- }
47
- methodargv = {
48
- 'load' => argvs['load'] || [],
49
- 'order' => argvs['order'] || []
50
- }
51
- tobeloaded = Sisimai::Message::Email.load(methodargv)
52
-
53
- # 1. Split email data to headers and a body part.
54
- return nil unless aftersplit = Sisimai::Message::Email.divideup(email)
55
-
56
- # 2. Convert email headers from text to hash reference
57
- headerargv = {
58
- 'extheaders' => ExtHeaders,
59
- 'tryonfirst' => [],
60
- 'extrafield' => argvs['field'] || [],
61
- }
62
- processing['from'] = aftersplit['from']
63
- processing['header'] = Sisimai::Message::Email.headers(aftersplit['header'], headerargv)
64
-
65
- # 3. Check headers for detecting MTA modules
66
- if headerargv['tryonfirst'].empty?
67
- headerargv['tryonfirst'] += Sisimai::Message::Email.makeorder(processing['header'])
68
- end
69
-
70
- # 4. Rewrite message body for detecting the bounce reason
71
- methodargv = {
72
- 'hook' => hookmethod,
73
- 'mail' => processing,
74
- 'body' => aftersplit['body'],
75
- 'tryonfirst' => headerargv['tryonfirst'],
76
- 'tobeloaded' => tobeloaded,
77
- }
78
- return nil unless bouncedata = Sisimai::Message::Email.parse(methodargv)
79
- return nil if bouncedata.empty?
80
- processing['ds'] = bouncedata['ds']
81
- processing['catch'] = bouncedata['catch']
82
-
83
- # 5. Rewrite headers of the original message in the body part
84
- rfc822part = bouncedata['rfc822']
85
- rfc822part = aftersplit['body'] if rfc822part.empty?
86
-
87
- processing['rfc822'] = if rfc822part.is_a? ::String
88
- # The value returned from Sisimai::Bite::Email::* modules
89
- Sisimai::Message::Email.takeapart(rfc822part)
90
- else
91
- # The value returned from Sisimai::Bite::JSON::* modules
92
- rfc822part
93
- end
94
- return processing
95
- end
96
-
97
- # Load MTA modules which specified at 'order' and 'load' in the argument
98
- # @param [Hash] argvs Module information to be loaded
99
- # @options argvs [Array] load User defined MTA module list
100
- # @options argvs [Array] order The order of MTA modules
101
- # @return [Array] Module list
102
- # @since v4.20.0
103
- def self.load(argvs)
104
- modulelist = []
105
- tobeloaded = []
106
-
107
- %w[load order].each do |e|
108
- # The order of MTA modules specified by user
109
- next unless argvs.key?(e)
110
- next unless argvs[e].is_a? Array
111
- next if argvs[e].empty?
112
-
113
- modulelist += argvs['order'] if e == 'order'
114
- next unless e == 'load'
115
-
116
- # Load user defined MTA module
117
- argvs['load'].each do |v|
118
- # Load user defined MTA module
119
- begin
120
- require v.to_s.gsub('::', '/').downcase
121
- rescue LoadError
122
- warn ' ***warning: Failed to load ' << v
123
- next
124
- end
125
-
126
- Module.const_get(v).headerlist.each do |w|
127
- # Get header name which required user defined MTA module
128
- ExtHeaders[w] ||= {}
129
- ExtHeaders[w][v] = 1
130
- end
131
- tobeloaded << v
132
- end
133
- end
134
-
135
- while e = modulelist.shift do
136
- # Append the custom order of MTA modules
137
- next if tobeloaded.index(e)
138
- tobeloaded << e
139
- end
140
-
141
- return tobeloaded
142
- end
143
-
144
- # Divide email data up headers and a body part.
145
- # @param [String] email Email data
146
- # @return [Hash] Email data after split
147
- def self.divideup(email)
148
- return nil if email.empty?
149
-
150
- block = { 'from' => '', 'header' => '', 'body' => '' }
151
- email.scrub!('?')
152
- email.gsub!(/\r\n/, "\n") if email.include?("\r\n")
153
- email.gsub!(/[ \t]+$/, '') if email =~ /[ \t]+$/
154
-
155
- (block['header'], block['body']) = email.split(/\n\n/, 2)
156
- return nil unless block['header']
157
- return nil unless block['body']
158
-
159
- if block['header'][0, 5] == 'From '
160
- # From MAILER-DAEMON Tue Feb 11 00:00:00 2014
161
- block['from'] = block['header'].split(/\n/, 2)[0].delete("\r")
162
- else
163
- # Set pseudo UNIX From line
164
- block['from'] = 'MAILER-DAEMON Tue Feb 11 00:00:00 2014'
165
- end
166
-
167
- block['body'] << "\n"
168
- return block
169
- end
170
-
171
- # Convert email headers from text to hash reference
172
- # @param [String] heads Email header data
173
- # @param [Hash] argvs
174
- # @param options extheaders [Array] External header table
175
- # @return [Hash] Structured email header data
176
- def self.headers(heads, argvs = {})
177
- return nil unless heads
178
-
179
- currheader = ''
180
- allheaders = {}
181
- structured = {}
182
- extheaders = argvs['extheaders'] || []
183
- extrafield = argvs['extrafield'] || []
184
- hasdivided = heads.split("\n")
185
-
186
- HeaderList.each { |e| structured[e] = nil }
187
- HeaderList.each { |e| allheaders[e] = true }
188
- RFC3834Set.each { |e| allheaders[e] = true }
189
- IsMultiple.each_key { |e| structured[e] = [] }
190
- extheaders.each_key { |e| allheaders[e] = true }
191
- unless extrafield.empty?
192
- extrafield.each { |e| allheaders[e] = true }
193
- end
194
-
195
- while e = hasdivided.shift do
196
- # Convert email headers to hash
197
- if cv = e.match(/\A[ \t]+(.+)\z/)
198
- # Continued (foled) header value from the previous line
199
- next unless allheaders.key?(currheader)
200
-
201
- # Header line continued from the previous line
202
- if structured[currheader].is_a? Array
203
- # Concatenate a header which have multi-lines such as 'Received'
204
- structured[currheader][-1] << ' ' << cv[1]
205
- else
206
- structured[currheader] ||= ''
207
- structured[currheader] << ' ' << cv[1]
208
- end
209
- else
210
- # split the line into a header name and a header content
211
- (lhs, rhs) = e.split(/:[ ]*/, 2)
212
- currheader = lhs ? lhs.downcase : ''
213
- next unless allheaders.key?(currheader)
214
-
215
- if IsMultiple.key?(currheader)
216
- # Such as 'Received' header, there are multiple headers in a single
217
- # email message.
218
- #rhs = rhs.tr("\t", ' ').squeeze(' ')
219
- rhs = rhs.tr("\t", ' ')
220
- structured[currheader] << rhs
221
- else
222
- # Other headers except "Received" and so on
223
- if extheaders[currheader]
224
- # MTA specific header
225
- extheaders[currheader].each do |r|
226
- next if argvs['tryonfirst'].index(r)
227
- argvs['tryonfirst'] << r
228
- end
229
- end
230
- structured[currheader] = rhs
231
- end
232
- end
233
- end
234
- return structured
20
+ Sisimai::Message.warn(self.name)
21
+ return Sisimai::Message.make(argvs)
235
22
  end
236
-
237
- # Check headers for detecting MTA module and returns the order of modules
238
- # @param [Hash] heads Email header data
239
- # @return [Array] Order of MTA modules
240
- def self.makeorder(heads)
241
- return [] unless heads
242
- return [] unless heads['subject']
243
- return [] if heads['subject'].empty?
244
- order = []
245
-
246
- # Try to match the value of "Subject" with patterns generated by
247
- # Sisimai::Order->by('subject') method
248
- title = heads['subject'].downcase
249
- SubjectTab.each_key do |e|
250
- # Get MTA list from the subject header
251
- next unless title.include?(e)
252
- order += SubjectTab[e] # Matched and push MTA list
253
- break
254
- end
255
- return order
256
- end
257
-
258
- # Take each email header in the original message apart
259
- # @param [String] heads The original message header
260
- # @return [Hash] Structured message headers
261
- def self.takeapart(heads)
262
- return {} unless heads
263
-
264
- # 1. Scrub to avoid "invalid byte sequence in UTF-8" exception (#82)
265
- # 2. Convert from string to hash reference
266
- heads = heads.scrub('?').gsub(/^[>]+[ ]/m, '').gsub(/=[ ]+=/, "=\n =")
267
-
268
- previousfn = '' # Previous field name
269
- asciiarmor = {} # Header names which has MIME encoded value
270
- headerpart = {} # Required headers in the original message part
271
- hasdivided = heads.split("\n")
272
-
273
- while e = hasdivided.shift do
274
- # Header name as a key, The value of header as a value
275
- if e.start_with?(' ', "\t")
276
- # Continued (foled) header value from the previous line
277
- next if previousfn.empty?
278
-
279
- # Concatenate the line if it is the value of required header
280
- if Sisimai::MIME.is_mimeencoded(e)
281
- # The line is MIME-Encoded test
282
- headerpart[previousfn] << if previousfn == 'subject'
283
- # Subject: header
284
- BorderLine + e
285
- else
286
- # Is not Subject header
287
- e
288
- end
289
- asciiarmor[previousfn] = true
290
- else
291
- # ASCII Characters only: Not MIME-Encoded
292
- headerpart[previousfn] << e.lstrip
293
- asciiarmor[previousfn] ||= false
294
- end
295
- else
296
- # Header name as a key, The value of header as a value
297
- (lhs, rhs) = e.split(/:[ ]*/, 2)
298
- next unless lhs
299
- lhs.downcase!
300
- previousfn = ''
301
-
302
- next unless RFC822Head.key?(lhs)
303
- previousfn = lhs
304
- headerpart[previousfn] = rhs unless headerpart[previousfn]
305
- end
306
- end
307
- return headerpart unless headerpart['subject']
308
-
309
- # Convert MIME-Encoded subject
310
- if Sisimai::String.is_8bit(headerpart['subject'])
311
- # The value of ``Subject'' header is including multibyte character,
312
- # is not MIME-Encoded text.
313
- headerpart['subject'] = 'MULTIBYTE CHARACTERS HAVE BEEN REMOVED'
314
- else
315
- # MIME-Encoded subject field or ASCII characters only
316
- r = []
317
- if asciiarmor['subject']
318
- # split the value of Subject by borderline
319
- headerpart['subject'].split(BorderLine).each do |v|
320
- # Insert value to the array if the string is MIME encoded text
321
- r << v if Sisimai::MIME.is_mimeencoded(v)
322
- end
323
- else
324
- # Subject line is not MIME encoded
325
- r << headerpart['subject']
326
- end
327
- headerpart['subject'] = Sisimai::MIME.mimedecode(r)
328
- end
329
- return headerpart
330
- end
331
-
332
- # @abstract Parse bounce mail with each MTA module
333
- # @param [Hash] argvs Processing message entity.
334
- # @param options argvs [Hash] mail Email message entity
335
- # @param options mail [String] from From line of mbox
336
- # @param options mail [Hash] header Email header data
337
- # @param options mail [String] rfc822 Original message part
338
- # @param options mail [Array] ds Delivery status list(parsed data)
339
- # @param options argvs [String] body Email message body
340
- # @param options argvs [Array] tryonfirst MTA module list to load on first
341
- # @param options argvs [Array] tobeloaded User defined MTA module list
342
- # @return [Hash] Parsed and structured bounce mails
343
- def self.parse(argvs)
344
- mesgentity = argvs['mail']
345
- bodystring = argvs['body']
346
- hookmethod = argvs['hook'] || nil
347
- havecaught = nil
348
- tryonfirst = argvs['tryonfirst'] || []
349
- tobeloaded = argvs['tobeloaded'] || []
350
- mailheader = mesgentity['header']
351
-
352
- return nil unless argvs['mail']
353
- return nil unless argvs['body']
354
-
355
- # PRECHECK_EACH_HEADER:
356
- # Set empty string if the value is nil
357
- mailheader['from'] ||= ''
358
- mailheader['subject'] ||= ''
359
- mailheader['content-type'] ||= ''
360
-
361
- # Decode BASE64 Encoded message body, rewrite.
362
- mesgformat = (mailheader['content-type'] || '').downcase
363
- ctencoding = (mailheader['content-transfer-encoding'] || '').downcase
364
-
365
- if mesgformat.start_with?('text/plain', 'text/html')
366
- # Content-Type: text/plain; charset=UTF-8
367
- if ctencoding == 'base64'
368
- # Content-Transfer-Encoding: base64
369
- bodystring = Sisimai::MIME.base64d(bodystring)
370
-
371
- elsif ctencoding == 'quoted-printable'
372
- # Content-Transfer-Encoding: quoted-printable
373
- bodystring = Sisimai::MIME.qprintd(bodystring)
374
- end
375
-
376
- if mesgformat.start_with?('text/html;')
377
- # Content-Type: text/html;...
378
- bodystring = Sisimai::String.to_plain(bodystring, true)
379
- end
380
- else
381
- # NOT text/plain
382
- if mesgformat.start_with?('multipart/')
383
- # In case of Content-Type: multipart/*
384
- p = Sisimai::MIME.makeflat(mailheader['content-type'], bodystring)
385
- bodystring = p unless p.empty?
386
- end
387
- end
388
-
389
- # EXPAND_FORWARDED_MESSAGE:
390
- # Check whether or not the message is a bounce mail.
391
- # Pre-Process email body if it is a forwarded bounce message.
392
- # Get the original text when the subject begins from 'fwd:' or 'fw:'
393
- if mailheader['subject'].downcase =~ /\A[ \t]*fwd?:/
394
- # Delete quoted strings, quote symbols(>)
395
- bodystring = bodystring.gsub(/^[>]+[ ]/m, '').gsub(/^[>]$/m, '')
396
- elsif Sisimai::MIME.is_mimeencoded(mailheader['subject'])
397
- # Decode MIME-Encoded "Subject:" header
398
- mailheader['subject'] = Sisimai::MIME.mimedecode(mailheader['subject'].split(/[ ]/))
399
- mailheader['subject'].scrub!('?')
400
- end
401
- bodystring = bodystring.scrub('?').delete("\r")
402
-
403
- if hookmethod.is_a? Proc
404
- # Call the hook method
405
- begin
406
- p = {
407
- 'datasrc' => 'email',
408
- 'headers' => mailheader,
409
- 'message' => bodystring,
410
- 'bounces' => nil
411
- }
412
- havecaught = hookmethod.call(p)
413
- rescue StandardError => ce
414
- warn ' ***warning: Something is wrong in hook method :' << ce.to_s
415
- end
416
- end
417
-
418
- bodystring << EndOfEmail
419
- haveloaded = {}
420
- scannedset = nil
421
-
422
- catch :SCANNER do
423
- while true
424
- # 1. Sisimai::ARF
425
- # 2. User-Defined Module
426
- # 3. MTA Module Candidates to be tried on first
427
- # 4. Sisimai::Bite::Email::*
428
- # 5. Sisimai::RFC3464
429
- # 6. Sisimai::RFC3834
430
- if Sisimai::ARF.is_arf(mailheader)
431
- # Feedback Loop message
432
- scannedset = Sisimai::ARF.scan(mailheader, bodystring)
433
- throw :SCANNER if scannedset
434
- end
435
-
436
- while r = tobeloaded.shift do
437
- # Call user defined MTA modules
438
- next if haveloaded[r]
439
- scannedset = Module.const_get(r).scan(mailheader, bodystring)
440
- haveloaded[r] = true
441
- throw :SCANNER if scannedset
442
- end
443
-
444
- tryonfirst.concat(DefaultSet)
445
- while r = tryonfirst.shift do
446
- # Try MTA module candidates
447
- next if haveloaded.key?(r)
448
- require r.gsub('::', '/').downcase
449
- scannedset = Module.const_get(r).scan(mailheader, bodystring)
450
- haveloaded[r] = true
451
- throw :SCANNER if scannedset
452
- end
453
-
454
- # When the all of Sisimai::Bite::Email::* modules did not return
455
- # bounce data, call Sisimai::RFC3464;
456
- require 'sisimai/rfc3464'
457
- scannedset = Sisimai::RFC3464.scan(mailheader, bodystring)
458
- break if scannedset
459
-
460
- # Try to parse the message as auto reply message defined in RFC3834
461
- require 'sisimai/rfc3834'
462
- scannedset = Sisimai::RFC3834.scan(mailheader, bodystring)
463
- break if scannedset
464
-
465
- # as of now, we have no sample email for coding this block
466
- break
467
- end
468
- end
469
-
470
- scannedset['catch'] = havecaught if scannedset
471
- return scannedset
472
- end
473
-
474
23
  end
475
24
  end
476
25
  end