sisimai 4.18.1 → 4.19.0
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.
- checksums.yaml +4 -4
- data/ANALYTICAL-PRECISION +9 -9
- data/Changes +8 -0
- data/README-JA.md +31 -2
- data/README.md +32 -3
- data/lib/sisimai.rb +20 -7
- data/lib/sisimai/data.rb +3 -0
- data/lib/sisimai/message.rb +39 -6
- data/lib/sisimai/mime.rb +5 -5
- data/lib/sisimai/msp/us/amazonses.rb +17 -4
- data/lib/sisimai/reason.rb +54 -0
- data/lib/sisimai/reason/systemerror.rb +1 -0
- data/lib/sisimai/reason/userunknown.rb +2 -1
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/README.md +52 -0
- data/set-of-emails/maildir/bsd/exchange2007-03.eml +1178 -0
- data/set-of-emails/maildir/bsd/postfix-22.eml +73 -0
- data/set-of-emails/maildir/bsd/postfix-23.eml +75 -0
- data/set-of-emails/maildir/bsd/postfix-24.eml +73 -0
- data/set-of-emails/maildir/bsd/postfix-25.eml +73 -0
- data/set-of-emails/maildir/bsd/postfix-26.eml +73 -0
- data/set-of-emails/maildir/bsd/postfix-27.eml +66 -0
- data/set-of-emails/maildir/bsd/qmail-10.eml +32 -0
- data/set-of-emails/maildir/bsd/qmail-11.eml +73 -0
- data/set-of-emails/maildir/bsd/qmail-12.eml +24 -0
- data/set-of-emails/maildir/bsd/rfc3464-28.eml +0 -0
- data/set-of-emails/maildir/bsd/rfc3464-30.eml +1173 -0
- data/set-of-emails/maildir/bsd/rfc3834-04.eml +29 -0
- data/set-of-emails/maildir/bsd/rfc3834-05.eml +29 -0
- data/set-of-emails/maildir/bsd/sendmail-41.eml +125 -0
- data/set-of-emails/maildir/bsd/us-amazonses-05.eml +73 -0
- data/set-of-emails/maildir/bsd/us-amazonses-06.eml +73 -0
- data/set-of-emails/maildir/bsd/us-amazonses-07.eml +73 -0
- data/set-of-emails/maildir/bsd/us-amazonses-08.eml +73 -0
- data/set-of-emails/maildir/dos/exchange2003-01.eml +31 -0
- data/set-of-emails/maildir/dos/exchange2007-01.eml +151 -0
- data/set-of-emails/maildir/mac/exchange2003-01.eml +1 -0
- data/set-of-emails/maildir/mac/exchange2007-01.eml +1 -10
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86487325ab861bea9bb3cb7a20682bde85aafb3c
|
4
|
+
data.tar.gz: 57a722c34477947dcf2d899c4b5ff3a3bcf76bc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0f428825f76e9746aacfe0db95eab9f9540cb85ebda8557a13794178c6932f9ebd578a7d13948c1a3d4f859fd77bcd36ffef9e00e89e3ca98cc3369f8409180
|
7
|
+
data.tar.gz: 632fb856aac2a29bfd99ba5a7db435d3c33fb6ed0b2b7259c6c299ef0c050eef42ef702e986a903c83ff77f92e7d76c2b2c6b3268c5fb97cf22bd458912d51f3
|
data/ANALYTICAL-PRECISION
CHANGED
@@ -6,7 +6,7 @@ MTA::ApacheJames ........ 0/0006 0.0000 Java Apache Mail Enterprise Server
|
|
6
6
|
MTA::Courier ............ 14/0016 0.8750 Courier MTA
|
7
7
|
MTA::Domino ............. 6/0015 0.4000 IBM Domino Server
|
8
8
|
MTA::Exchange2003 ....... 1/0051 0.0196 Microsoft Exchange Server 2003
|
9
|
-
MTA::Exchange2007 .......
|
9
|
+
MTA::Exchange2007 ....... 5/0007 0.7143 Microsoft Exchange Server 2007
|
10
10
|
MTA::Exim ............... 144/0174 0.8276 Exim
|
11
11
|
MTA::IMailServer ........ 0/0045 0.0000 IPSWITCH IMail Server
|
12
12
|
MTA::InterScanMSS ....... 0/0009 0.0000 Trend Micro InterScan Messaging Security Suite
|
@@ -17,8 +17,8 @@ MTA::McAfee ............. 0/0010 0.0000 McAfee Email Appliance
|
|
17
17
|
MTA::MessagingServer .... 19/0022 0.8636 Oracle Communications Messaging Server
|
18
18
|
MTA::Notes .............. 0/0012 0.0000 Lotus Notes
|
19
19
|
MTA::OpenSMTPD .......... 5/0023 0.2174 OpenSMTPD
|
20
|
-
MTA::Postfix ............
|
21
|
-
MTA::Sendmail ...........
|
20
|
+
MTA::Postfix ............ 171/0189 0.9048 Postfix
|
21
|
+
MTA::Sendmail ........... 331/0253 1.0000 V8Sendmail: /usr/sbin/sendmail
|
22
22
|
MTA::SurfControl ........ 6/0008 0.7500 WebSense SurfControl
|
23
23
|
MTA::V5sendmail ......... 0/0386 0.0000 Sendmail version 5
|
24
24
|
MTA::X1 ................. 0/0007 0.0000 Unknown MTA #1
|
@@ -27,7 +27,7 @@ MTA::X3 ................. 0/0012 0.0000 Unknown MTA #3
|
|
27
27
|
MTA::X4 ................. 0/0029 0.0000 Unknown MTA #4 qmail clones
|
28
28
|
MTA::X5 ................. 3/0003 1.0000 Unknown MTA #5
|
29
29
|
MTA::mFILTER ............ 0/0009 0.0000 Digital Arts m-FILTER
|
30
|
-
MTA::qmail .............. 52/
|
30
|
+
MTA::qmail .............. 52/0082 0.6341 qmail
|
31
31
|
MSP::DE::EinsUndEins .... 0/0003 0.0000 1&1: http://www.1and1.de
|
32
32
|
MSP::DE::GMX ............ 0/0010 0.0000 GMX: http://www.gmx.net
|
33
33
|
MSP::JP::Biglobe ........ 5/0007 0.7143 BIGLOBE: http://www.biglobe.ne.jp
|
@@ -36,7 +36,7 @@ MSP::JP::KDDI ........... 6/0006 1.0000 au by KDDI: http://www.au.kddi.com
|
|
36
36
|
MSP::RU::MailRu ......... 4/0014 0.2857 @mail.ru: https://mail.ru
|
37
37
|
MSP::RU::Yandex ......... 4/0007 0.5714 Yandex.Mail: http://www.yandex.ru
|
38
38
|
MSP::UK::MessageLabs .... 2/0002 1.0000 Symantec.cloud http://www.messagelabs.com
|
39
|
-
MSP::US::AmazonSES ......
|
39
|
+
MSP::US::AmazonSES ...... 22/0022 1.0000 Amazon SES(Sending): http://aws.amazon.com/ses/
|
40
40
|
MSP::US::AmazonWorkMail . 8/0012 0.6667 Amazon WorkMail: https://aws.amazon.com/workmail/
|
41
41
|
MSP::US::Aol ............ 18/0021 0.8571 Aol Mail: http://www.aol.com
|
42
42
|
MSP::US::Bigfoot ........ 2/0002 1.0000 Bigfoot: http://www.bigfoot.com
|
@@ -50,8 +50,8 @@ MSP::US::Verizon ........ 3/0003 1.0000 Verizon Wireless: http://www.verizo
|
|
50
50
|
MSP::US::Yahoo .......... 0/0009 0.0000 Yahoo! MAIL: https://www.yahoo.com
|
51
51
|
MSP::US::Zoho ........... 0/0011 0.0000 Zoho Mail: https://www.zoho.com
|
52
52
|
ARF ..................... 9/0050 0.1800 Abuse Feedback Reporting Format
|
53
|
-
RFC3464 .................
|
54
|
-
RFC3834 ................. 0/
|
53
|
+
RFC3464 ................. 136/0277 0.4910 Fallback Module for MTAs
|
54
|
+
RFC3834 ................. 0/0006 0.0000 Detector for auto replied message
|
55
55
|
-------------------------------------------------------------------------------
|
56
|
-
bounceHammer 2.7.13p3
|
57
|
-
Sisimai 4.
|
56
|
+
bounceHammer 2.7.13p3 1201/2178 0.5514
|
57
|
+
Sisimai 4.19.0 2178/2178 1.0000
|
data/Changes
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
Revision history for Ruby version of Sisimai
|
2
2
|
|
3
|
+
4.19.0 Tue, 18 Oct 2016 14:19:10 +0900 (JST)
|
4
|
+
- Implement a callback feature at Sisimai.make and Sisimai.dump methods.
|
5
|
+
More imformation about the feature are available at the following pages:
|
6
|
+
- http://libsisimai.org/en/usage#callback
|
7
|
+
- http://libsisimai.org/ja/usage#callback
|
8
|
+
- Implement Sisimai.match() method: issue #52.
|
9
|
+
- Minor bug fix in Sisimai::MSP::US::AmazonSES.scan() method.
|
10
|
+
|
3
11
|
4.18.1 Sun, 11 Sep 2016 20:05:20 +0900 (JST)
|
4
12
|
- Fix bug in Sisimai::Mail::STDIN.read() method reported at issue #61.
|
5
13
|
Thanks to @yaegassy.
|
data/README-JA.md
CHANGED
@@ -127,6 +127,35 @@ puts Sisimai.dump('/path/to/mbox', delivered: true)
|
|
127
127
|
[{"recipient": "kijitora@example.jp", "addresser": "shironeko@1jo.example.org", "feedbacktype": "", "action": "failed", "subject": "Nyaaaaan", "smtpcommand": "DATA", "diagnosticcode": "550 Unknown user kijitora@example.jp", "listid": "", "destination": "example.jp", "smtpagent": "Courier", "lhost": "1jo.example.org", "deliverystatus": "5.0.0", "timestamp": 1291954879, "messageid": "201012100421.oBA4LJFU042012@1jo.example.org", "diagnostictype": "SMTP", "timezoneoffset": "+0900", "reason": "filtered", "token": "ce999a4c869e3f5e4d8a77b2e310b23960fb32ab", "alias": "", "senderdomain": "1jo.example.org", "rhost": "mfsmax.example.jp"}, {"diagnostictype": "SMTP", "timezoneoffset": "+0900", "reason": "userunknown", "timestamp": 1381900535, "messageid": "E1C50F1B-1C83-4820-BC36-AC6FBFBE8568@example.org", "token": "9fe754876e9133aae5d20f0fd8dd7f05b4e9d9f0", "alias": "", "senderdomain": "example.org", "rhost": "mx.bouncehammer.jp", "action": "failed", "addresser": "kijitora@example.org", "recipient": "userunknown@bouncehammer.jp", "feedbacktype": "", "smtpcommand": "DATA", "subject": "バウンスメールのテスト(日本語)", "destination": "bouncehammer.jp", "listid": "", "diagnosticcode": "550 5.1.1 <userunknown@bouncehammer.jp>... User Unknown", "deliverystatus": "5.1.1", "lhost": "p0000-ipbfpfx00kyoto.kyoto.example.co.jp", "smtpagent": "Sendmail"}]
|
128
128
|
```
|
129
129
|
|
130
|
+
コールバック機能
|
131
|
+
----------------
|
132
|
+
Sisimai 4.19.0から、`Sisimai.make()`と`Sisimai.dump()`にLamda(Procオブジェクト)
|
133
|
+
を引数`hook`に指定できるようになりました。`hook`に指定したコードによって処理さ
|
134
|
+
れた結果は`Sisimai::Data.catch`メソッドで得ることができます。
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
#! /usr/bin/env ruby
|
138
|
+
require 'sisimai'
|
139
|
+
callbackto = lambda do |v|
|
140
|
+
r = { 'x-mailer' => '' }
|
141
|
+
|
142
|
+
if cv = v['message'].match(/^X-Mailer:\s*(.+)$/)
|
143
|
+
r['x-mailer'] = cv[1]
|
144
|
+
end
|
145
|
+
return r
|
146
|
+
end
|
147
|
+
|
148
|
+
data = Sisimai.make('/path/to/mbox', hook: callbackto)
|
149
|
+
json = Sisimai.dump('/path/to/mbox', hook: callbackto)
|
150
|
+
|
151
|
+
puts data[0].catch['x-mailer'] # Apple Mail (2.1283)
|
152
|
+
```
|
153
|
+
|
154
|
+
コールバック機能のより詳細な使い方は
|
155
|
+
[Sisimai | 解析方法 - コールバック機能](http://libsisimai.org/ja/usage/#callback)
|
156
|
+
をご覧ください。
|
157
|
+
|
158
|
+
|
130
159
|
ワンライナーで
|
131
160
|
--------------
|
132
161
|
|
@@ -148,8 +177,8 @@ Perl版Sisimaiとの違い
|
|
148
177
|
| メール解析速度(1000通のメール) | 3.30秒 | 2.33秒 |
|
149
178
|
| インストール方法 | gem install | cpanm |
|
150
179
|
| 依存モジュール数(コアモジュールを除く) | 1モジュール | 2モジュール |
|
151
|
-
| LOC:ソースコードの行数 |
|
152
|
-
| テスト件数(spec/,t/,xt/ディレクトリ) |
|
180
|
+
| LOC:ソースコードの行数 | 11700行 | 8600行 |
|
181
|
+
| テスト件数(spec/,t/,xt/ディレクトリ) | 103800件 | 184100件 |
|
153
182
|
| ライセンス | 二条項BSD | 二条項BSD |
|
154
183
|
| 開発会社によるサポート契約 | 準備中 | 提供中 |
|
155
184
|
|
data/README.md
CHANGED
@@ -126,6 +126,35 @@ puts Sisimai.dump('/path/to/mbox', delivered: true)
|
|
126
126
|
[{"recipient": "kijitora@example.jp", "addresser": "shironeko@1jo.example.org", "feedbacktype": "", "action": "failed", "subject": "Nyaaaaan", "smtpcommand": "DATA", "diagnosticcode": "550 Unknown user kijitora@example.jp", "listid": "", "destination": "example.jp", "smtpagent": "Courier", "lhost": "1jo.example.org", "deliverystatus": "5.0.0", "timestamp": 1291954879, "messageid": "201012100421.oBA4LJFU042012@1jo.example.org", "diagnostictype": "SMTP", "timezoneoffset": "+0900", "reason": "filtered", "token": "ce999a4c869e3f5e4d8a77b2e310b23960fb32ab", "alias": "", "senderdomain": "1jo.example.org", "rhost": "mfsmax.example.jp"}, {"diagnostictype": "SMTP", "timezoneoffset": "+0900", "reason": "userunknown", "timestamp": 1381900535, "messageid": "E1C50F1B-1C83-4820-BC36-AC6FBFBE8568@example.org", "token": "9fe754876e9133aae5d20f0fd8dd7f05b4e9d9f0", "alias": "", "senderdomain": "example.org", "rhost": "mx.bouncehammer.jp", "action": "failed", "addresser": "kijitora@example.org", "recipient": "userunknown@bouncehammer.jp", "feedbacktype": "", "smtpcommand": "DATA", "subject": "バウンスメールのテスト(日本語)", "destination": "bouncehammer.jp", "listid": "", "diagnosticcode": "550 5.1.1 <userunknown@bouncehammer.jp>... User Unknown", "deliverystatus": "5.1.1", "lhost": "p0000-ipbfpfx00kyoto.kyoto.example.co.jp", "smtpagent": "Sendmail"}]
|
127
127
|
```
|
128
128
|
|
129
|
+
Callback Feature
|
130
|
+
----------------
|
131
|
+
Beginning with Sisimai 4.19.0, `make()` and `dump()` methods of Sisimai accept
|
132
|
+
a Lambda (Proc object) in `hook` argument for setting a callback method and
|
133
|
+
getting the results generated by the method via `Sisimai::Data.catch` method.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
#! /usr/bin/env ruby
|
137
|
+
require 'sisimai'
|
138
|
+
callbackto = lambda do |v|
|
139
|
+
r = { 'x-mailer' => '' }
|
140
|
+
|
141
|
+
if cv = v['message'].match(/^X-Mailer:\s*(.+)$/)
|
142
|
+
r['x-mailer'] = cv[1]
|
143
|
+
end
|
144
|
+
return r
|
145
|
+
end
|
146
|
+
|
147
|
+
data = Sisimai.make('/path/to/mbox', hook: callbackto)
|
148
|
+
json = Sisimai.dump('/path/to/mbox', hook: callbackto)
|
149
|
+
|
150
|
+
puts data[0].catch['x-mailer'] # Apple Mail (2.1283)
|
151
|
+
```
|
152
|
+
|
153
|
+
More information about the callback feature is available at
|
154
|
+
[Sisimai | How To Parse - Callback](http://libsisimai.org/en/usage/#callback)
|
155
|
+
Page.
|
156
|
+
|
157
|
+
|
129
158
|
One-Liner
|
130
159
|
---------
|
131
160
|
|
@@ -147,9 +176,9 @@ and bounceHammer are available at
|
|
147
176
|
| Analytical precision ratio(2000 emails)[1] | 1.00 | 1.00 |
|
148
177
|
| The speed of parsing email(1000 emails) | 3.30s | 2.33s |
|
149
178
|
| How to install | gem install | cpanm |
|
150
|
-
| Dependencies (Except core modules) | 1
|
151
|
-
| LOC:Source lines of code |
|
152
|
-
| The number of tests(spec/,t/,xt/) directory |
|
179
|
+
| Dependencies (Except core modules) | 1 module | 2 modules |
|
180
|
+
| LOC:Source lines of code | 11750 lines | 8600 lines |
|
181
|
+
| The number of tests(spec/,t/,xt/) directory | 103800 tests | 184100 tests |
|
153
182
|
| License | BSD 2-Clause | BSD 2-Clause |
|
154
183
|
| Support Contract provided by Developer | Coming soon | Available |
|
155
184
|
|
data/lib/sisimai.rb
CHANGED
@@ -16,6 +16,7 @@ module Sisimai
|
|
16
16
|
# @param [String] path Path to mbox or Maildir/
|
17
17
|
# @param [Hash] argvs Parser options(delivered=false)
|
18
18
|
# @options argvs [Boolean] delivered true: Include "delivered" reason
|
19
|
+
# @options argvs [Lambda] hook Lambda object to be called back
|
19
20
|
# @return [Array] Parsed objects
|
20
21
|
# @return [nil] nil if the argument was wrong or an empty array
|
21
22
|
def make(path, **argvs)
|
@@ -24,17 +25,19 @@ module Sisimai
|
|
24
25
|
require 'sisimai/mail'
|
25
26
|
mail = Sisimai::Mail.new(path)
|
26
27
|
list = []
|
27
|
-
opts = argvs[:delivered] || false
|
28
28
|
|
29
29
|
return nil unless mail
|
30
30
|
require 'sisimai/data'
|
31
31
|
require 'sisimai/message'
|
32
32
|
|
33
|
+
methodargv = { :delivered => argvs[:delivered] || false }
|
34
|
+
hookmethod = argvs[:hook] || nil
|
35
|
+
|
33
36
|
while r = mail.read do
|
34
37
|
# Read and parse each mail file
|
35
|
-
mesg = Sisimai::Message.new(data: r)
|
38
|
+
mesg = Sisimai::Message.new(data: r, hook: hookmethod)
|
36
39
|
next if mesg.void
|
37
|
-
data = Sisimai::Data.make(data: mesg, delivered:
|
40
|
+
data = Sisimai::Data.make(data: mesg, delivered: methodargv)
|
38
41
|
next unless data
|
39
42
|
list.concat(data) if data.size > 0
|
40
43
|
end
|
@@ -47,18 +50,19 @@ module Sisimai
|
|
47
50
|
# @param [String] path Path to mbox or Maildir/
|
48
51
|
# @param [Hash] argvs Parser options
|
49
52
|
# @options argvs [Integer] delivered true: Include "delivered" reason
|
53
|
+
# @options argvs [Lambda] hook Lambda object to be called back
|
50
54
|
# @return [String] Parsed data as JSON text
|
51
55
|
def dump(path, **argvs)
|
52
56
|
return nil unless path
|
53
57
|
|
54
|
-
|
58
|
+
nyaan = Sisimai.make(path, argvs) || []
|
55
59
|
if RUBY_PLATFORM =~ /java/
|
56
60
|
# java-based ruby environment like JRuby.
|
57
61
|
require 'jrjackson'
|
58
|
-
jsonstring = JrJackson::Json.dump(
|
62
|
+
jsonstring = JrJackson::Json.dump(nyaan)
|
59
63
|
else
|
60
64
|
require 'oj'
|
61
|
-
jsonstring = Oj.dump(
|
65
|
+
jsonstring = Oj.dump(nyaan, :mode => :compat)
|
62
66
|
end
|
63
67
|
return jsonstring
|
64
68
|
end
|
@@ -104,11 +108,20 @@ module Sisimai
|
|
104
108
|
# Call .description() method of Sisimai::Reason::*
|
105
109
|
r = 'Sisimai::Reason::' + e
|
106
110
|
require r.gsub('::', '/').downcase
|
107
|
-
table[
|
111
|
+
table[e.to_sym] = Module.const_get(r).send(:description)
|
108
112
|
end
|
109
113
|
|
110
114
|
return table
|
111
115
|
end
|
116
|
+
|
117
|
+
# Try to match with message patterns
|
118
|
+
# @param [String] Error message text
|
119
|
+
# @return [String] Reason text
|
120
|
+
def match(argvs = '')
|
121
|
+
return nil if argvs.empty?
|
122
|
+
require 'sisimai/reason'
|
123
|
+
return Sisimai::Reason.match(argvs)
|
124
|
+
end
|
112
125
|
end
|
113
126
|
end
|
114
127
|
|
data/lib/sisimai/data.rb
CHANGED
@@ -14,6 +14,7 @@ module Sisimai
|
|
14
14
|
require 'sisimai/datetime'
|
15
15
|
|
16
16
|
@@rwaccessors = [
|
17
|
+
:catch, # [?] Results generated by hook method
|
17
18
|
:token, # [String] Message token/MD5 Hex digest value
|
18
19
|
:lhost, # [String] local host name/Local MTA
|
19
20
|
:rhost, # [String] Remote host name/Remote MTA
|
@@ -83,6 +84,7 @@ module Sisimai
|
|
83
84
|
@timezoneoffset = argvs['timezoneoffset'] || '+0000'
|
84
85
|
@lhost = argvs['lhost'] || ''
|
85
86
|
@rhost = argvs['rhost'] || ''
|
87
|
+
@catch = argvs['catch'] || nil
|
86
88
|
@reason = argvs['reason'] || ''
|
87
89
|
@listid = argvs['listid'] || ''
|
88
90
|
@subject = argvs['subject'] || ''
|
@@ -148,6 +150,7 @@ module Sisimai
|
|
148
150
|
o = nil # Sisimai::Data Object
|
149
151
|
r = nil # Reason text
|
150
152
|
p = {
|
153
|
+
'catch' => messageobj.catch || nil,
|
151
154
|
'lhost' => e['lhost'] || '',
|
152
155
|
'rhost' => e['rhost'] || '',
|
153
156
|
'alias' => e['alias'] || '',
|
data/lib/sisimai/message.rb
CHANGED
@@ -17,6 +17,7 @@ module Sisimai
|
|
17
17
|
:header, # [Hash] Header part of a email
|
18
18
|
:ds, # [Array] Parsed data by Sisimai::MTA::*
|
19
19
|
:rfc822, # [Hash] Header part of the original message
|
20
|
+
:catch, # [?] The results returned by hook method
|
20
21
|
]
|
21
22
|
@@rwaccessors.each { |e| attr_accessor e }
|
22
23
|
|
@@ -41,7 +42,10 @@ module Sisimai
|
|
41
42
|
# Constructor of Sisimai::Message
|
42
43
|
# @param [String] data Email text data
|
43
44
|
# @param [Hash] argvs Module to be loaded
|
44
|
-
# @options argvs [String] data
|
45
|
+
# @options argvs [String] :data Entire email message
|
46
|
+
# @options argvs [Array] :load User defined MTA module list
|
47
|
+
# @options argvs [Array] :order The order of MTA modules
|
48
|
+
# @options argvs [Code] :hook Reference to callback method
|
45
49
|
# @return [Sisimai::Message] Structured email data or Undef if each
|
46
50
|
# value of the arguments are missing
|
47
51
|
def initialize(data: '', **argvs)
|
@@ -50,9 +54,9 @@ module Sisimai
|
|
50
54
|
email = data
|
51
55
|
email = email.scrub('?')
|
52
56
|
email = email.gsub("\r\n", "\n")
|
53
|
-
methodargv = { 'data' => email }
|
57
|
+
methodargv = { 'data' => email, 'hook' => argvs[:hook] || nil }
|
54
58
|
|
55
|
-
[:
|
59
|
+
[:load, :order].each do |e|
|
56
60
|
# Order of MTA, MSP modules
|
57
61
|
next unless argvs.key?(e)
|
58
62
|
next unless argvs[e].is_a? Array
|
@@ -68,6 +72,7 @@ module Sisimai
|
|
68
72
|
@header = parameters['header']
|
69
73
|
@ds = parameters['ds']
|
70
74
|
@rfc822 = parameters['rfc822']
|
75
|
+
@catch = parameters['catch'] || nil
|
71
76
|
end
|
72
77
|
|
73
78
|
# Check whether the object has valid content or not
|
@@ -80,11 +85,22 @@ module Sisimai
|
|
80
85
|
# Make data structure from the email message(a body part and headers)
|
81
86
|
# @param [Hash] argvs Email data
|
82
87
|
# @options argvs [String] data Entire email message
|
88
|
+
# @options argvs [Array] load User defined MTA module list
|
89
|
+
# @options argvs [Array] order The order of MTA modules
|
90
|
+
# @options argvs [Code] hook Reference to callback method
|
83
91
|
# @return [Hash] Resolved data structure
|
84
92
|
def self.make(argvs)
|
85
93
|
email = argvs['data']
|
86
94
|
|
87
95
|
processing = { 'from' => '', 'header' => {}, 'rfc822' => '', 'ds' => [] }
|
96
|
+
hookmethod = argvs['hook'] || nil
|
97
|
+
processing = {
|
98
|
+
'from' => '', # From_ line
|
99
|
+
'header' => {}, # Email header
|
100
|
+
'rfc822' => '', # Original message part
|
101
|
+
'ds' => [], # Parsed data, Delivery Status
|
102
|
+
'catch' => nil, # Data parsed by callback method
|
103
|
+
}
|
88
104
|
mtamodules = []
|
89
105
|
extheaders = ExtHeaders
|
90
106
|
tobeloaded = []
|
@@ -124,11 +140,11 @@ module Sisimai
|
|
124
140
|
tobeloaded << e
|
125
141
|
end
|
126
142
|
|
127
|
-
#
|
143
|
+
# 1. Split email data to headers and a body part.
|
128
144
|
aftersplit = Sisimai::Message.divideup(email)
|
129
145
|
return nil if aftersplit.empty?
|
130
146
|
|
131
|
-
#
|
147
|
+
# 2. Convert email headers from text to hash reference
|
132
148
|
headerargv['extheaders'] = extheaders
|
133
149
|
headerargv['tryonfirst'] = []
|
134
150
|
processing['from'] = aftersplit['from']
|
@@ -141,6 +157,7 @@ module Sisimai
|
|
141
157
|
|
142
158
|
# 4. Rewrite message body for detecting the bounce reason
|
143
159
|
methodargv = {
|
160
|
+
'hook' => hookmethod,
|
144
161
|
'mail' => processing,
|
145
162
|
'body' => aftersplit['body'],
|
146
163
|
'tryonfirst' => headerargv['tryonfirst'],
|
@@ -150,7 +167,8 @@ module Sisimai
|
|
150
167
|
|
151
168
|
return nil unless bouncedata
|
152
169
|
return nil if bouncedata.empty?
|
153
|
-
processing['ds']
|
170
|
+
processing['ds'] = bouncedata['ds']
|
171
|
+
processing['catch'] = bouncedata['catch']
|
154
172
|
|
155
173
|
# 5. Rewrite headers of the original message in the body part
|
156
174
|
rfc822part = bouncedata['rfc822']
|
@@ -396,6 +414,8 @@ module Sisimai
|
|
396
414
|
def self.parse(argvs)
|
397
415
|
mesgentity = argvs['mail']
|
398
416
|
bodystring = argvs['body']
|
417
|
+
hookmethod = argvs['hook'] || nil
|
418
|
+
havacaught = nil
|
399
419
|
tryonfirst = argvs['tryonfirst'] || []
|
400
420
|
tobeloaded = argvs['tobeloaded'] || []
|
401
421
|
mailheader = mesgentity['header']
|
@@ -450,6 +470,17 @@ module Sisimai
|
|
450
470
|
end
|
451
471
|
end
|
452
472
|
|
473
|
+
# Call the hook method
|
474
|
+
if hookmethod.is_a? Proc
|
475
|
+
# Execute hook method
|
476
|
+
begin
|
477
|
+
p = { 'headers' => mailheader, 'message' => bodystring }
|
478
|
+
havecaught = hookmethod.call(p)
|
479
|
+
rescue StandardError => ce
|
480
|
+
warn sprintf(" ***warning: Something is wrong in hook method :%s", ce.to_s)
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
453
484
|
# EXPAND_FORWARDED_MESSAGE:
|
454
485
|
# Check whether or not the message is a bounce mail.
|
455
486
|
# Pre-Process email body if it is a forwarded bounce message.
|
@@ -537,6 +568,8 @@ module Sisimai
|
|
537
568
|
break
|
538
569
|
end
|
539
570
|
end
|
571
|
+
|
572
|
+
scannedset['catch'] = havecaught if scannedset
|
540
573
|
return scannedset
|
541
574
|
end
|
542
575
|
|
data/lib/sisimai/mime.rb
CHANGED
@@ -29,17 +29,17 @@ module Sisimai
|
|
29
29
|
return false unless argv1
|
30
30
|
|
31
31
|
argv1 = argv1.delete('"')
|
32
|
-
|
32
|
+
piece = []
|
33
33
|
isnot = false
|
34
34
|
|
35
35
|
if argv1 =~ /[ ]/
|
36
36
|
# Multiple MIME-Encoded strings in a line
|
37
|
-
|
37
|
+
piece = argv1.split(' ')
|
38
38
|
else
|
39
|
-
|
39
|
+
piece << argv1
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
piece.each do |e|
|
43
43
|
# Check all the string in the array
|
44
44
|
next if e =~ /[ \t]*=[?][-_0-9A-Za-z]+[?][BbQq][?].+[?]=?[ \t]*\z/
|
45
45
|
isnot = true
|
@@ -224,7 +224,7 @@ module Sisimai
|
|
224
224
|
return nil unless argv1
|
225
225
|
value = ''
|
226
226
|
|
227
|
-
if cv = argv1.match(/\bboundary=([^ ]+)/)
|
227
|
+
if cv = argv1.match(/\bboundary=([^ ]+)/i)
|
228
228
|
# Content-Type: multipart/mixed; boundary=Apple-Mail-5--931376066
|
229
229
|
# Content-Type: multipart/report; report-type=delivery-status;
|
230
230
|
# boundary="n6H9lKZh014511.1247824040/mx.example.jp"
|
@@ -10,12 +10,17 @@ module Sisimai
|
|
10
10
|
require 'sisimai/rfc5322'
|
11
11
|
|
12
12
|
# http://aws.amazon.com/ses/
|
13
|
+
ReE = { :'x-mailer' => %r/Amazon[ ]WorkMail/ }
|
13
14
|
Re0 = {
|
14
15
|
:from => %r/\AMAILER-DAEMON[@]email[-]bounces[.]amazonses[.]com\z/,
|
15
16
|
:subject => %r/\ADelivery Status Notification [(]Failure[)]\z/,
|
16
17
|
}
|
17
18
|
Re1 = {
|
18
|
-
:begin => %r/\
|
19
|
+
:begin => %r/\A(?:
|
20
|
+
The[ ]following[ ]message[ ]to[ ][<]
|
21
|
+
|An[ ]error[ ]occurred[ ]while[ ]trying[ ]to[ ]deliver[ ]the[ ]mail[ ]
|
22
|
+
)
|
23
|
+
/x,
|
19
24
|
:rfc822 => %r|\Acontent-type: message/rfc822\z|,
|
20
25
|
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
21
26
|
}
|
@@ -30,7 +35,8 @@ module Sisimai
|
|
30
35
|
# X-SenderID: Sendmail Sender-ID Filter v1.0.0 nijo.example.jp p7V3i843003008
|
31
36
|
# X-Original-To: 000001321defbd2a-788e31c8-2be1-422f-a8d4-cf7765cc9ed7-000000@email-bounces.amazonses.com
|
32
37
|
# X-AWS-Outgoing: 199.255.192.156
|
33
|
-
|
38
|
+
# X-SES-Outgoing: 2016.10.12-54.240.27.6
|
39
|
+
def headerlist; return ['X-AWS-Outgoing', 'X-SES-Outgoing']; end
|
34
40
|
def pattern; return Re0; end
|
35
41
|
|
36
42
|
# Parse bounce messages from Amazon SES
|
@@ -47,7 +53,14 @@ module Sisimai
|
|
47
53
|
def scan(mhead, mbody)
|
48
54
|
return nil unless mhead
|
49
55
|
return nil unless mbody
|
50
|
-
|
56
|
+
|
57
|
+
match = 0
|
58
|
+
xmail = mhead['x-mailer'] || ''
|
59
|
+
|
60
|
+
return nil if mhead['x-mailer'] =~ ReE[:'x-mailer']
|
61
|
+
match += 1 if mhead['x-aws-outgoing']
|
62
|
+
match += 1 if mhead['x-ses-outgoing']
|
63
|
+
return nil if match == 0
|
51
64
|
|
52
65
|
dscontents = [Sisimai::MSP.DELIVERYSTATUS]
|
53
66
|
hasdivided = mbody.split("\n")
|
@@ -168,7 +181,7 @@ module Sisimai
|
|
168
181
|
#
|
169
182
|
# Reporting-MTA: dns; a192-79.smtp-out.amazonses.com
|
170
183
|
#
|
171
|
-
if cv = e.match(/\A[Rr]eporting-MTA:[ ]*
|
184
|
+
if cv = e.match(/\A[Rr]eporting-MTA:[ ]*[DNSdns]+;[ ]*(.+)\z/)
|
172
185
|
# Reporting-MTA: dns; mx.example.jp
|
173
186
|
next if connheader['lhost'].size > 0
|
174
187
|
connheader['lhost'] = cv[1].downcase
|