sisimai 4.22.7 → 4.23.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/ChangeLog.md +15 -0
- data/README-JA.md +13 -8
- data/README.md +14 -9
- data/lib/sisimai.rb +11 -12
- data/lib/sisimai/address.rb +13 -23
- data/lib/sisimai/arf.rb +10 -12
- data/lib/sisimai/bite/email/activehunter.rb +5 -9
- data/lib/sisimai/bite/email/amazonses.rb +12 -18
- data/lib/sisimai/bite/email/amazonworkmail.rb +7 -12
- data/lib/sisimai/bite/email/aol.rb +10 -16
- data/lib/sisimai/bite/email/apachejames.rb +8 -12
- data/lib/sisimai/bite/email/bigfoot.rb +10 -15
- data/lib/sisimai/bite/email/biglobe.rb +7 -11
- data/lib/sisimai/bite/email/courier.rb +11 -15
- data/lib/sisimai/bite/email/domino.rb +8 -13
- data/lib/sisimai/bite/email/einsundeins.rb +7 -11
- data/lib/sisimai/bite/email/exchange2003.rb +11 -15
- data/lib/sisimai/bite/email/exchange2007.rb +7 -11
- data/lib/sisimai/bite/email/exim.rb +20 -27
- data/lib/sisimai/bite/email/ezweb.rb +13 -22
- data/lib/sisimai/bite/email/facebook.rb +7 -10
- data/lib/sisimai/bite/email/fml.rb +4 -7
- data/lib/sisimai/bite/email/gmx.rb +7 -12
- data/lib/sisimai/bite/email/google.rb +6 -12
- data/lib/sisimai/bite/email/gsuite.rb +11 -18
- data/lib/sisimai/bite/email/imailserver.rb +6 -10
- data/lib/sisimai/bite/email/interscanmss.rb +7 -11
- data/lib/sisimai/bite/email/kddi.rb +10 -16
- data/lib/sisimai/bite/email/mailfoundry.rb +6 -9
- data/lib/sisimai/bite/email/mailmarshalsmtp.rb +6 -10
- data/lib/sisimai/bite/email/mailru.rb +12 -16
- data/lib/sisimai/bite/email/mcafee.rb +5 -9
- data/lib/sisimai/bite/email/messagelabs.rb +7 -10
- data/lib/sisimai/bite/email/messagingserver.rb +8 -14
- data/lib/sisimai/bite/email/mfilter.rb +6 -10
- data/lib/sisimai/bite/email/mxlogic.rb +11 -17
- data/lib/sisimai/bite/email/notes.rb +9 -13
- data/lib/sisimai/bite/email/office365.rb +8 -13
- data/lib/sisimai/bite/email/opensmtpd.rb +7 -11
- data/lib/sisimai/bite/email/outlook.rb +9 -13
- data/lib/sisimai/bite/email/postfix.rb +12 -18
- data/lib/sisimai/bite/email/qmail.rb +10 -15
- data/lib/sisimai/bite/email/receivingses.rb +10 -17
- data/lib/sisimai/bite/email/sendgrid.rb +8 -14
- data/lib/sisimai/bite/email/sendmail.rb +8 -12
- data/lib/sisimai/bite/email/surfcontrol.rb +5 -9
- data/lib/sisimai/bite/email/userdefined.rb +5 -8
- data/lib/sisimai/bite/email/v5sendmail.rb +7 -11
- data/lib/sisimai/bite/email/verizon.rb +14 -28
- data/lib/sisimai/bite/email/x1.rb +5 -8
- data/lib/sisimai/bite/email/x2.rb +5 -8
- data/lib/sisimai/bite/email/x3.rb +5 -9
- data/lib/sisimai/bite/email/x4.rb +10 -14
- data/lib/sisimai/bite/email/x5.rb +6 -11
- data/lib/sisimai/bite/email/yahoo.rb +6 -11
- data/lib/sisimai/bite/email/yandex.rb +8 -12
- data/lib/sisimai/bite/email/zoho.rb +7 -12
- data/lib/sisimai/bite/json/amazonses.rb +6 -12
- data/lib/sisimai/bite/json/sendgrid.rb +1 -7
- data/lib/sisimai/data.rb +26 -34
- data/lib/sisimai/datetime.rb +5 -5
- data/lib/sisimai/mail.rb +9 -3
- data/lib/sisimai/mail/maildir.rb +1 -3
- data/lib/sisimai/mail/mbox.rb +1 -1
- data/lib/sisimai/mail/memory.rb +47 -0
- data/lib/sisimai/mail/stdin.rb +1 -1
- data/lib/sisimai/mda.rb +7 -10
- data/lib/sisimai/message.rb +4 -6
- data/lib/sisimai/message/email.rb +16 -24
- data/lib/sisimai/message/json.rb +3 -5
- data/lib/sisimai/mime.rb +13 -18
- data/lib/sisimai/order/email.rb +5 -8
- data/lib/sisimai/order/json.rb +2 -2
- data/lib/sisimai/reason.rb +3 -7
- data/lib/sisimai/reason/blocked.rb +0 -4
- data/lib/sisimai/reason/contenterror.rb +1 -1
- data/lib/sisimai/reason/exceedlimit.rb +2 -5
- data/lib/sisimai/reason/expired.rb +1 -1
- data/lib/sisimai/reason/filtered.rb +1 -4
- data/lib/sisimai/reason/hasmoved.rb +1 -4
- data/lib/sisimai/reason/hostunknown.rb +1 -4
- data/lib/sisimai/reason/mailboxfull.rb +2 -5
- data/lib/sisimai/reason/mesgtoobig.rb +1 -4
- data/lib/sisimai/reason/networkerror.rb +1 -1
- data/lib/sisimai/reason/norelaying.rb +1 -4
- data/lib/sisimai/reason/notaccept.rb +1 -3
- data/lib/sisimai/reason/onhold.rb +1 -5
- data/lib/sisimai/reason/policyviolation.rb +1 -1
- data/lib/sisimai/reason/rejected.rb +2 -6
- data/lib/sisimai/reason/spamdetected.rb +1 -5
- data/lib/sisimai/reason/suspend.rb +2 -5
- data/lib/sisimai/reason/syntaxerror.rb +0 -3
- data/lib/sisimai/reason/systemerror.rb +1 -1
- data/lib/sisimai/reason/systemfull.rb +1 -1
- data/lib/sisimai/reason/toomanyconn.rb +1 -5
- data/lib/sisimai/reason/userunknown.rb +1 -4
- data/lib/sisimai/reason/vacation.rb +1 -1
- data/lib/sisimai/reason/virusdetected.rb +1 -1
- data/lib/sisimai/rfc2606.rb +3 -3
- data/lib/sisimai/rfc3464.rb +12 -20
- data/lib/sisimai/rfc3834.rb +1 -10
- data/lib/sisimai/rfc5322.rb +4 -6
- data/lib/sisimai/rhost.rb +0 -4
- data/lib/sisimai/rhost/exchangeonline.rb +5 -7
- data/lib/sisimai/rhost/franceptt.rb +1 -3
- data/lib/sisimai/rhost/godaddy.rb +2 -4
- data/lib/sisimai/rhost/googleapps.rb +2 -4
- data/lib/sisimai/rhost/kddi.rb +0 -3
- data/lib/sisimai/smtp/error.rb +0 -3
- data/lib/sisimai/smtp/reply.rb +5 -8
- data/lib/sisimai/smtp/status.rb +3 -4
- data/lib/sisimai/string.rb +13 -20
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/email-office365-09.eml +596 -0
- data/set-of-emails/maildir/bsd/email-office365-10.eml +594 -0
- data/set-of-emails/maildir/bsd/email-postfix-45.eml +76 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 124512b04d19c1929badc41c4554e3b84d3ffd5d
|
4
|
+
data.tar.gz: 24cdb80d3079432a26ef72ef022e2eaba31dfb5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6365ec7dfc91737be04c9e61b8e735ef59f9c384cfe6e67cca83a864cbbd36e6fbde05772d1088bf0432f5f756f7596636da2ccba8561e5014d1752b6584b751
|
7
|
+
data.tar.gz: 9a62227d405f0c0f15a3a8a7d3ad3c5bfc95b7cc1af24be2fb8b5bdd8a6ad966cd5981554f912987d211642e9877f0351f5a74ed754ec3336a9dc17ca1b551bf
|
data/ChangeLog.md
CHANGED
@@ -3,6 +3,21 @@ RELEASE NOTES for Ruby version of Sisimai
|
|
3
3
|
- releases: "https://github.com/sisimai/rb-Sisimai/releases"
|
4
4
|
- download: "https://rubygems.org/gems/sisimai"
|
5
5
|
|
6
|
+
v4.23.0
|
7
|
+
--------------------------------------------------------------------------------
|
8
|
+
- release: ""
|
9
|
+
- version: "4.23.0"
|
10
|
+
- changes:
|
11
|
+
- #124 Implement Sisimai::Mail::Memory class for reading bounce messages from
|
12
|
+
memory(variable).
|
13
|
+
- Update regular expression in Sisimai::Bite::Email::Office365 for detecting
|
14
|
+
failure on SMTP RCPT.
|
15
|
+
- #126 Fix awful bugs(NoMethodError) in Sisimai::Bite::Email::Biglobe, EZweb,
|
16
|
+
and KDDI. Thanks to @rinmu.
|
17
|
+
- #128 Less method calls: use method chain, bang method.
|
18
|
+
- Import commit sisimai/p5-Sisimai@cccb4ef Some test code have been loosened
|
19
|
+
for UTC+13(Pacific/Tongatapu), UTC+14(Pacific/Kiritimati).
|
20
|
+
|
6
21
|
v4.22.7
|
7
22
|
--------------------------------------------------------------------------------
|
8
23
|
- release: "Mon, 16 Jul 2018 13:02:54 +0900 (JST)"
|
data/README-JA.md
CHANGED
@@ -80,10 +80,10 @@ Install
|
|
80
80
|
|
81
81
|
```shell
|
82
82
|
$ sudo gem install sisimai
|
83
|
-
Fetching: sisimai-4.
|
84
|
-
Successfully installed sisimai-4.
|
85
|
-
Parsing documentation for sisimai-4.
|
86
|
-
Installing ri documentation for sisimai-4.
|
83
|
+
Fetching: sisimai-4.23.0.gem (100%)
|
84
|
+
Successfully installed sisimai-4.23.0
|
85
|
+
Parsing documentation for sisimai-4.23.0
|
86
|
+
Installing ri documentation for sisimai-4.23.0
|
87
87
|
Done installing documentation for sisimai after 6 seconds
|
88
88
|
1 gem installed
|
89
89
|
```
|
@@ -99,8 +99,8 @@ gem install bundle rake rspec coveralls
|
|
99
99
|
...
|
100
100
|
4 gems installed
|
101
101
|
bundle exec rake install
|
102
|
-
sisimai 4.
|
103
|
-
sisimai (4.
|
102
|
+
sisimai 4.23.0 built to pkg/sisimai-4.23.0.gem.
|
103
|
+
sisimai (4.23.0) installed.
|
104
104
|
```
|
105
105
|
|
106
106
|
Usage
|
@@ -116,6 +116,11 @@ Basic usage
|
|
116
116
|
require 'sisimai'
|
117
117
|
v = Sisimai.make('/path/to/mbox') # or path to Maildir/
|
118
118
|
|
119
|
+
# Beginning with v4.23.0, both make() and dump() method of Sisimai class can
|
120
|
+
# read bounce messages from variable instead of a path to mailbox
|
121
|
+
f = File.open('/path/to/mbox', 'r'); # or path to Maildir/
|
122
|
+
v = Sisimai.make(f.read)
|
123
|
+
|
119
124
|
# If you want to get bounce records which reason is "delivered", set "delivered"
|
120
125
|
# option to make() method like the following:
|
121
126
|
v = Sisimai.make('/path/to/mbox', delivered: true)
|
@@ -239,8 +244,8 @@ Differences between Ruby version and Perl version
|
|
239
244
|
| メール解析速度(1000通のメール) | 3.75秒[2] | 1.70秒 |
|
240
245
|
| インストール方法 | gem install | cpanm, cpm |
|
241
246
|
| 依存モジュール数(コアモジュールを除く) | 1モジュール | 2モジュール |
|
242
|
-
| LOC:ソースコードの行数 |
|
243
|
-
| テスト件数(spec/,t/,xt/ディレクトリ) |
|
247
|
+
| LOC:ソースコードの行数 | 11700行 | 8500行 |
|
248
|
+
| テスト件数(spec/,t/,xt/ディレクトリ) | 218000件 | 236000件 |
|
244
249
|
| ライセンス | 二条項BSD | 二条項BSD |
|
245
250
|
| 開発会社によるサポート契約 | 準備中 | 提供中 |
|
246
251
|
|
data/README.md
CHANGED
@@ -85,10 +85,10 @@ Install
|
|
85
85
|
|
86
86
|
```shell
|
87
87
|
$ sudo gem install sisimai
|
88
|
-
Fetching: sisimai-4.
|
89
|
-
Successfully installed sisimai-4.
|
90
|
-
Parsing documentation for sisimai-4.
|
91
|
-
Installing ri documentation for sisimai-4.
|
88
|
+
Fetching: sisimai-4.23.0.gem (100%)
|
89
|
+
Successfully installed sisimai-4.23.0
|
90
|
+
Parsing documentation for sisimai-4.23.0
|
91
|
+
Installing ri documentation for sisimai-4.23.0
|
92
92
|
Done installing documentation for sisimai after 6 seconds
|
93
93
|
1 gem installed
|
94
94
|
```
|
@@ -104,8 +104,8 @@ gem install bundle rake rspec coveralls
|
|
104
104
|
...
|
105
105
|
4 gems installed
|
106
106
|
bundle exec rake install
|
107
|
-
sisimai 4.
|
108
|
-
sisimai (4.
|
107
|
+
sisimai 4.23.0 built to pkg/sisimai-4.23.0.gem.
|
108
|
+
sisimai (4.23.0) installed.
|
109
109
|
```
|
110
110
|
|
111
111
|
Usage
|
@@ -121,6 +121,11 @@ messages like following.
|
|
121
121
|
require 'sisimai'
|
122
122
|
v = Sisimai.make('/path/to/mbox') # or path to Maildir/
|
123
123
|
|
124
|
+
# Beginning with v4.23.0, both make() and dump() method of Sisimai class can
|
125
|
+
# read bounce messages from variable instead of a path to mailbox
|
126
|
+
f = File.open('/path/to/mbox', 'r'); # or path to Maildir/
|
127
|
+
v = Sisimai.make(f.read)
|
128
|
+
|
124
129
|
# If you want to get bounce records which reason is "delivered", set "delivered"
|
125
130
|
# option to make() method like the following:
|
126
131
|
v = Sisimai.make('/path/to/mbox', delivered: true)
|
@@ -222,7 +227,7 @@ Output example
|
|
222
227
|
![](https://libsisimai.org/static/images/demo/sisimai-dump-02.gif)
|
223
228
|
|
224
229
|
```json
|
225
|
-
[{"
|
230
|
+
[{"action": "failed", "subject": "Nyaan", "catch": null, "token": "08acf78323edc7923a783c04749dd547ab45c433", "alias": "", "messageid": "201806090556.w595u8GZ093276@neko.example.jp", "listid": "", "smtpcommand": "MAIL", "smtpagent": "Email::Sendmail", "lhost": "localhost", "timezoneoffset": "+0900", "feedbacktype": "", "senderdomain": "neko.example.jp", "diagnostictype": "SMTP", "softbounce": 1, "deliverystatus": "5.0.0", "addresser": "kijitora@neko.example.jp", "diagnosticcode": "550 Unauthenticated senders not allowed", "timestamp": 1528523769, "destination": "example.com", "recipient": "sironeko@example.com", "reason": "securityerror", "replycode": "550", "rhost": "neko.example.jp"}]
|
226
231
|
```
|
227
232
|
|
228
233
|
Sisimai Specification
|
@@ -243,8 +248,8 @@ and bounceHammer are available at
|
|
243
248
|
| The speed of parsing email(1000 emails) | 3.75s[2] | 1.70s |
|
244
249
|
| How to install | gem install | cpanm, cpm |
|
245
250
|
| Dependencies (Except core modules) | 1 module | 2 modules |
|
246
|
-
| LOC:Source lines of code |
|
247
|
-
| The number of tests(spec/,t/,xt/) directory |
|
251
|
+
| LOC:Source lines of code | 11700 lines | 8500 lines |
|
252
|
+
| The number of tests(spec/,t/,xt/) directory | 218000 tests | 236000 tests |
|
248
253
|
| License | BSD 2-Clause | BSD 2-Clause |
|
249
254
|
| Support Contract provided by Developer | Coming soon | Available |
|
250
255
|
|
data/lib/sisimai.rb
CHANGED
@@ -26,20 +26,17 @@ module Sisimai
|
|
26
26
|
def make(argv0, **argv1)
|
27
27
|
return nil unless argv0
|
28
28
|
|
29
|
-
require 'sisimai/data'
|
30
|
-
require 'sisimai/message'
|
31
|
-
|
32
29
|
input = argv1[:input] || nil
|
33
30
|
field = argv1[:field] || []
|
34
31
|
raise ' ***error: "field" accepts an array only' unless field.is_a? Array
|
35
32
|
|
36
33
|
unless input
|
34
|
+
klass = argv0.class
|
37
35
|
# "input" did not specified, try to detect automatically.
|
38
|
-
if
|
39
|
-
# The argument may be a path to email
|
36
|
+
if klass == ::String || klass == IO
|
37
|
+
# The argument may be a path to email OR an email text
|
40
38
|
input = 'email'
|
41
|
-
|
42
|
-
elsif argv0.is_a?(Array) || argv0.is_a?(Hash)
|
39
|
+
elsif klass == Array || klass == Hash
|
43
40
|
# The argument may be a decoded JSON object
|
44
41
|
input = 'json'
|
45
42
|
end
|
@@ -49,6 +46,8 @@ module Sisimai
|
|
49
46
|
hookmethod = argv1[:hook] || nil
|
50
47
|
bouncedata = []
|
51
48
|
|
49
|
+
require 'sisimai/data'
|
50
|
+
require 'sisimai/message'
|
52
51
|
if input == 'email'
|
53
52
|
# Path to mailbox or Maildir/, or STDIN: 'input' => 'email'
|
54
53
|
require 'sisimai/mail'
|
@@ -64,7 +63,7 @@ module Sisimai
|
|
64
63
|
methodargv = { data: mesg, hook: hookmethod, input: 'email', delivered: delivered1 }
|
65
64
|
data = Sisimai::Data.make(methodargv)
|
66
65
|
next unless data
|
67
|
-
bouncedata
|
66
|
+
bouncedata += data unless data.empty?
|
68
67
|
end
|
69
68
|
|
70
69
|
elsif input == 'json'
|
@@ -90,14 +89,14 @@ module Sisimai
|
|
90
89
|
data = Sisimai::Data.make(methodargv)
|
91
90
|
|
92
91
|
next unless data
|
93
|
-
bouncedata
|
92
|
+
bouncedata += data unless data.empty?
|
94
93
|
end
|
95
94
|
else
|
96
95
|
# The value of "input" neither "email" nor "json"
|
97
96
|
raise ' ***error: invalid value of "input"'
|
98
97
|
end
|
99
98
|
|
100
|
-
return nil if bouncedata.
|
99
|
+
return nil if bouncedata.empty?
|
101
100
|
return bouncedata
|
102
101
|
end
|
103
102
|
|
@@ -159,8 +158,8 @@ module Sisimai
|
|
159
158
|
names = Sisimai::Reason.index
|
160
159
|
|
161
160
|
# These reasons are not included in the results of Sisimai::Reason.index
|
162
|
-
names
|
163
|
-
names.
|
161
|
+
names += %w[Delivered Feedback Undefined Vacation]
|
162
|
+
while e = names.shift do
|
164
163
|
# Call .description() method of Sisimai::Reason::*
|
165
164
|
r = 'Sisimai::Reason::' << e
|
166
165
|
require r.gsub('::', '/').downcase
|
data/lib/sisimai/address.rb
CHANGED
@@ -8,7 +8,6 @@ module Sisimai
|
|
8
8
|
:'quoted-string' => (1 << 1), # "Neko, Nyaan"
|
9
9
|
:'comment-block' => (1 << 2), # (neko)
|
10
10
|
}
|
11
|
-
|
12
11
|
@@undisclosed = 'libsisimai.org.invalid'
|
13
12
|
|
14
13
|
# Return pseudo recipient or sender address
|
@@ -67,7 +66,7 @@ module Sisimai
|
|
67
66
|
|
68
67
|
while e = characters.shift do
|
69
68
|
# Check each characters
|
70
|
-
if %w[< > ( ) " ,].
|
69
|
+
if %w[< > ( ) " ,].any? { |r| r == e }
|
71
70
|
# The character is a delimiter character
|
72
71
|
if e == ','
|
73
72
|
# Separator of email addresses or not
|
@@ -88,7 +87,7 @@ module Sisimai
|
|
88
87
|
end
|
89
88
|
else
|
90
89
|
# "Neko, Nyaan" <neko@nyaan.example.org> OR <"neko,nyaan"@example.org>
|
91
|
-
p.
|
90
|
+
p.empty? ? (v[:name] << e) : (v[p] << e)
|
92
91
|
end
|
93
92
|
next
|
94
93
|
end # End of if(',')
|
@@ -96,7 +95,7 @@ module Sisimai
|
|
96
95
|
if e == '<'
|
97
96
|
# <: The beginning of an email address or not
|
98
97
|
if v[:address].size > 0
|
99
|
-
p.
|
98
|
+
p.empty? ? (v[:name] << e) : (v[p] << e)
|
100
99
|
else
|
101
100
|
# <neko@nyaan.example.org>
|
102
101
|
readcursor |= Indicators[:'email-address']
|
@@ -116,7 +115,7 @@ module Sisimai
|
|
116
115
|
p = ''
|
117
116
|
else
|
118
117
|
# a comment block or a display name
|
119
|
-
p.
|
118
|
+
p.empty? ? (v[:name] << e) : (v[:comment] << e)
|
120
119
|
end
|
121
120
|
next
|
122
121
|
end # End of if('>')
|
@@ -201,7 +200,7 @@ module Sisimai
|
|
201
200
|
end # End of if('"')
|
202
201
|
else
|
203
202
|
# The character is not a delimiter
|
204
|
-
p.
|
203
|
+
p.empty? ? (v[:name] << e) : (v[p] << e)
|
205
204
|
next
|
206
205
|
end
|
207
206
|
end
|
@@ -220,7 +219,7 @@ module Sisimai
|
|
220
219
|
v[:address] = v[:name]
|
221
220
|
end
|
222
221
|
|
223
|
-
|
222
|
+
unless v[:address].empty?
|
224
223
|
# Remove the comment from the address
|
225
224
|
if cv = v[:address].match(/(.*)([(].+[)])(.*)/)
|
226
225
|
# (nyaan)nekochan@example.org, nekochan(nyaan)cat@example.org or
|
@@ -243,15 +242,9 @@ module Sisimai
|
|
243
242
|
|
244
243
|
# Remove angle brackets, other brackets, and quotations: []<>{}'`
|
245
244
|
# except a domain part is an IP address like neko@[192.0.2.222]
|
246
|
-
e[:address] = e[:address].sub(/\A[\[<{('`]/, '')
|
247
|
-
e[:address]
|
248
|
-
e[:address] = e[:address].chomp('
|
249
|
-
|
250
|
-
unless e[:address] =~ /\A["].+["][@]/
|
251
|
-
# Remove double-quotations
|
252
|
-
e[:address] = e[:address].sub(/\A["]/, '')
|
253
|
-
e[:address] = e[:address].chomp('"')
|
254
|
-
end
|
245
|
+
e[:address] = e[:address].sub(/\A[\[<{('`]/, '').sub(/['`>})]\z/, '')
|
246
|
+
e[:address].chomp!(']') unless e[:address] =~ /[@]\[[0-9A-Za-z:\.]+\]\z/
|
247
|
+
e[:address] = e[:address].sub(/\A["]/, '').chomp('"') unless e[:address] =~ /\A["].+["][@]/
|
255
248
|
|
256
249
|
if addrs
|
257
250
|
# Almost compatible with parse() method, returns email address only
|
@@ -259,14 +252,11 @@ module Sisimai
|
|
259
252
|
e.delete(:comment)
|
260
253
|
else
|
261
254
|
# Remove double-quotations, trailing spaces.
|
262
|
-
[:name, :comment].each
|
263
|
-
e[f] = e[f].strip
|
264
|
-
end
|
255
|
+
[:name, :comment].each { |f| e[f].strip! }
|
265
256
|
e[:comment] = '' unless e[:comment] =~ /\A[(].+[)]/
|
266
|
-
|
267
|
-
e[:name]
|
268
|
-
e[:name]
|
269
|
-
e[:name] = e[:name].chomp('"')
|
257
|
+
e[:name].squeeze!(' ') unless e[:name] =~ /\A["].+["]\z/
|
258
|
+
e[:name].sub!(/\A["]/, '') unless e[:name] =~ /\A["].+["][@]/
|
259
|
+
e[:name].chomp!('"')
|
270
260
|
end
|
271
261
|
addrtables << e
|
272
262
|
end
|
data/lib/sisimai/arf.rb
CHANGED
@@ -4,7 +4,6 @@ module Sisimai
|
|
4
4
|
# Imported from p5-Sisimail/lib/Sisimai/ARF.pm
|
5
5
|
class << self
|
6
6
|
require 'sisimai/bite/email'
|
7
|
-
require 'sisimai/rfc5322'
|
8
7
|
|
9
8
|
# http://tools.ietf.org/html/rfc5965
|
10
9
|
# http://en.wikipedia.org/wiki/Feedback_loop_(email)
|
@@ -50,9 +49,9 @@ module Sisimai
|
|
50
49
|
# Microsoft (Hotmail, MSN, Live, Outlook) uses its own report format.
|
51
50
|
# Amazon SES Complaints bounces
|
52
51
|
mfrom = %r{(?:
|
53
|
-
staff[@]hotmail[.]com
|
54
|
-
|complaints[@]email-abuse[.]amazonses[.]com
|
55
|
-
)
|
52
|
+
staff[@]hotmail[.]com
|
53
|
+
|complaints[@]email-abuse[.]amazonses[.]com
|
54
|
+
)\z
|
56
55
|
}x
|
57
56
|
if heads['from'] =~ mfrom && heads['subject'].include?('complaint about message from ')
|
58
57
|
# From: staff@hotmail.com
|
@@ -78,7 +77,6 @@ module Sisimai
|
|
78
77
|
def scan(mhead, mbody)
|
79
78
|
return nil unless self.is_arf(mhead)
|
80
79
|
|
81
|
-
require 'sisimai/address'
|
82
80
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
83
81
|
hasdivided = mbody.split("\n")
|
84
82
|
rfc822part = '' # (String) message/rfc822-headers part
|
@@ -121,7 +119,7 @@ module Sisimai
|
|
121
119
|
# this specification is set to "1".
|
122
120
|
#
|
123
121
|
while e = hasdivided.shift do
|
124
|
-
if readcursor
|
122
|
+
if readcursor == 0
|
125
123
|
# Beginning of the bounce message or delivery status part
|
126
124
|
if e =~ MarkingsOf[:message]
|
127
125
|
readcursor |= Indicators[:deliverystatus]
|
@@ -129,7 +127,7 @@ module Sisimai
|
|
129
127
|
end
|
130
128
|
end
|
131
129
|
|
132
|
-
if (readcursor & Indicators[:'message-rfc822'])
|
130
|
+
if (readcursor & Indicators[:'message-rfc822']) == 0
|
133
131
|
# Beginning of the original message part
|
134
132
|
if e.start_with?(StartingOf[:rfc822][0], StartingOf[:rfc822][1])
|
135
133
|
readcursor |= Indicators[:'message-rfc822']
|
@@ -169,13 +167,13 @@ module Sisimai
|
|
169
167
|
elsif e.start_with?(' ', "\t")
|
170
168
|
# Continued line from the previous line
|
171
169
|
rfc822part << e + "\n" if LongFields.key?(previousfn)
|
172
|
-
next
|
170
|
+
next unless e.empty?
|
173
171
|
rcptintext << e if previousfn == 'to'
|
174
172
|
end
|
175
173
|
else
|
176
174
|
# Before "message/rfc822"
|
177
175
|
next unless readcursor & Indicators[:deliverystatus] > 0
|
178
|
-
next
|
176
|
+
next if e.empty?
|
179
177
|
|
180
178
|
# Feedback-Type: abuse
|
181
179
|
# User-Agent: SomeGenerator/1.0
|
@@ -255,7 +253,7 @@ module Sisimai
|
|
255
253
|
commondata[:diagnosis] << ' ' << arfheaders[:authres]
|
256
254
|
end
|
257
255
|
|
258
|
-
|
256
|
+
unless recipients > 0
|
259
257
|
# Insert pseudo recipient address when there is no valid recipient
|
260
258
|
# address in the message.
|
261
259
|
dscontents[-1]['recipient'] = Sisimai::Address.undisclosed(:r)
|
@@ -265,7 +263,7 @@ module Sisimai
|
|
265
263
|
unless rfc822part =~ /\bFrom: [^ ]+[@][^ ]+\b/
|
266
264
|
# There is no "From:" header in the original message
|
267
265
|
# Append the value of "Original-Mail-From" value as a sender address.
|
268
|
-
rfc822part << 'From: ' << commondata[:from] + "\n"
|
266
|
+
rfc822part << 'From: ' << commondata[:from] + "\n" unless commondata[:from].empty?
|
269
267
|
end
|
270
268
|
|
271
269
|
if cv = mhead['subject'].match(/complaint about message from (\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3})/)
|
@@ -275,7 +273,7 @@ module Sisimai
|
|
275
273
|
'This is a Microsoft email abuse report for an email message received from IP' << arfheaders[:rhost] + ' on ' << mhead['date']
|
276
274
|
end
|
277
275
|
|
278
|
-
dscontents.
|
276
|
+
dscontents.each do |e|
|
279
277
|
if e['recipient'] =~ /\A[^ ]+[@]\z/
|
280
278
|
# AOL = http://forums.cpanel.net/f43/aol-brutal-work-71473.html
|
281
279
|
e['recipient'] = Sisimai::Address.s3s4(rcptintext)
|
@@ -29,9 +29,6 @@ module Sisimai::Bite::Email
|
|
29
29
|
# part or nil if it failed to parse or
|
30
30
|
# the arguments are missing
|
31
31
|
def scan(mhead, mbody)
|
32
|
-
return nil unless mhead
|
33
|
-
return nil unless mbody
|
34
|
-
|
35
32
|
# :from => %r/\A"MAILER-DAEMON"/,
|
36
33
|
# :subject => %r/FAILURE NOTICE :/,
|
37
34
|
return nil unless mhead['x-ahmailid']
|
@@ -45,7 +42,7 @@ module Sisimai::Bite::Email
|
|
45
42
|
v = nil
|
46
43
|
|
47
44
|
while e = hasdivided.shift do
|
48
|
-
if readcursor
|
45
|
+
if readcursor == 0
|
49
46
|
# Beginning of the bounce message or delivery status part
|
50
47
|
if e == StartingOf[:message][0]
|
51
48
|
readcursor |= Indicators[:deliverystatus]
|
@@ -53,7 +50,7 @@ module Sisimai::Bite::Email
|
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
56
|
-
if (readcursor & Indicators[:'message-rfc822'])
|
53
|
+
if (readcursor & Indicators[:'message-rfc822']) == 0
|
57
54
|
# Beginning of the original message part
|
58
55
|
if e == StartingOf[:rfc822][0]
|
59
56
|
readcursor |= Indicators[:'message-rfc822']
|
@@ -71,7 +68,7 @@ module Sisimai::Bite::Email
|
|
71
68
|
rfc822list << e
|
72
69
|
else
|
73
70
|
# Before "message/rfc822"
|
74
|
-
next if (readcursor & Indicators[:deliverystatus])
|
71
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
75
72
|
next if e.empty?
|
76
73
|
|
77
74
|
# ----- The following addresses had permanent fatal errors -----
|
@@ -100,10 +97,9 @@ module Sisimai::Bite::Email
|
|
100
97
|
end
|
101
98
|
end
|
102
99
|
end
|
103
|
-
return nil
|
100
|
+
return nil unless recipients > 0
|
104
101
|
|
105
|
-
|
106
|
-
dscontents.map do |e|
|
102
|
+
dscontents.each do |e|
|
107
103
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
108
104
|
e['agent'] = self.smtpagent
|
109
105
|
e.each_key { |a| e[a] ||= '' }
|
@@ -36,9 +36,6 @@ module Sisimai::Bite::Email
|
|
36
36
|
# part or nil if it failed to parse or
|
37
37
|
# the arguments are missing
|
38
38
|
def scan(mhead, mbody)
|
39
|
-
return nil unless mhead
|
40
|
-
return nil unless mbody
|
41
|
-
|
42
39
|
# :from => %r/\AMAILER-DAEMON[@]email[-]bounces[.]amazonses[.]com\z/,
|
43
40
|
# :subject => %r/\ADelivery Status Notification [(]Failure[)]\z/,
|
44
41
|
return nil if mhead['x-mailer'].to_s.start_with?('Amazon WorkMail')
|
@@ -46,7 +43,7 @@ module Sisimai::Bite::Email
|
|
46
43
|
match = 0
|
47
44
|
match += 1 if mhead['x-aws-outgoing']
|
48
45
|
match += 1 if mhead['x-ses-outgoing']
|
49
|
-
return nil
|
46
|
+
return nil unless match > 0
|
50
47
|
|
51
48
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
52
49
|
hasdivided = mbody.split("\n")
|
@@ -66,7 +63,7 @@ module Sisimai::Bite::Email
|
|
66
63
|
havepassed << e
|
67
64
|
p = havepassed[-2]
|
68
65
|
|
69
|
-
if readcursor
|
66
|
+
if readcursor == 0
|
70
67
|
# Beginning of the bounce message or delivery status part
|
71
68
|
if e.start_with?(StartingOf[:message][0], StartingOf[:message][1])
|
72
69
|
readcursor |= Indicators[:deliverystatus]
|
@@ -74,7 +71,7 @@ module Sisimai::Bite::Email
|
|
74
71
|
end
|
75
72
|
end
|
76
73
|
|
77
|
-
if (readcursor & Indicators[:'message-rfc822'])
|
74
|
+
if (readcursor & Indicators[:'message-rfc822']) == 0
|
78
75
|
# Beginning of the original message part
|
79
76
|
if e == StartingOf[:rfc822][0]
|
80
77
|
readcursor |= Indicators[:'message-rfc822']
|
@@ -93,7 +90,7 @@ module Sisimai::Bite::Email
|
|
93
90
|
rfc822list << e
|
94
91
|
else
|
95
92
|
# Before "message/rfc822"
|
96
|
-
next if (readcursor & Indicators[:deliverystatus])
|
93
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
97
94
|
next if e.empty?
|
98
95
|
|
99
96
|
if connvalues == connheader.keys.size
|
@@ -165,7 +162,7 @@ module Sisimai::Bite::Email
|
|
165
162
|
#
|
166
163
|
if cv = e.match(/\AReporting-MTA:[ ]*[DNSdns]+;[ ]*(.+)\z/)
|
167
164
|
# Reporting-MTA: dns; mx.example.jp
|
168
|
-
next
|
165
|
+
next unless connheader['lhost'].empty?
|
169
166
|
connheader['lhost'] = cv[1].downcase
|
170
167
|
connvalues += 1
|
171
168
|
end
|
@@ -174,7 +171,7 @@ module Sisimai::Bite::Email
|
|
174
171
|
end
|
175
172
|
end
|
176
173
|
|
177
|
-
if recipients
|
174
|
+
if recipients == 0 && mbody =~ /notificationType/
|
178
175
|
# Try to parse with Sisimai::Bite::JSON::AmazonSES module
|
179
176
|
require 'sisimai/bite/json/amazonses'
|
180
177
|
j = Sisimai::Bite::JSON::AmazonSES.scan(mhead, mbody)
|
@@ -185,17 +182,14 @@ module Sisimai::Bite::Email
|
|
185
182
|
recipients = j['ds'].size
|
186
183
|
end
|
187
184
|
end
|
188
|
-
return nil
|
185
|
+
return nil unless recipients > 0
|
189
186
|
|
190
|
-
|
191
|
-
require 'sisimai/smtp/status'
|
192
|
-
dscontents.map do |e|
|
187
|
+
dscontents.each do |e|
|
193
188
|
# Set default values if each value is empty.
|
194
189
|
connheader.each_key { |a| e[a] ||= connheader[a] || '' }
|
195
190
|
|
196
|
-
e['agent']
|
197
|
-
e['diagnosis'] = e['diagnosis'].to_s.gsub(/\\n/, ' ')
|
198
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
191
|
+
e['agent'] = self.smtpagent
|
192
|
+
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].to_s.gsub(/\\n/, ' '))
|
199
193
|
|
200
194
|
if e['status'].to_s.start_with?('5.0.0', '5.1.0', '4.0.0', '4.1.0')
|
201
195
|
# Get other D.S.N. value from the error message
|
@@ -206,12 +200,12 @@ module Sisimai::Bite::Email
|
|
206
200
|
errormessage = cv[1]
|
207
201
|
end
|
208
202
|
pseudostatus = Sisimai::SMTP::Status.find(errormessage)
|
209
|
-
e['status'] = pseudostatus
|
203
|
+
e['status'] = pseudostatus unless pseudostatus.empty?
|
210
204
|
end
|
211
205
|
|
212
206
|
MessagesOf.each_key do |r|
|
213
207
|
# Verify each regular expression of session errors
|
214
|
-
next unless MessagesOf[r].
|
208
|
+
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
215
209
|
e['reason'] = r.to_s
|
216
210
|
break
|
217
211
|
end
|