sisimai 5.5.0-java → 5.6.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +21 -0
  3. data/LICENSE +1 -1
  4. data/README-JA.md +15 -12
  5. data/README.md +16 -13
  6. data/lib/sisimai/fact.rb +17 -2
  7. data/lib/sisimai/lhost/amazonses.rb +1 -1
  8. data/lib/sisimai/lhost/einsundeins.rb +1 -1
  9. data/lib/sisimai/lhost/exchange2007.rb +2 -2
  10. data/lib/sisimai/lhost/exim.rb +6 -8
  11. data/lib/sisimai/lhost/qmail.rb +5 -5
  12. data/lib/sisimai/message.rb +2 -0
  13. data/lib/sisimai/reason/authfailure.rb +9 -13
  14. data/lib/sisimai/reason/badreputation.rb +7 -7
  15. data/lib/sisimai/reason/blocked.rb +57 -83
  16. data/lib/sisimai/reason/contenterror.rb +14 -8
  17. data/lib/sisimai/reason/{mesgtoobig.rb → emailtoolarge.rb} +22 -25
  18. data/lib/sisimai/reason/expired.rb +16 -23
  19. data/lib/sisimai/reason/filtered.rb +13 -17
  20. data/lib/sisimai/reason/hasmoved.rb +2 -1
  21. data/lib/sisimai/reason/hostunknown.rb +16 -19
  22. data/lib/sisimai/reason/mailboxfull.rb +27 -49
  23. data/lib/sisimai/reason/networkerror.rb +16 -16
  24. data/lib/sisimai/reason/norelaying.rb +19 -19
  25. data/lib/sisimai/reason/notaccept.rb +6 -8
  26. data/lib/sisimai/reason/notcompliantrfc.rb +5 -9
  27. data/lib/sisimai/reason/policyviolation.rb +11 -25
  28. data/lib/sisimai/reason/ratelimited.rb +62 -0
  29. data/lib/sisimai/reason/rejected.rb +45 -59
  30. data/lib/sisimai/reason/requireptr.rb +13 -25
  31. data/lib/sisimai/reason/securityerror.rb +13 -19
  32. data/lib/sisimai/reason/spamdetected.rb +51 -101
  33. data/lib/sisimai/reason/suspend.rb +26 -24
  34. data/lib/sisimai/reason/systemerror.rb +19 -23
  35. data/lib/sisimai/reason/systemfull.rb +1 -1
  36. data/lib/sisimai/reason/userunknown.rb +79 -112
  37. data/lib/sisimai/reason/virusdetected.rb +6 -8
  38. data/lib/sisimai/reason.rb +14 -14
  39. data/lib/sisimai/rhost/apple.rb +5 -5
  40. data/lib/sisimai/rhost/cloudflare.rb +2 -0
  41. data/lib/sisimai/rhost/cox.rb +22 -20
  42. data/lib/sisimai/rhost/facebook.rb +16 -16
  43. data/lib/sisimai/rhost/franceptt.rb +8 -3
  44. data/lib/sisimai/rhost/godaddy.rb +33 -15
  45. data/lib/sisimai/rhost/google.rb +63 -64
  46. data/lib/sisimai/rhost/iua.rb +1 -1
  47. data/lib/sisimai/rhost/messagelabs.rb +12 -12
  48. data/lib/sisimai/rhost/microsoft.rb +82 -86
  49. data/lib/sisimai/rhost/mimecast.rb +34 -34
  50. data/lib/sisimai/rhost/nttdocomo.rb +2 -2
  51. data/lib/sisimai/rhost/spectrum.rb +7 -7
  52. data/lib/sisimai/rhost/tencent.rb +9 -11
  53. data/lib/sisimai/rhost/yahooinc.rb +7 -8
  54. data/lib/sisimai/smtp/command.rb +2 -0
  55. data/lib/sisimai/smtp/status.rb +50 -90
  56. data/lib/sisimai/string.rb +0 -15
  57. data/lib/sisimai/version.rb +1 -1
  58. metadata +4 -6
  59. data/lib/sisimai/reason/exceedlimit.rb +0 -47
  60. data/lib/sisimai/reason/speeding.rb +0 -47
  61. data/lib/sisimai/reason/toomanyconn.rb +0 -59
@@ -2,27 +2,25 @@ module Sisimai
2
2
  module Reason
3
3
  # This is the error that a sent email size is too big for a destination mail server. In many
4
4
  # case, There are many attachment files with email, or the file size is too large. Sisimai will
5
- # set "mesgtoobig" to the reason of email bounce if the value of Status: field in a bounce email
6
- # is "5.3.4".
7
- module MesgTooBig
5
+ # set "emailtoolarge" to the reason of email bounce if the value of Status: field in a bounce
6
+ # email is "5.2.3" or "5.3.4".
7
+ module EmailTooLarge
8
8
  class << self
9
9
  Index = [
10
- 'exceeded maximum inbound message size',
11
- 'exceeded the maximum incoming message size',
12
- 'line limit exceeded',
13
- 'max message size exceeded',
14
- 'message file too big',
15
- 'message length exceeds administrative limit',
16
- 'message size exceeds fixed limit',
17
- 'message size exceeds fixed maximum message size',
18
- 'message size exceeds maximum value',
19
- 'message too big',
20
- 'message too large for this ',
21
- 'size limit',
22
- 'taille limite du message atteinte',
10
+ "line limit exceeded",
11
+ "mail file size exceeds the maximum size allowed for mail delivery",
12
+ "message too large",
13
+ "size limit",
14
+ "taille limite du message atteinte",
15
+ ].freeze
16
+ Pairs = [
17
+ ["exceeded", "message size"],
18
+ ["message ", "exceeds ", "limit"],
19
+ ["message ", "size", "exceed"],
20
+ ["message ", "too", "big"],
23
21
  ].freeze
24
22
 
25
- def text; return 'mesgtoobig'; end
23
+ def text; return 'emailtoolarge'; end
26
24
  def description; return 'Email rejected due to an email size is too big for a destination mail server'; end
27
25
 
28
26
  # Try to match that the given text and regular expressions
@@ -31,6 +29,7 @@ module Sisimai
31
29
  def match(argv1)
32
30
  return false if argv1.nil? || argv1.empty?
33
31
  return true if Index.any? { |a| argv1.include?(a) }
32
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
34
33
  return false
35
34
  end
36
35
 
@@ -40,18 +39,18 @@ module Sisimai
40
39
  # false: is not big
41
40
  # @see http://www.ietf.org/rfc/rfc2822.txt
42
41
  def true(argvs)
43
- return true if argvs['reason'] == 'mesgtoobig'
42
+ return true if argvs['reason'] == 'emailtoolarge'
44
43
 
45
44
  statuscode = argvs['deliverystatus'] || ''
46
45
  tempreason = Sisimai::SMTP::Status.name(statuscode)
47
46
 
48
- # Delivery status code points "mesgtoobig".
47
+ # Delivery status code points "emailtoolarge".
49
48
  # Status: 5.3.4
50
49
  # Diagnostic-Code: SMTP; 552 5.3.4 Error: message file too big
51
- return true if tempreason == 'mesgtoobig'
52
-
53
- # 5.2.3 Message length exceeds administrative limit
54
- return false if( tempreason == 'exceedlimit' || statuscode == '5.2.3' )
50
+ #
51
+ # Status: 5.2.3
52
+ # Deiagnostic-Code: Message length exceeds administrative limit
53
+ return true if tempreason == 'emailtoolarge'
55
54
  return match(argvs['diagnosticcode'].downcase)
56
55
  end
57
56
 
@@ -60,5 +59,3 @@ module Sisimai
60
59
  end
61
60
  end
62
61
 
63
-
64
-
@@ -7,32 +7,25 @@ module Sisimai
7
7
  # the message you sent has been in the queue for long time.
8
8
  module Expired
9
9
  class << self
10
- require 'sisimai/string'
11
-
12
10
  Index = [
13
- 'connection timed out',
14
- 'could not find a gateway for',
15
- 'delivery attempts will continue to be',
16
- 'delivery expired',
17
- 'delivery time expired',
18
- 'failed to deliver to domain ',
19
- 'giving up on',
20
- 'have been failing for a long time',
21
- 'has been delayed',
22
- 'it has not been collected after',
23
- 'message expired after sitting in queue for',
24
- 'message expired, cannot connect to remote server',
25
- 'message expired, connection refulsed',
26
- 'message timed out',
27
- 'retry time not reached for any host after a long failure period',
28
- 'server did not respond',
29
- 'this message has been in the queue too long',
30
- 'unable to deliver message after multiple retries',
31
- 'was not reachable within the allowed queue period',
32
- 'your message could not be delivered for more than',
11
+ "connection timed out",
12
+ "could not find a gateway for",
13
+ "delivery attempts will continue to be",
14
+ "failed to deliver to domain ",
15
+ "have been failing for a long time",
16
+ "has been delayed",
17
+ "it has not been collected after",
18
+ "message could not be delivered for more than",
19
+ "message expired, ",
20
+ "message has been in the queue too long",
21
+ "message timed out",
22
+ "server did not respond",
23
+ "unable to deliver message after multiple retries",
33
24
  ].freeze
34
25
  Pairs = [
35
- ['could not be delivered for', ' days'],
26
+ ["could not be delivered for", " days"],
27
+ ["delivery ", "expired"],
28
+ ["not", "reach", "period"],
36
29
  ].freeze
37
30
 
38
31
  def text; return 'expired'; end
@@ -10,22 +10,18 @@ module Sisimai
10
10
  module Filtered
11
11
  class << self
12
12
  Index = [
13
- 'because the recipient is only accepting mail from specific email addresses', # AOL Phoenix
14
- 'bounced address', # SendGrid|a message to an address has previously been Bounced.
15
- 'due to extended inactivity new mail is not currently being accepted for this mailbox',
16
- 'has restricted sms e-mail', # AT&T
17
- 'is not accepting any mail',
13
+ "account is protected by",
14
+ "has restricted sms e-mail", # AT&T
15
+ "is not accepting any mail",
18
16
  "message filtered",
19
- 'message rejected due to user rules',
20
- 'not found recipient account',
21
- 'refused due to recipient preferences', # Facebook
22
- 'resolver.rst.notauthorized', # Microsoft Exchange
23
- 'this account is protected by',
24
- 'user not found', # Filter on MAIL.RU
25
- 'user refuses to receive this mail',
26
- 'user reject',
27
- 'we failed to deliver mail because the following address recipient id refuse to receive mail', # Willcom
28
- 'you have been blocked by the recipient',
17
+ "message rejected due to user rules",
18
+ "not found recipient account",
19
+ "recipient id refuse to receive mail", # Willcom
20
+ "recipient is only accepting mail from specific email addresses", # AOL Phoenix
21
+ "refused due to recipient preferences", # Facebook
22
+ "user refuses to receive this mail",
23
+ "user reject",
24
+ "you have been blocked by the recipient",
29
25
  ].freeze
30
26
 
31
27
  def text; return 'filtered'; end
@@ -48,7 +44,6 @@ module Sisimai
48
44
  def true(argvs)
49
45
  return true if argvs['reason'] == 'filtered'
50
46
 
51
- require 'sisimai/reason/userunknown'
52
47
  tempreason = Sisimai::SMTP::Status.name(argvs['deliverystatus'])
53
48
  return false if tempreason == 'suspend'
54
49
 
@@ -56,12 +51,13 @@ module Sisimai
56
51
  thecommand = argvs['command'] || ''
57
52
  if tempreason == 'filtered'
58
53
  # Delivery status code points "filtered".
54
+ require 'sisimai/reason/userunknown'
59
55
  return true if Sisimai::Reason::UserUnknown.match(issuedcode) || match(issuedcode)
60
56
  else
61
57
  # The value of "reason" isn't "filtered" when the value of "command" is an SMTP command
62
58
  # to be sent before the SMTP DATA command because all the MTAs read the headers and the
63
59
  # entire message body after the DATA command.
64
- return false if %w[CONN EHLO HELO MAIL RCPT].include?(thecommand)
60
+ return false if Sisimai::SMTP::Command::ExceptDATA.include?(thecommand)
65
61
  return true if match(issuedcode) || Sisimai::Reason::UserUnknown.match(issuedcode)
66
62
  end
67
63
  return false
@@ -28,7 +28,8 @@ module Sisimai
28
28
  # false: Has not moved
29
29
  # @see http://www.ietf.org/rfc/rfc2822.txt
30
30
  def true(argvs)
31
- return true if argvs['reason'] == 'hasmoved'
31
+ return true if argvs['reason'] == 'hasmoved'
32
+ return false if Sisimai::SMTP::Command::BeforeRCPT.include?(argvs['command'])
32
33
  return match(argvs['diagnosticcode'].downcase)
33
34
  end
34
35
 
@@ -6,26 +6,22 @@ module Sisimai
6
6
  # Status: field in a bounce mail is "5.1.2".
7
7
  module HostUnknown
8
8
  class << self
9
- require 'sisimai/string'
10
-
11
9
  Index = [
12
- 'domain does not exist',
13
- 'domain is not reachable',
14
- 'domain must exist',
15
- 'host or domain name not found',
16
- 'host unknown',
17
- 'host unreachable',
18
- 'mail domain mentioned in email address is unknown',
19
- 'name or service not known',
20
- 'no such domain',
21
- 'recipient address rejected: unknown domain name',
22
- 'recipient domain must exist',
23
- 'the account or domain may not exist',
24
- 'unknown host',
25
- 'unroutable address',
26
- 'unrouteable address',
10
+ "domain is not reachable",
11
+ "domain mentioned in email address is unknown",
12
+ "domain must exist",
13
+ "host or domain name not found",
14
+ "host unknown",
15
+ "host unreachable",
16
+ "name or service not known",
17
+ "no such domain",
18
+ "recipient address rejected: unknown domain name",
19
+ "unknown host",
20
+ ].freeze
21
+ Pairs = [
22
+ ["domain ", "not exist"],
23
+ ["unrout", "able ", "address"],
27
24
  ].freeze
28
- Pairs = [['553 ', ' does not exist']].freeze
29
25
 
30
26
  def text; return 'hostunknown'; end
31
27
  def description; return "Delivery failed due to a domain part of a recipient's email address does not exist"; end
@@ -47,7 +43,8 @@ module Sisimai
47
43
  # false: is not unknown host.
48
44
  # @see http://www.ietf.org/rfc/rfc2822.txt
49
45
  def true(argvs)
50
- return true if argvs['reason'] == 'hostunknown'
46
+ return true if argvs['reason'] == 'hostunknown'
47
+ return false if Sisimai::SMTP::Command::BeforeRCPT.include?(argvs['command'])
51
48
 
52
49
  issuedcode = argvs['diagnosticcode'].downcase || ''
53
50
  statuscode = argvs['deliverystatus'] || ''
@@ -8,55 +8,32 @@ module Sisimai
8
8
  module MailboxFull
9
9
  class << self
10
10
  Index = [
11
- '452 insufficient disk space',
12
- 'account disabled temporarly for exceeding receiving limits',
13
- 'account is exceeding their quota',
14
- 'account is over quota',
15
- 'account is temporarily over quota',
16
- 'boite du destinataire pleine',
17
- 'delivery failed: over quota',
18
- 'disc quota exceeded',
19
- 'diskspace quota',
20
- 'does not have enough space',
21
- 'exceeded storage allocation',
22
- 'exceeding its mailbox quota',
23
- 'full mailbox',
24
- 'is over disk quota',
25
- 'is over quota temporarily',
26
- 'mail file size exceeds the maximum size allowed for mail delivery',
27
- 'mail quota exceeded',
28
- 'mailbox exceeded the local limit',
29
- 'mailbox full',
30
- 'mailbox has exceeded its disk space limit',
31
- 'mailbox is full',
32
- 'mailbox over quota',
33
- 'mailbox quota usage exceeded',
34
- 'mailbox size limit exceeded',
35
- 'maildir over quota',
36
- 'maildir delivery failed: userdisk quota ',
37
- 'maildir delivery failed: domaindisk quota ',
38
- 'mailfolder is full',
39
- 'no space left on device',
40
- 'not enough disk space',
41
- 'not enough storage space in',
42
- 'not sufficient disk space',
43
- 'over the allowed quota',
44
- 'quota exceeded',
45
- 'quota violation for',
46
- 'recipient reached disk quota',
47
- 'recipient rejected: mailbox would exceed maximum allowed storage',
48
- 'the recipient mailbox has exceeded its disk space limit',
49
- "the user's space has been used up",
50
- 'the user you are trying to reach is over quota',
51
- 'too much mail data', # @docomo.ne.jp
52
- 'user has exceeded quota, bouncing mail',
53
- 'user has too many messages on the server',
54
- 'user is over quota',
55
- 'user is over the quota',
56
- 'user over quota',
57
- 'user over quota. (#5.1.1)', # qmail-toaster
58
- 'was automatically rejected: quota exceeded',
59
- 'would be over the allowed quota',
11
+ "452 insufficient disk space",
12
+ "account disabled temporarly for exceeding receiving limits",
13
+ "boite du destinataire pleine",
14
+ "exceeded storage allocation",
15
+ "full mailbox",
16
+ "mailbox size limit exceeded",
17
+ "mailbox would exceed maximum allowed storage",
18
+ "mailfolder is full",
19
+ "no space left on device",
20
+ "not sufficient disk space",
21
+ "quota violation for",
22
+ "too much mail data", # @docomo.ne.jp
23
+ "user has exceeded quota, bouncing mail",
24
+ "user has too many messages on the server",
25
+ "user's space has been used up",
26
+ ].freeze
27
+ Pairs = [
28
+ ["account is ", " quota"],
29
+ ["disk", "quota"],
30
+ ["enough ", " space"],
31
+ ["mailbox ", "exceeded", " limit"],
32
+ ["mailbox ", "full"],
33
+ ["mailbox ", "quota"],
34
+ ["maildir ", "quota"],
35
+ ["over ", "quota"],
36
+ ["quota ", "exceeded"],
60
37
  ].freeze
61
38
 
62
39
  def text; return 'mailboxfull'; end
@@ -68,6 +45,7 @@ module Sisimai
68
45
  def match(argv1)
69
46
  return false if argv1.nil? || argv1.empty?
70
47
  return true if Index.any? { |a| argv1.include?(a) }
48
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
71
49
  return false
72
50
  end
73
51
 
@@ -11,22 +11,21 @@ module Sisimai
11
11
  module NetworkError
12
12
  class << self
13
13
  Index = [
14
- 'could not connect and send the mail to',
15
- 'dns records for the destination computer could not be found',
16
- 'hop count exceeded - possible mail loop',
17
- 'host is unreachable',
18
- 'host name lookup failure',
19
- 'host not found, try again',
20
- 'mail forwarding loop for ',
21
- 'malformed name server reply',
22
- 'malformed or unexpected name server reply',
23
- 'maximum forwarding loop count exceeded',
24
- 'message looping',
25
- 'message probably in a routing loop',
26
- 'no route to host',
27
- 'too many hops',
28
- 'unable to resolve route ',
29
- 'unrouteable mail domain',
14
+ "could not connect and send the mail to",
15
+ "dns records for the destination computer could not be found",
16
+ "host is unreachable",
17
+ "host name lookup failure",
18
+ "host not found, try again",
19
+ "maximum forwarding loop count exceeded",
20
+ "no route to host",
21
+ "too many hops",
22
+ "unable to resolve route ",
23
+ "unrouteable mail domain",
24
+ ].freeze
25
+ Pairs = [
26
+ ["malformed", "name server reply"],
27
+ ["mail ", "loop"],
28
+ ["message ", "loop"],
30
29
  ].freeze
31
30
 
32
31
  def text; return 'networkerror'; end
@@ -38,6 +37,7 @@ module Sisimai
38
37
  def match(argv1)
39
38
  return false if argv1.nil? || argv1.empty?
40
39
  return true if Index.any? { |a| argv1.include?(a) }
40
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
41
41
  return false
42
42
  end
43
43
 
@@ -10,27 +10,26 @@ module Sisimai
10
10
  module NoRelaying
11
11
  class << self
12
12
  Index = [
13
- 'as a relay',
14
- 'email address is not verified.',
15
- 'insecure mail relay',
16
- 'is not permitted to relay through this server without authentication',
17
- 'mail server requires authentication when attempting to send to a non-local e-mail address', # MailEnable
18
- 'no relaying',
19
- 'not a gateway',
20
- 'not allowed to relay through this machine',
21
- 'not an open relay, so get lost',
22
- 'not local host',
23
- 'relay access denied',
24
- 'relay denied',
25
- 'relay not permitted',
26
- 'relaying denied', # Sendmail
27
- 'relaying mail to ',
28
- 'specified domain is not allowed',
29
- "that domain isn't in my list of allowed rcpthost",
30
- 'this system is not configured to relay mail',
31
- 'unable to relay ',
13
+ "as a relay",
14
+ "domain isn't in my list of allowed rcpthost",
15
+ "email address is not verified.",
16
+ "insecure mail relay",
17
+ "no relaying",
18
+ "not a gateway",
19
+ "not an open relay, so get lost",
20
+ "not local host",
21
+ "relay not permitted",
22
+ "relaying denied", # Sendmail
23
+ "relaying mail to ",
24
+ "send to a non-local e-mail address", # MailEnable
25
+ "specified domain is not allowed",
26
+ "unable to relay ",
32
27
  "we don't handle mail for",
33
28
  ].freeze
29
+ Pairs = [
30
+ ["relay ", "denied"],
31
+ [" not ", " to relay"],
32
+ ].freeze
34
33
 
35
34
  def text; return 'norelaying'; end
36
35
  def description; return 'Email rejected with error message "Relaying Denied"'; end
@@ -41,6 +40,7 @@ module Sisimai
41
40
  def match(argv1)
42
41
  return false if argv1.nil? || argv1.empty?
43
42
  return true if Index.any? { |a| argv1.include?(a) }
43
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
44
44
  return false
45
45
  end
46
46
 
@@ -11,13 +11,11 @@ module Sisimai
11
11
  class << self
12
12
  # Destination mail server does not accept any message
13
13
  Index = [
14
- 'does not accept mail', # Sendmail
15
- 'host/domain does not accept mail', # iCloud
16
- 'mail receiving disabled',
17
- 'name server: .: host not found', # Sendmail
18
- 'no mx record found for domain=', # Oath(Yahoo!)
19
- 'no route for current request',
20
- 'smtp protocol returned a permanent error',
14
+ "does not accept mail", # Sendmail, iCloud
15
+ "mail receiving disabled",
16
+ "name server: .: host not found", # Sendmail
17
+ "no mx record found for domain=", # Oath(Yahoo!)
18
+ "no route for current request",
21
19
  ].freeze
22
20
 
23
21
  def text; return 'notaccept'; end
@@ -40,7 +38,7 @@ module Sisimai
40
38
  def true(argvs)
41
39
  return true if argvs['reason'] == 'notaccept'
42
40
  return true if [521, 556].index(argvs['replycode'].to_i) # SMTP Reply Code is 554 or 556
43
- return false if argvs['command'] != 'MAIL'
41
+ return false if Sisimai::SMTP::Command::BeforeRCPT.include?(argvs['command'])
44
42
  return match(argvs['diagnosticcode'].downcase)
45
43
  end
46
44
 
@@ -7,16 +7,13 @@ module Sisimai
7
7
  # example, there are multiple "Subject" headers in the email.
8
8
  module NotCompliantRFC
9
9
  class << self
10
- require 'sisimai/string'
11
10
  Index = [
12
- 'duplicate header',
13
- 'this message is not rfc 5322 compliant',
14
- 'https://support.google.com/mail/?p=rfcmessagenoncompliant',
11
+ "duplicate header",
12
+ "message is not rfc 5322 compliant",
13
+ "multiple addresses in from: header are not accepted",
14
+ "rfc 1035 violation",
15
+ "https://support.google.com/mail/?p=rfcmessagenoncompliant",
15
16
  ].freeze
16
- Pairs = [
17
- [' multiple ', ' header'],
18
- ].freeze
19
-
20
17
 
21
18
  def text; return 'notcompliantrfc'; end
22
19
  def description; return 'Email rejected due to non-compliance with RFC'; end
@@ -27,7 +24,6 @@ module Sisimai
27
24
  def match(argv1)
28
25
  return false if argv1.nil? || argv1.empty?
29
26
  return true if Index.any? { |a| argv1.include?(a) }
30
- return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
31
27
  return false
32
28
  end
33
29
 
@@ -14,34 +14,21 @@ module Sisimai
14
14
  #
15
15
  module PolicyViolation
16
16
  class << self
17
- require 'sisimai/string'
18
-
19
17
  Index = [
20
- 'an illegal attachment on your message',
21
- 'because the recipient is not accepting mail with ', # AOL Phoenix
22
- 'closed mailing list',
23
- 'denied by policy',
24
- 'email not accepted for policy reasons',
18
+ "because the recipient is not accepting mail with ", # AOL Phoenix
19
+ "closed mailing list",
20
+ "delivery not authorized, message refused",
21
+ "denied by policy",
25
22
  # http://kb.mimecast.com/Mimecast_Knowledge_Base/Administration_Console/Monitoring/Mimecast_SMTP_Error_Codes#554
26
- 'email rejected due to security policies',
27
- 'header are not accepted',
28
- 'header error',
29
- 'local policy violation',
30
- 'message bounced due to organizational settings',
31
- 'message given low priority',
32
- 'message not accepted for policy reasons',
33
- 'message rejected due to local policy',
34
- 'messages with multiple addresses',
35
- 'rejected for policy reasons',
36
- 'protocol violation',
37
- 'the message was rejected by organization policy',
38
- 'this message was blocked because its content presents a potential', # https://support.google.com/mail/answer/6590
39
- 'we do not accept messages containing images or other attachments',
23
+ "email rejected due to security policies",
24
+ "for policy reasons",
25
+ "local policy violation",
26
+ "message bounced due to organizational settings",
27
+ "message given low priority",
28
+ "message was rejected by organization policy",
29
+ "protocol violation",
40
30
  "you're using a mass mailer",
41
31
  ].freeze
42
- Pairs = [
43
- ['you have exceeded the', 'allowable number of posts without solving a captcha'],
44
- ].freeze
45
32
 
46
33
  def text; return 'policyviolation'; end
47
34
  def description; return 'Email rejected due to policy violation on a destination host'; end
@@ -53,7 +40,6 @@ module Sisimai
53
40
  def match(argv1)
54
41
  return false if argv1.nil? || argv1.empty?
55
42
  return true if Index.any? { |a| argv1.include?(a) }
56
- return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
57
43
  return false
58
44
  end
59
45
 
@@ -0,0 +1,62 @@
1
+ module Sisimai
2
+ module Reason
3
+ # Sisimai::Reason::RateLimited checks the bounce reason is "ratelimited" or not. This class is
4
+ # called only Sisimai::Reason class.
5
+ #
6
+ # This is the error that SMTP connection was rejected temporarily due to too many recipients or
7
+ # too many concurrency connections to the remote server. This reason has added in Sisimai 4.1.26.
8
+ #
9
+ # <kijitora@example.ne.jp>: host mx02.example.ne.jp[192.0.1.20] said:
10
+ # 452 4.3.2 Connection rate limit exceeded. (in reply to MAIL FROM command)
11
+ module RateLimited
12
+ class << self
13
+ Index = [
14
+ "has exceeded the max emails per hour ",
15
+ "please try again slower",
16
+ "receiving mail at a rate that prevents additional messages from being delivered",
17
+ "temporarily deferred due to unexpected volume or user complaints",
18
+ "throttling failure: ",
19
+ "too many errors from your ip", # Free.fr
20
+ "too many recipients", # ntt docomo
21
+ "too many smtp sessions for this host", # Sendmail(daemon.c)
22
+ "trop de connexions, ",
23
+ "we have already made numerous attempts to deliver this message",
24
+ ].freeze
25
+ Pairs = [
26
+ ["exceeded ", "allowable number of posts without solving a captcha"],
27
+ ["connection ", "limit"],
28
+ ["temporarily", "rate limited"],
29
+ ["too many con", "s"],
30
+ ].freeze
31
+
32
+ def text; return 'ratelimited'; end
33
+ def description; return 'SMTP connection rejected temporarily due to too many concurrency connections to the remote host'; end
34
+
35
+ # Try to match that the given text and regular expressions
36
+ # @param [String] argv1 String to be matched with regular expressions
37
+ # @return [Boolean] false: Did not match, true: Matched
38
+ def match(argv1)
39
+ return false if argv1.nil? || argv1.empty?
40
+ return true if Index.any? { |a| argv1.include?(a) }
41
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
42
+ return false
43
+ end
44
+
45
+ # Rejected by domain or address filter ?
46
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
47
+ # @return [Boolean] true: is rate limited
48
+ # false: is not rate limited
49
+ # @see http://www.ietf.org/rfc/rfc2822.txt
50
+ def true(argvs)
51
+ return true if argvs['reason'] == 'ratelimited'
52
+ return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == 'ratelimited'
53
+ return match(argvs['diagnosticcode'].downcase)
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+