sisimai 4.16.0-java → 4.17.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/ANALYTICAL-PRECISION +7 -7
  4. data/Changes +15 -0
  5. data/Makefile +1 -1
  6. data/README.md +30 -28
  7. data/lib/sisimai.rb +20 -1
  8. data/lib/sisimai/address.rb +28 -9
  9. data/lib/sisimai/arf.rb +37 -46
  10. data/lib/sisimai/data.rb +67 -43
  11. data/lib/sisimai/datetime.rb +210 -210
  12. data/lib/sisimai/mda.rb +30 -30
  13. data/lib/sisimai/message.rb +3 -5
  14. data/lib/sisimai/msp/de/einsundeins.rb +14 -42
  15. data/lib/sisimai/msp/de/gmx.rb +17 -44
  16. data/lib/sisimai/msp/jp/biglobe.rb +15 -44
  17. data/lib/sisimai/msp/jp/ezweb.rb +20 -50
  18. data/lib/sisimai/msp/jp/kddi.rb +16 -43
  19. data/lib/sisimai/msp/ru/mailru.rb +20 -48
  20. data/lib/sisimai/msp/ru/yandex.rb +16 -50
  21. data/lib/sisimai/msp/uk/messagelabs.rb +17 -51
  22. data/lib/sisimai/msp/us/amazonses.rb +18 -40
  23. data/lib/sisimai/msp/us/amazonworkmail.rb +17 -35
  24. data/lib/sisimai/msp/us/aol.rb +17 -41
  25. data/lib/sisimai/msp/us/bigfoot.rb +15 -48
  26. data/lib/sisimai/msp/us/facebook.rb +63 -90
  27. data/lib/sisimai/msp/us/google.rb +15 -44
  28. data/lib/sisimai/msp/us/office365.rb +21 -46
  29. data/lib/sisimai/msp/us/outlook.rb +17 -50
  30. data/lib/sisimai/msp/us/receivingses.rb +20 -43
  31. data/lib/sisimai/msp/us/sendgrid.rb +13 -37
  32. data/lib/sisimai/msp/us/verizon.rb +30 -74
  33. data/lib/sisimai/msp/us/yahoo.rb +12 -40
  34. data/lib/sisimai/msp/us/zoho.rb +14 -42
  35. data/lib/sisimai/mta/activehunter.rb +11 -40
  36. data/lib/sisimai/mta/apachejames.rb +18 -40
  37. data/lib/sisimai/mta/courier.rb +20 -57
  38. data/lib/sisimai/mta/domino.rb +24 -56
  39. data/lib/sisimai/mta/exchange.rb +26 -54
  40. data/lib/sisimai/mta/exim.rb +20 -39
  41. data/lib/sisimai/mta/imailserver.rb +26 -71
  42. data/lib/sisimai/mta/interscanmss.rb +26 -44
  43. data/lib/sisimai/mta/mailfoundry.rb +12 -42
  44. data/lib/sisimai/mta/mailmarshalsmtp.rb +13 -43
  45. data/lib/sisimai/mta/mcafee.rb +17 -46
  46. data/lib/sisimai/mta/messagingserver.rb +14 -47
  47. data/lib/sisimai/mta/mfilter.rb +12 -35
  48. data/lib/sisimai/mta/mxlogic.rb +18 -42
  49. data/lib/sisimai/mta/notes.rb +22 -45
  50. data/lib/sisimai/mta/opensmtpd.rb +18 -48
  51. data/lib/sisimai/mta/postfix.rb +15 -45
  52. data/lib/sisimai/mta/qmail.rb +32 -60
  53. data/lib/sisimai/mta/sendmail.rb +13 -38
  54. data/lib/sisimai/mta/surfcontrol.rb +15 -44
  55. data/lib/sisimai/mta/userdefined.rb +14 -30
  56. data/lib/sisimai/mta/v5sendmail.rb +18 -40
  57. data/lib/sisimai/mta/x1.rb +12 -41
  58. data/lib/sisimai/mta/x2.rb +12 -41
  59. data/lib/sisimai/mta/x3.rb +12 -39
  60. data/lib/sisimai/mta/x4.rb +33 -66
  61. data/lib/sisimai/mta/x5.rb +15 -42
  62. data/lib/sisimai/reason.rb +8 -71
  63. data/lib/sisimai/reason/blocked.rb +3 -0
  64. data/lib/sisimai/reason/contenterror.rb +3 -0
  65. data/lib/sisimai/reason/delivered.rb +27 -0
  66. data/lib/sisimai/reason/exceedlimit.rb +3 -0
  67. data/lib/sisimai/reason/expired.rb +3 -0
  68. data/lib/sisimai/reason/feedback.rb +18 -0
  69. data/lib/sisimai/reason/filtered.rb +4 -0
  70. data/lib/sisimai/reason/hasmoved.rb +3 -0
  71. data/lib/sisimai/reason/hostunknown.rb +3 -0
  72. data/lib/sisimai/reason/mailboxfull.rb +3 -0
  73. data/lib/sisimai/reason/mailererror.rb +3 -0
  74. data/lib/sisimai/reason/mesgtoobig.rb +3 -0
  75. data/lib/sisimai/reason/networkerror.rb +3 -0
  76. data/lib/sisimai/reason/norelaying.rb +3 -0
  77. data/lib/sisimai/reason/notaccept.rb +3 -0
  78. data/lib/sisimai/reason/onhold.rb +3 -0
  79. data/lib/sisimai/reason/rejected.rb +3 -0
  80. data/lib/sisimai/reason/securityerror.rb +3 -0
  81. data/lib/sisimai/reason/spamdetected.rb +3 -0
  82. data/lib/sisimai/reason/suspend.rb +3 -0
  83. data/lib/sisimai/reason/syntaxerror.rb +41 -0
  84. data/lib/sisimai/reason/systemerror.rb +3 -0
  85. data/lib/sisimai/reason/systemfull.rb +3 -0
  86. data/lib/sisimai/reason/toomanyconn.rb +3 -0
  87. data/lib/sisimai/reason/undefined.rb +18 -0
  88. data/lib/sisimai/reason/userunknown.rb +3 -0
  89. data/lib/sisimai/reason/vacation.rb +18 -0
  90. data/lib/sisimai/rfc3464.rb +15 -40
  91. data/lib/sisimai/rfc3834.rb +1 -10
  92. data/lib/sisimai/rfc5322.rb +57 -19
  93. data/lib/sisimai/rhost/googleapps.rb +82 -82
  94. data/lib/sisimai/smtp/reply.rb +2 -1
  95. data/lib/sisimai/smtp/status.rb +154 -152
  96. data/lib/sisimai/string.rb +2 -3
  97. data/lib/sisimai/version.rb +1 -1
  98. data/set-of-emails/maildir/bsd/rfc3464-29.eml +60 -0
  99. data/set-of-emails/maildir/bsd/us-amazonworkmail-06.eml +156 -0
  100. data/set-of-emails/maildir/bsd/us-amazonworkmail-07.eml +158 -0
  101. data/set-of-emails/maildir/bsd/us-google-15.eml +97 -0
  102. data/set-of-emails/maildir/bsd/us-google-16.eml +99 -0
  103. data/set-of-emails/maildir/bsd/us-google-17.eml +104 -0
  104. data/set-of-emails/maildir/dos/apachejames-01.eml +4 -4
  105. data/set-of-emails/maildir/dos/us-amazonworkmail-01.eml +156 -0
  106. data/set-of-emails/maildir/dos/us-office365-01.eml +102 -0
  107. data/set-of-emails/maildir/mac/apachejames-01.eml +1 -9
  108. data/set-of-emails/maildir/mac/us-amazonworkmail-01.eml +1 -7
  109. data/set-of-emails/maildir/mac/us-office365-01.eml +1 -4
  110. metadata +17 -2
@@ -24,18 +24,16 @@ module Sisimai
24
24
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
25
25
  }
26
26
  CodeTable = {
27
- '4.4.7' => 'expired',
28
- '5.1.0' => 'rejected',
29
- '5.1.1' => 'userunknown',
30
- '5.1.10' => 'filtered',
31
- '5.4.1' => 'networkerror',
32
- '5.4.14' => 'networkerror',
33
- '5.7.1' => 'rejected',
34
- '5.7.133' => 'rejected',
27
+ :'4.4.7' => 'expired',
28
+ :'5.1.0' => 'rejected',
29
+ :'5.1.1' => 'userunknown',
30
+ :'5.1.10' => 'filtered',
31
+ :'5.4.1' => 'networkerror',
32
+ :'5.4.14' => 'networkerror',
33
+ :'5.7.1' => 'rejected',
34
+ :'5.7.133' => 'rejected',
35
35
  }
36
36
  Indicators = Sisimai::MSP.INDICATORS
37
- LongFields = Sisimai::RFC5322.LONGFIELDS
38
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
39
37
 
40
38
  def description; return 'Microsoft Office 365: http://office.microsoft.com/'; end
41
39
  def smtpagent; return 'US::Office365'; end
@@ -98,11 +96,10 @@ module Sisimai
98
96
  mbody = Sisimai::MIME.qprintd(mbody)
99
97
  end
100
98
 
101
- dscontents = []; dscontents << Sisimai::MSP.DELIVERYSTATUS
99
+ dscontents = [Sisimai::MSP.DELIVERYSTATUS]
102
100
  hasdivided = mbody.split("\n")
103
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
104
- rfc822part = '' # (String) message/rfc822-headers part
105
- previousfn = '' # (String) Previous field name
101
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
102
+ blanklines = 0 # (Integer) The number of blank lines
106
103
  readcursor = 0 # (Integer) Points the current cursor position
107
104
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
108
105
  connheader = {}
@@ -114,7 +111,7 @@ module Sisimai
114
111
  if readcursor == 0
115
112
  # Beginning of the bounce message or delivery status part
116
113
  if e =~ Re1[:begin]
117
- readcursor |= Indicators[:'deliverystatus']
114
+ readcursor |= Indicators[:deliverystatus]
118
115
  next
119
116
  end
120
117
  end
@@ -129,30 +126,16 @@ module Sisimai
129
126
 
130
127
  if readcursor & Indicators[:'message-rfc822'] > 0
131
128
  # After "message/rfc822"
132
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
133
- # Get required headers only
134
- lhs = cv[1].downcase
135
- previousfn = ''
136
- next unless RFC822Head.key?(lhs)
137
-
138
- previousfn = lhs
139
- rfc822part += e + "\n"
140
-
141
- elsif e =~ /\A[ \t]+/
142
- # Continued line from the previous line
143
- next if rfc822next[previousfn]
144
- rfc822part += e + "\n" if LongFields.key?(previousfn)
145
-
146
- else
147
- # Check the end of headers in rfc822 part
148
- next unless LongFields.key?(previousfn)
149
- next unless e.empty?
150
- rfc822next[previousfn] = true
129
+ if e.empty?
130
+ blanklines += 1
131
+ break if blanklines > 1
132
+ next
151
133
  end
134
+ rfc822list << e
152
135
 
153
136
  else
154
137
  # Before "message/rfc822"
155
- next if readcursor & Indicators[:'deliverystatus'] == 0
138
+ next if readcursor & Indicators[:deliverystatus] == 0
156
139
  next if e.empty?
157
140
 
158
141
  # kijitora@example.com<mailto:kijitora@example.com>
@@ -239,17 +222,8 @@ module Sisimai
239
222
  # Set default values if each value is empty.
240
223
  connheader.each_key { |a| e[a] ||= connheader[a] || '' }
241
224
 
242
- if mhead['received'].size > 0
243
- # Get localhost and remote host name from Received header.
244
- r0 = mhead['received']
245
- %w|lhost rhost|.each { |a| e[a] ||= '' }
246
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
247
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
248
- end
249
-
250
- e['spec'] ||= 'SMTP'
251
- e['status'] ||= ''
252
225
  e['agent'] = Sisimai::MSP::US::Office365.smtpagent
226
+ e['status'] ||= ''
253
227
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
254
228
 
255
229
  if e['status'].empty? || e['status'] =~ /\A\d[.]0[.]0\z/
@@ -259,10 +233,11 @@ module Sisimai
259
233
  end
260
234
 
261
235
  if e['status']
262
- e['reason'] = CodeTable[e['status']] || ''
236
+ e['reason'] = CodeTable[e['status'].to_sym] || ''
263
237
  end
264
238
  end
265
239
 
240
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
266
241
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
267
242
  end
268
243
 
@@ -20,12 +20,10 @@ module Sisimai
20
20
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
21
21
  }
22
22
  ReFailure = {
23
- 'hostunknown' => %r/The mail could not be delivered to the recipient because the domain is not reachable/,
24
- 'userunknown' => %r/Requested action not taken: mailbox unavailable/,
23
+ hostunknown: %r/The mail could not be delivered to the recipient because the domain is not reachable/,
24
+ userunknown: %r/Requested action not taken: mailbox unavailable/,
25
25
  }
26
26
  Indicators = Sisimai::MSP.INDICATORS
27
- LongFields = Sisimai::RFC5322.LONGFIELDS
28
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
29
27
 
30
28
  def description; return 'Microsoft Outlook.com: https://www.outlook.com/'; end
31
29
  def smtpagent; return 'US::Outlook'; end
@@ -57,12 +55,11 @@ module Sisimai
57
55
  match += 1 if mhead['received'].find { |a| a =~ Re0[:received] }
58
56
  return nil if match < 2
59
57
 
60
- dscontents = []; dscontents << Sisimai::MSP.DELIVERYSTATUS
58
+ dscontents = [Sisimai::MSP.DELIVERYSTATUS]
61
59
  hasdivided = mbody.split("\n")
62
- havepassed = [''];
63
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
64
- rfc822part = '' # (String) message/rfc822-headers part
65
- previousfn = '' # (String) Previous field name
60
+ havepassed = ['']
61
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
62
+ blanklines = 0 # (Integer) The number of blank lines
66
63
  readcursor = 0 # (Integer) Points the current cursor position
67
64
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
68
65
  connvalues = 0 # (Integer) Flag, 1 if all the value of $connheader have been set
@@ -74,12 +71,13 @@ module Sisimai
74
71
 
75
72
  hasdivided.each do |e|
76
73
  # Save the current line for the next loop
77
- havepassed << e; p = havepassed[-2]
74
+ havepassed << e
75
+ p = havepassed[-2]
78
76
 
79
77
  if readcursor == 0
80
78
  # Beginning of the bounce message or delivery status part
81
79
  if e =~ Re1[:begin]
82
- readcursor |= Indicators[:'deliverystatus']
80
+ readcursor |= Indicators[:deliverystatus]
83
81
  next
84
82
  end
85
83
  end
@@ -94,30 +92,16 @@ module Sisimai
94
92
 
95
93
  if readcursor & Indicators[:'message-rfc822'] > 0
96
94
  # After "message/rfc822"
97
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
98
- # Get required headers only
99
- lhs = cv[1].downcase
100
- previousfn = ''
101
- next unless RFC822Head.key?(lhs)
102
-
103
- previousfn = lhs
104
- rfc822part += e + "\n"
105
-
106
- elsif e =~ /\A[ \t]+/
107
- # Continued line from the previous line
108
- next if rfc822next[previousfn]
109
- rfc822part += e + "\n" if LongFields.key?(previousfn)
110
-
111
- else
112
- # Check the end of headers in rfc822 part
113
- next unless LongFields.key?(previousfn)
114
- next unless e.empty?
115
- rfc822next[previousfn] = true
95
+ if e.empty?
96
+ blanklines += 1
97
+ break if blanklines > 1
98
+ next
116
99
  end
100
+ rfc822list << e
117
101
 
118
102
  else
119
103
  # Before "message/rfc822"
120
- next if readcursor & Indicators[:'deliverystatus'] == 0
104
+ next if readcursor & Indicators[:deliverystatus] == 0
121
105
  next if e.empty?
122
106
 
123
107
  if connvalues == connheader.keys.size
@@ -184,24 +168,12 @@ module Sisimai
184
168
  end
185
169
  end
186
170
  end
187
-
188
171
  return nil if recipients == 0
189
172
  require 'sisimai/string'
190
- require 'sisimai/smtp/status'
191
173
 
192
174
  dscontents.map do |e|
193
175
  # Set default values if each value is empty.
194
176
  connheader.each_key { |a| e[a] ||= connheader[a] || '' }
195
-
196
- if mhead['received'].size > 0
197
- # Get localhost and remote host name from Received header.
198
- r0 = mhead['received']
199
- %w|lhost rhost|.each { |a| e[a] ||= '' }
200
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
201
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
202
- end
203
-
204
- e['spec'] ||= 'SMTP'
205
177
  e['agent'] = Sisimai::MSP::US::Outlook.smtpagent
206
178
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
207
179
 
@@ -221,17 +193,12 @@ module Sisimai
221
193
  ReFailure.each_key do |r|
222
194
  # Verify each regular expression of session errors
223
195
  next unless e['diagnosis'] =~ ReFailure[r]
224
- e['reason'] = r
196
+ e['reason'] = r.to_s
225
197
  break
226
198
  end
227
-
228
- if e['status'].empty? || e['status'] =~ /\A\d[.]0[.]0\z/
229
- # There is no value of Status header or the value is 5.0.0, 4.0.0
230
- pseudostatus = Sisimai::SMTP::Status.find(e['diagnosis'])
231
- e['status'] = pseudostatus if pseudostatus.size > 0
232
- end
233
199
  end
234
200
 
201
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
235
202
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
236
203
  end
237
204
 
@@ -21,14 +21,12 @@ module Sisimai
21
21
  }
22
22
  ReFailure = {
23
23
  # The followings are error messages in Rule sets/*/Actions/Template
24
- 'filtered' => %r/Mailbox does not exist/,
25
- 'mesgtoobig' => %r/Message too large/,
26
- 'mailboxfull' => %r/Mailbox full/,
27
- 'contenterror' => %r/Message content rejected/,
24
+ filtered: %r/Mailbox does not exist/,
25
+ mesgtoobig: %r/Message too large/,
26
+ mailboxfull: %r/Mailbox full/,
27
+ contenterror: %r/Message content rejected/,
28
28
  }
29
29
  Indicators = Sisimai::MSP.INDICATORS
30
- LongFields = Sisimai::RFC5322.LONGFIELDS
31
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
32
30
 
33
31
  def description; return 'Amazon SES(Receiving): http://aws.amazon.com/ses/'; end
34
32
  def smtpagent; return 'US::ReceivingSES'; end
@@ -54,12 +52,11 @@ module Sisimai
54
52
  return nil unless mbody
55
53
  return nil unless mhead['x-ses-outgoing']
56
54
 
57
- dscontents = []; dscontents << Sisimai::MSP.DELIVERYSTATUS
55
+ dscontents = [Sisimai::MSP.DELIVERYSTATUS]
58
56
  hasdivided = mbody.split("\n")
59
- havepassed = [''];
60
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
61
- rfc822part = '' # (String) message/rfc822-headers part
62
- previousfn = '' # (String) Previous field name
57
+ havepassed = ['']
58
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
59
+ blanklines = 0 # (Integer) The number of blank lines
63
60
  readcursor = 0 # (Integer) Points the current cursor position
64
61
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
65
62
  connvalues = 0 # (Integer) Flag, 1 if all the value of $connheader have been set
@@ -71,12 +68,13 @@ module Sisimai
71
68
 
72
69
  hasdivided.each do |e|
73
70
  # Save the current line for the next loop
74
- havepassed << e; p = havepassed[-2]
71
+ havepassed << e
72
+ p = havepassed[-2]
75
73
 
76
74
  if readcursor == 0
77
75
  # Beginning of the bounce message or delivery status part
78
76
  if e =~ Re1[:begin]
79
- readcursor |= Indicators[:'deliverystatus']
77
+ readcursor |= Indicators[:deliverystatus]
80
78
  next
81
79
  end
82
80
  end
@@ -91,30 +89,16 @@ module Sisimai
91
89
 
92
90
  if readcursor & Indicators[:'message-rfc822'] > 0
93
91
  # After "message/rfc822"
94
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
95
- # Get required headers only
96
- lhs = cv[1].downcase
97
- previousfn = ''
98
- next unless RFC822Head.key?(lhs)
99
-
100
- previousfn = lhs
101
- rfc822part += e + "\n"
102
-
103
- elsif e =~ /\A[ \t]+/
104
- # Continued line from the previous line
105
- next if rfc822next[previousfn]
106
- rfc822part += e + "\n" if LongFields.key?(previousfn)
107
-
108
- else
109
- # Check the end of headers in rfc822 part
110
- next unless LongFields.key?(previousfn)
111
- next unless e.empty?
112
- rfc822next[previousfn] = true
92
+ if e.empty?
93
+ blanklines += 1
94
+ break if blanklines > 1
95
+ next
113
96
  end
97
+ rfc822list << e
114
98
 
115
99
  else
116
100
  # Before "message/rfc822"
117
- next if readcursor & Indicators[:'deliverystatus'] == 0
101
+ next if readcursor & Indicators[:deliverystatus] == 0
118
102
  next if e.empty?
119
103
 
120
104
  if connvalues == connheader.keys.size
@@ -136,7 +120,7 @@ module Sisimai
136
120
  recipients += 1
137
121
 
138
122
  elsif cv = e.match(/\A[Xx]-[Aa]ctual-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/) ||
139
- cv = e.match(/\A[Oo]riginal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
123
+ e.match(/\A[Oo]riginal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
140
124
  # X-Actual-Recipient: RFC822; kijitora@example.co.jp
141
125
  # Original-Recipient: rfc822; kijitora@example.co.jp
142
126
  v['alias'] = cv[1]
@@ -203,13 +187,6 @@ module Sisimai
203
187
  # Set default values if each value is empty.
204
188
  connheader.each_key { |a| e[a] ||= connheader[a] || '' }
205
189
 
206
- if mhead['received'].size > 0
207
- # Get localhost and remote host name from Received header.
208
- r0 = mhead['received']
209
- %w|lhost rhost|.each { |a| e[a] ||= '' }
210
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
211
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
212
- end
213
190
  e['diagnosis'] = e['diagnosis'].gsub(/\\n/, ' ')
214
191
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
215
192
 
@@ -228,15 +205,15 @@ module Sisimai
228
205
  ReFailure.each_key do |r|
229
206
  # Verify each regular expression of session errors
230
207
  next unless e['diagnosis'] =~ ReFailure[r]
231
- e['reason'] = r
208
+ e['reason'] = r.to_s
232
209
  break
233
210
  end
234
211
 
235
212
  e['reason'] ||= Sisimai::SMTP::Status.name(e['status'])
236
- e['spec'] ||= 'SMTP'
237
213
  e['agent'] = Sisimai::MSP::US::ReceivingSES.smtpagent
238
214
  end
239
215
 
216
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
240
217
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
241
218
  end
242
219
 
@@ -20,8 +20,6 @@ module Sisimai
20
20
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
21
21
  }
22
22
  Indicators = Sisimai::MSP.INDICATORS
23
- LongFields = Sisimai::RFC5322.LONGFIELDS
24
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
25
23
 
26
24
  def description; return 'SendGrid: http://sendgrid.com/'; end
27
25
  def smtpagent; return 'US::SendGrid'; end
@@ -50,12 +48,11 @@ module Sisimai
50
48
  return nil unless mhead['subject'] =~ Re0[:'subject']
51
49
 
52
50
  require 'sisimai/datetime'
53
- dscontents = []; dscontents << Sisimai::MSP.DELIVERYSTATUS
51
+ dscontents = [Sisimai::MSP.DELIVERYSTATUS]
54
52
  hasdivided = mbody.split("\n")
55
53
  havepassed = ['']
56
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
57
- rfc822part = '' # (String) message/rfc822-headers part
58
- previousfn = '' # (String) Previous field name
54
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
55
+ blanklines = 0 # (Integer) The number of blank lines
59
56
  readcursor = 0 # (Integer) Points the current cursor position
60
57
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
61
58
  commandtxt = '' # (String) SMTP Command name begin with the string '>>>'
@@ -67,12 +64,13 @@ module Sisimai
67
64
 
68
65
  hasdivided.each do |e|
69
66
  # Save the current line for the next loop
70
- havepassed << e; p = havepassed[-2]
67
+ havepassed << e
68
+ p = havepassed[-2]
71
69
 
72
70
  if readcursor == 0
73
71
  # Beginning of the bounce message or delivery status part
74
72
  if e =~ Re1[:begin]
75
- readcursor |= Indicators[:'deliverystatus']
73
+ readcursor |= Indicators[:deliverystatus]
76
74
  next
77
75
  end
78
76
  end
@@ -87,30 +85,16 @@ module Sisimai
87
85
 
88
86
  if readcursor & Indicators[:'message-rfc822'] > 0
89
87
  # After "message/rfc822"
90
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
91
- # Get required headers only
92
- lhs = cv[1].downcase
93
- previousfn = ''
94
- next unless RFC822Head.key?(lhs)
95
-
96
- previousfn = lhs
97
- rfc822part += e + "\n"
98
-
99
- elsif e =~ /\A[ \t]+/
100
- # Continued line from the previous line
101
- next if rfc822next[previousfn]
102
- rfc822part += e + "\n" if LongFields.key?(previousfn)
103
-
104
- else
105
- # Check the end of headers in rfc822 part
106
- next unless LongFields.key?(previousfn)
107
- next unless e.empty?
108
- rfc822next[previousfn] = true
88
+ if e.empty?
89
+ blanklines += 1
90
+ break if blanklines > 1
91
+ next
109
92
  end
93
+ rfc822list << e
110
94
 
111
95
  else
112
96
  # Before "message/rfc822"
113
- next if readcursor & Indicators[:'deliverystatus'] == 0
97
+ next if readcursor & Indicators[:deliverystatus] == 0
114
98
  next if e.empty?
115
99
 
116
100
  if connvalues == connheader.keys.size
@@ -234,19 +218,11 @@ module Sisimai
234
218
  end
235
219
  end
236
220
 
237
- if mhead['received'].size > 0
238
- # Get localhost and remote host name from Received header.
239
- r0 = mhead['received']
240
- %w|lhost rhost|.each { |a| e[a] ||= '' }
241
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
242
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
243
- end
244
-
245
- e['spec'] ||= 'SMTP'
246
221
  e['agent'] = Sisimai::MSP::US::SendGrid.smtpagent
247
222
  e['command'] = commandtxt
248
223
  end
249
224
 
225
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
250
226
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
251
227
  end
252
228