dsn 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +6 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +9 -0
  6. data/Gemfile.lock +21 -0
  7. data/README.md +64 -0
  8. data/Rakefile +12 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/dsn.gemspec +31 -0
  12. data/lib/dsn.rb +31 -0
  13. data/lib/dsn/data/2.XXX.XXX +5 -0
  14. data/lib/dsn/data/4.XXX.XXX +7 -0
  15. data/lib/dsn/data/5.XXX.XXX +6 -0
  16. data/lib/dsn/data/X.0.0 +5 -0
  17. data/lib/dsn/data/X.0.XXX +3 -0
  18. data/lib/dsn/data/X.1.0 +4 -0
  19. data/lib/dsn/data/X.1.1 +6 -0
  20. data/lib/dsn/data/X.1.2 +7 -0
  21. data/lib/dsn/data/X.1.3 +5 -0
  22. data/lib/dsn/data/X.1.4 +6 -0
  23. data/lib/dsn/data/X.1.5 +4 -0
  24. data/lib/dsn/data/X.1.6 +5 -0
  25. data/lib/dsn/data/X.1.7 +4 -0
  26. data/lib/dsn/data/X.1.8 +6 -0
  27. data/lib/dsn/data/X.1.XXX +5 -0
  28. data/lib/dsn/data/X.2.0 +4 -0
  29. data/lib/dsn/data/X.2.1 +5 -0
  30. data/lib/dsn/data/X.2.2 +7 -0
  31. data/lib/dsn/data/X.2.3 +6 -0
  32. data/lib/dsn/data/X.2.4 +5 -0
  33. data/lib/dsn/data/X.2.XXX +5 -0
  34. data/lib/dsn/data/X.3.0 +5 -0
  35. data/lib/dsn/data/X.3.1 +6 -0
  36. data/lib/dsn/data/X.3.2 +6 -0
  37. data/lib/dsn/data/X.3.3 +6 -0
  38. data/lib/dsn/data/X.3.4 +5 -0
  39. data/lib/dsn/data/X.3.5 +4 -0
  40. data/lib/dsn/data/X.3.XXX +6 -0
  41. data/lib/dsn/data/X.4.0 +5 -0
  42. data/lib/dsn/data/X.4.1 +5 -0
  43. data/lib/dsn/data/X.4.2 +6 -0
  44. data/lib/dsn/data/X.4.3 +8 -0
  45. data/lib/dsn/data/X.4.4 +10 -0
  46. data/lib/dsn/data/X.4.5 +5 -0
  47. data/lib/dsn/data/X.4.6 +6 -0
  48. data/lib/dsn/data/X.4.7 +8 -0
  49. data/lib/dsn/data/X.4.XXX +7 -0
  50. data/lib/dsn/data/X.5.0 +5 -0
  51. data/lib/dsn/data/X.5.1 +5 -0
  52. data/lib/dsn/data/X.5.2 +6 -0
  53. data/lib/dsn/data/X.5.3 +8 -0
  54. data/lib/dsn/data/X.5.4 +6 -0
  55. data/lib/dsn/data/X.5.5 +4 -0
  56. data/lib/dsn/data/X.5.XXX +6 -0
  57. data/lib/dsn/data/X.6.0 +5 -0
  58. data/lib/dsn/data/X.6.1 +5 -0
  59. data/lib/dsn/data/X.6.2 +6 -0
  60. data/lib/dsn/data/X.6.3 +7 -0
  61. data/lib/dsn/data/X.6.4 +7 -0
  62. data/lib/dsn/data/X.6.5 +4 -0
  63. data/lib/dsn/data/X.6.XXX +8 -0
  64. data/lib/dsn/data/X.7.0 +7 -0
  65. data/lib/dsn/data/X.7.1 +7 -0
  66. data/lib/dsn/data/X.7.2 +4 -0
  67. data/lib/dsn/data/X.7.3 +5 -0
  68. data/lib/dsn/data/X.7.4 +5 -0
  69. data/lib/dsn/data/X.7.5 +6 -0
  70. data/lib/dsn/data/X.7.6 +5 -0
  71. data/lib/dsn/data/X.7.7 +6 -0
  72. data/lib/dsn/data/X.7.XXX +9 -0
  73. data/lib/dsn/message.rb +43 -0
  74. data/lib/dsn/parser/string.rb +45 -0
  75. data/lib/dsn/status_code.rb +52 -0
  76. data/lib/dsn/subcode/base.rb +53 -0
  77. data/lib/dsn/subcode/class_subcode.rb +34 -0
  78. data/lib/dsn/subcode/detail_subcode.rb +19 -0
  79. data/lib/dsn/subcode/subject_subcode.rb +19 -0
  80. data/lib/dsn/version.rb +5 -0
  81. metadata +139 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 534f17912ad61e0312b2237ab2b2f85e1b2297e7188470d0fbc978dcb7f41d5b
4
+ data.tar.gz: d29e79a5bfcc273805efb859d7f7b2cb8f36fc485c899ac5def0f197d7cf108d
5
+ SHA512:
6
+ metadata.gz: c236e9d93f3222c92994772aea68b7931b3bc005a61d92c3a95d4ef59d4e59da267d4db51ce58c9cf81b04739621ca3ea145371b93245423d4e105b78ab032d0
7
+ data.tar.gz: 436e8e0289765292e634a9581a9ca815e337b098cf6d23aeb41afe649e5dfc262638698c954df6d232589c21490d15ad901ce3d10cb90d3d3858b91758f031d6
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.1
6
+ before_install: gem install bundler -v 2.1.2
@@ -0,0 +1,3 @@
1
+ ## [0.1.0] - 2020-07-18
2
+
3
+ * Initial version of DSN.
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in dsn.gemspec
6
+ gemspec
7
+
8
+ gem 'minitest', '~> 5.0'
9
+ gem 'rake', '~> 12.0'
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dsn (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.14.1)
10
+ rake (12.3.3)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ dsn!
17
+ minitest (~> 5.0)
18
+ rake (~> 12.0)
19
+
20
+ BUNDLED WITH
21
+ 2.1.2
@@ -0,0 +1,64 @@
1
+ # DSN
2
+
3
+ Ruby parser for [RFC 3463](https://tools.ietf.org/html/rfc3463) Delivery Status Notification codes.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's `Gemfile`:
8
+
9
+ ```ruby
10
+ gem 'dsn'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install dsn
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ dsn = DSN.new('5.7.5')
25
+ dsn.valid?
26
+ # => true
27
+ dsn.success?
28
+ # => false
29
+ dsn.transient_failure?
30
+ # => false
31
+ dsn.failed?
32
+ # => true
33
+ dsn.to_s
34
+ # => "5.7.5"
35
+ dsn.subcode.to_s
36
+ # => "X.7.5"
37
+
38
+ dsn = DSN.new('5.7.999')
39
+ dsn.valid?
40
+ # => false
41
+ dsn.class_subcode.valid?
42
+ # => true
43
+ dsn.subject_subcode.valid?
44
+ # => true
45
+ dsn.detail_subcode.valid?
46
+ # => false
47
+ dsn.to_s
48
+ # => "5.7.999"
49
+ dsn.subcode.to_s
50
+ # => "X.7.XXX"
51
+
52
+ msg = DSN::Message.new(dsn.subcode)
53
+ msg.summary
54
+ # => "Security or Policy Status"
55
+ msg.body
56
+ # => "The security or policy status codes report failures involving policies such as per-recipient or per-host filtering and cryptographic operations. Security and policy status issues are assumed to be under the control of either or both the sender and recipient. Both the sender and recipient must permit the exchange of messages and arrange the exchange of necessary keys and certificates for cryptographic operations."
57
+
58
+ DSN.message('5.7.5').summary
59
+ # => "Cryptographic failure"
60
+ ```
61
+
62
+ ## Contributing
63
+
64
+ Bug reports and pull requests are welcome on GitHub at https://github.com/garethrees/dsn.
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:spec) do |t|
7
+ t.libs << 'spec'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['spec/**/*_spec.rb']
10
+ end
11
+
12
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "dsn"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/dsn/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'dsn'
7
+ spec.version = DSN::VERSION
8
+ spec.authors = ['Gareth Rees']
9
+ spec.email = ['gareth@garethrees.co.uk']
10
+ spec.license = 'MIT'
11
+
12
+ spec.summary = %(Ruby parser for RFC 3463 Delivery Status Notification codes)
13
+ spec.homepage = 'https://github.com/garethrees/dsn'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
15
+
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = spec.homepage
18
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/master/CHANGELOG.md"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject do |f|
24
+ f.match(%r{^(test|spec|features)/})
25
+ end
26
+ end
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ['lib']
29
+
30
+ spec.add_development_dependency 'minitest', '~> 5.0'
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dsn/status_code'
4
+ require 'dsn/message'
5
+ require 'dsn/version'
6
+
7
+ require 'dsn/parser/string'
8
+
9
+ require 'dsn/subcode/base'
10
+ require 'dsn/subcode/class_subcode'
11
+ require 'dsn/subcode/subject_subcode'
12
+ require 'dsn/subcode/detail_subcode'
13
+
14
+ # Ruby parser for RFC 3463 Delivery Status Notification codes
15
+ module DSN
16
+ # Raised when the status code is unparsable.
17
+ class InvalidStatusCode < StandardError; end
18
+
19
+ # Raised when attempting to operate on an invalid subcode.
20
+ class InvalidSubcode < StandardError; end
21
+
22
+ # Parse a StatsCode from a String
23
+ def self.new(*args)
24
+ StatusCode.new(Parser::String.new(*args))
25
+ end
26
+
27
+ # Return the most detailed Message possible from a String code
28
+ def self.message(*args)
29
+ Message.new(new(*args).subcode)
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ Success
2
+
3
+ Success specifies that the DSN is reporting a positive delivery
4
+ action. Detail sub-codes may provide notification of
5
+ transformations required for delivery.
@@ -0,0 +1,7 @@
1
+ Persistent Transient Failure
2
+
3
+ A persistent transient failure is one in which the message as
4
+ sent is valid, but persistence of some temporary condition has
5
+ caused abandonment or delay of attempts to send the message.
6
+ If this code accompanies a delivery failure report, sending in
7
+ the future may be successful.
@@ -0,0 +1,6 @@
1
+ Permanent Failure
2
+
3
+ A permanent failure is one which is not likely to be resolved
4
+ by resending the message in the current form. Some change to
5
+ the message or the destination must be made for successful
6
+ delivery.
@@ -0,0 +1,5 @@
1
+ Other undefined Status
2
+
3
+ Other undefined status is the only undefined error code. It
4
+ should be used for all errors for which only the class of the
5
+ error is known.
@@ -0,0 +1,3 @@
1
+ Other or Undefined Status
2
+
3
+ There is no additional subject information available.
@@ -0,0 +1,4 @@
1
+ Other address status
2
+
3
+ Something about the address specified in the message caused
4
+ this DSN.
@@ -0,0 +1,6 @@
1
+ Bad destination mailbox address
2
+
3
+ The mailbox specified in the address does not exist. For
4
+ Internet mail names, this means the address portion to the left
5
+ of the "@" sign is invalid. This code is only useful for
6
+ permanent failures.
@@ -0,0 +1,7 @@
1
+ Bad destination system address
2
+
3
+ The destination system specified in the address does not exist
4
+ or is incapable of accepting mail. For Internet mail names,
5
+ this means the address portion to the right of the "@" is
6
+ invalid for mail. This code is only useful for permanent
7
+ failures.
@@ -0,0 +1,5 @@
1
+ Bad destination mailbox address syntax
2
+
3
+ The destination address was syntactically invalid. This can
4
+ apply to any field in the address. This code is only useful
5
+ for permanent failures.
@@ -0,0 +1,6 @@
1
+ Destination mailbox address ambiguous
2
+
3
+ The mailbox address as specified matches one or more recipients
4
+ on the destination system. This may result if a heuristic
5
+ address mapping algorithm is used to map the specified address
6
+ to a local mailbox name.
@@ -0,0 +1,4 @@
1
+ Destination address valid
2
+
3
+ This mailbox address as specified was valid. This status code
4
+ should be used for positive delivery reports.
@@ -0,0 +1,5 @@
1
+ Destination mailbox has moved, No forwarding address
2
+
3
+ The mailbox address provided was at one time valid, but mail is
4
+ no longer being accepted for that address. This code is only
5
+ useful for permanent failures.
@@ -0,0 +1,4 @@
1
+ Bad sender's mailbox address syntax
2
+
3
+ The sender's address was syntactically invalid. This can apply
4
+ to any field in the address.
@@ -0,0 +1,6 @@
1
+ Bad sender's system address
2
+
3
+ The sender's system specified in the address does not exist or
4
+ is incapable of accepting return mail. For domain names, this
5
+ means the address portion to the right of the "@" is invalid
6
+ for mail.
@@ -0,0 +1,5 @@
1
+ Addressing Status
2
+
3
+ The address status reports on the originator or destination
4
+ address. It may include address syntax or validity. These
5
+ errors can generally be corrected by the sender and retried.
@@ -0,0 +1,4 @@
1
+ Other or undefined mailbox status
2
+
3
+ The mailbox exists, but something about the destination mailbox
4
+ has caused the sending of this DSN.
@@ -0,0 +1,5 @@
1
+ Mailbox disabled, not accepting messages
2
+
3
+ The mailbox exists, but is not accepting messages. This may be
4
+ a permanent error if the mailbox will never be re-enabled or a
5
+ transient error if the mailbox is only temporarily disabled.
@@ -0,0 +1,7 @@
1
+ Mailbox full
2
+
3
+ The mailbox is full because the user has exceeded a per-mailbox
4
+ administrative quota or physical capacity. The general
5
+ semantics implies that the recipient can delete messages to
6
+ make more space available. This code should be used as a
7
+ persistent transient failure.
@@ -0,0 +1,6 @@
1
+ Message length exceeds administrative limit
2
+
3
+ A per-mailbox administrative message length limit has been
4
+ exceeded. This status code should be used when the per-mailbox
5
+ message length limit is less than the general system limit.
6
+ This code should be used as a permanent failure.
@@ -0,0 +1,5 @@
1
+ Mailing list expansion problem
2
+
3
+ The mailbox is a mailing list address and the mailing list was
4
+ unable to be expanded. This code may represent a permanent
5
+ failure or a persistent transient failure.
@@ -0,0 +1,5 @@
1
+ Mailbox Status
2
+
3
+ Mailbox status indicates that something having to do with the
4
+ mailbox has caused this DSN. Mailbox issues are assumed to be
5
+ under the general control of the recipient.
@@ -0,0 +1,5 @@
1
+ Other or undefined mail system status
2
+
3
+ The destination system exists and normally accepts mail, but
4
+ something about the system has caused the generation of this
5
+ DSN.
@@ -0,0 +1,6 @@
1
+ Mail system full
2
+
3
+ Mail system storage has been exceeded. The general semantics
4
+ imply that the individual recipient may not be able to delete
5
+ material to make room for additional messages. This is useful
6
+ only as a persistent transient error.
@@ -0,0 +1,6 @@
1
+ System not accepting network messages
2
+
3
+ The host on which the mailbox is resident is not accepting
4
+ messages. Examples of such conditions include an immanent
5
+ shutdown, excessive load, or system maintenance. This is
6
+ useful for both permanent and persistent transient errors.
@@ -0,0 +1,6 @@
1
+ System not capable of selected features
2
+
3
+ Selected features specified for the message are not supported
4
+ by the destination system. This can occur in gateways when
5
+ features from one domain cannot be mapped onto the supported
6
+ feature in another.
@@ -0,0 +1,5 @@
1
+ Message too big for system
2
+
3
+ The message is larger than per-message size limit. This limit
4
+ may either be for physical or administrative reasons. This is
5
+ useful only as a permanent error.
@@ -0,0 +1,4 @@
1
+ System incorrectly configured
2
+
3
+ The system is not configured in a manner that will permit it to
4
+ accept this message.
@@ -0,0 +1,6 @@
1
+ Mail System Status
2
+
3
+ Mail system status indicates that something having to do with
4
+ the destination system has caused this DSN. System issues are
5
+ assumed to be under the general control of the destination
6
+ system administrator.
@@ -0,0 +1,5 @@
1
+ Other or undefined network or routing status
2
+
3
+ Something went wrong with the networking, but it is not clear
4
+ what the problem is, or the problem cannot be well expressed
5
+ with any of the other provided detail codes.
@@ -0,0 +1,5 @@
1
+ No answer from host
2
+
3
+ The outbound connection attempt was not answered, because
4
+ either the remote system was busy, or was unable to take a
5
+ call. This is useful only as a persistent transient error.
@@ -0,0 +1,6 @@
1
+ Bad connection
2
+
3
+ The outbound connection was established, but was unable to
4
+ complete the message transaction, either because of time-out,
5
+ or inadequate connection quality. This is useful only as a
6
+ persistent transient error.
@@ -0,0 +1,8 @@
1
+ Directory server failure
2
+
3
+ The network system was unable to forward the message, because a
4
+ directory server was unavailable. This is useful only as a
5
+ persistent transient error.
6
+
7
+ The inability to connect to an Internet DNS server is one
8
+ example of the directory server failure error.
@@ -0,0 +1,10 @@
1
+ Unable to route
2
+
3
+ The mail system was unable to determine the next hop for the
4
+ message because the necessary routing information was
5
+ unavailable from the directory server. This is useful for both
6
+ permanent and persistent transient errors.
7
+
8
+ A DNS lookup returning only an SOA (Start of Administration)
9
+ record for a domain name is one example of the unable to route
10
+ error.
@@ -0,0 +1,5 @@
1
+ Mail system congestion
2
+
3
+ The mail system was unable to deliver the message because the
4
+ mail system was congested. This is useful only as a persistent
5
+ transient error.
@@ -0,0 +1,6 @@
1
+ Routing loop detected
2
+
3
+ A routing loop caused the message to be forwarded too many
4
+ times, either because of incorrect routing tables or a user-
5
+ forwarding loop. This is useful only as a persistent transient
6
+ error.
@@ -0,0 +1,8 @@
1
+ Delivery time expired
2
+
3
+ The message was considered too old by the rejecting system,
4
+ either because it remained on that host too long or because the
5
+ time-to-live value specified by the sender of the message was
6
+ exceeded. If possible, the code for the actual problem found
7
+ when delivery was attempted should be returned rather than this
8
+ code.
@@ -0,0 +1,7 @@
1
+ Network and Routing Status
2
+
3
+ The networking or routing codes report status about the
4
+ delivery system itself. These system components include any
5
+ necessary infrastructure such as directory and routing
6
+ services. Network issues are assumed to be under the control
7
+ of the destination or intermediate system administrator.
@@ -0,0 +1,5 @@
1
+ Other or undefined protocol status
2
+
3
+ Something was wrong with the protocol necessary to deliver the
4
+ message to the next hop and the problem cannot be well
5
+ expressed with any of the other provided detail codes.
@@ -0,0 +1,5 @@
1
+ Invalid command
2
+
3
+ A mail transaction protocol command was issued which was either
4
+ out of sequence or unsupported. This is useful only as a
5
+ permanent error.
@@ -0,0 +1,6 @@
1
+ Syntax error
2
+
3
+ A mail transaction protocol command was issued which could not
4
+ be interpreted, either because the syntax was wrong or the
5
+ command is unrecognized. This is useful only as a permanent
6
+ error.
@@ -0,0 +1,8 @@
1
+ Too many recipients
2
+
3
+ More recipients were specified for the message than could have
4
+ been delivered by the protocol. This error should normally
5
+ result in the segmentation of the message into two, the
6
+ remainder of the recipients to be delivered on a subsequent
7
+ delivery attempt. It is included in this list in the event
8
+ that such segmentation is not possible.
@@ -0,0 +1,6 @@
1
+ Invalid command arguments
2
+
3
+ A valid mail transaction protocol command was issued with
4
+ invalid arguments, either because the arguments were out of
5
+ range or represented unrecognized features. This is useful
6
+ only as a permanent error.
@@ -0,0 +1,4 @@
1
+ Wrong protocol version
2
+
3
+ A protocol version mis-match existed which could not be
4
+ automatically resolved by the communicating parties.
@@ -0,0 +1,6 @@
1
+ Mail Delivery Protocol Status
2
+
3
+ The mail delivery protocol status codes report failures
4
+ involving the message delivery protocol. These failures
5
+ include the full range of problems resulting from
6
+ implementation errors or an unreliable connection.
@@ -0,0 +1,5 @@
1
+ Other or undefined media error
2
+
3
+ Something about the content of a message caused it to be
4
+ considered undeliverable and the problem cannot be well
5
+ expressed with any of the other provided detail codes.
@@ -0,0 +1,5 @@
1
+ Media not supported
2
+
3
+ The media of the message is not supported by either the
4
+ delivery protocol or the next system in the forwarding path.
5
+ This is useful only as a permanent error.
@@ -0,0 +1,6 @@
1
+ Conversion required and prohibited
2
+
3
+ The content of the message must be converted before it can be
4
+ delivered and such conversion is not permitted. Such
5
+ prohibitions may be the expression of the sender in the message
6
+ itself or the policy of the sending host.
@@ -0,0 +1,7 @@
1
+ Conversion required but not supported
2
+
3
+ The message content must be converted in order to be forwarded
4
+ but such conversion is not possible or is not practical by a
5
+ host in the forwarding path. This condition may result when an
6
+ ESMTP gateway supports 8bit transport but is not able to
7
+ downgrade the message to 7 bit as required for the next hop.
@@ -0,0 +1,7 @@
1
+ Conversion with loss performed
2
+
3
+ This is a warning sent to the sender when message delivery was
4
+ successfully but when the delivery required a conversion in
5
+ which some data was lost. This may also be a permanent error
6
+ if the sender has indicated that conversion with loss is
7
+ prohibited for the message.
@@ -0,0 +1,4 @@
1
+ Conversion Failed
2
+
3
+ A conversion was required but was unsuccessful. This may be
4
+ useful as a permanent or persistent temporary notification.
@@ -0,0 +1,8 @@
1
+ Message Content or Media Status
2
+
3
+ The message content or media status codes report failures
4
+ involving the content of the message. These codes report
5
+ failures due to translation, transcoding, or otherwise
6
+ unsupported message media. Message content or media issues are
7
+ under the control of both the sender and the receiver, both of
8
+ which must support a common set of supported content-types.
@@ -0,0 +1,7 @@
1
+ Other or undefined security status
2
+
3
+ Something related to security caused the message to be
4
+ returned, and the problem cannot be well expressed with any of
5
+ the other provided detail codes. This status code may also be
6
+ used when the condition cannot be further described because of
7
+ security policies in force.
@@ -0,0 +1,7 @@
1
+ Delivery not authorized, message refused
2
+
3
+ The sender is not authorized to send to the destination. This
4
+ can be the result of per-host or per-recipient filtering. This
5
+ memo does not discuss the merits of any such filtering, but
6
+ provides a mechanism to report such. This is useful only as a
7
+ permanent error.
@@ -0,0 +1,4 @@
1
+ Mailing list expansion prohibited
2
+
3
+ The sender is not authorized to send a message to the intended
4
+ mailing list. This is useful only as a permanent error.
@@ -0,0 +1,5 @@
1
+ Security conversion required but not possible
2
+
3
+ A conversion from one secure messaging protocol to another was
4
+ required for delivery and such conversion was not possible.
5
+ This is useful only as a permanent error.
@@ -0,0 +1,5 @@
1
+ Security features not supported
2
+
3
+ A message contained security features such as secure
4
+ authentication that could not be supported on the delivery
5
+ protocol. This is useful only as a permanent error.
@@ -0,0 +1,6 @@
1
+ Cryptographic failure
2
+
3
+ A transport system otherwise authorized to validate or decrypt
4
+ a message in transport was unable to do so because necessary
5
+ information such as key was not available or such information
6
+ was invalid.
@@ -0,0 +1,5 @@
1
+ Cryptographic algorithm not supported
2
+
3
+ A transport system otherwise authorized to validate or decrypt
4
+ a message was unable to do so because the necessary algorithm
5
+ was not supported.
@@ -0,0 +1,6 @@
1
+ Message integrity failure
2
+
3
+ A transport system otherwise authorized to validate a message
4
+ was unable to do so because the message was corrupted or
5
+ altered. This may be useful as a permanent, transient
6
+ persistent, or successful delivery code.
@@ -0,0 +1,9 @@
1
+ Security or Policy Status
2
+
3
+ The security or policy status codes report failures involving
4
+ policies such as per-recipient or per-host filtering and
5
+ cryptographic operations. Security and policy status issues
6
+ are assumed to be under the control of either or both the
7
+ sender and recipient. Both the sender and recipient must
8
+ permit the exchange of messages and arrange the exchange of
9
+ necessary keys and certificates for cryptographic operations.
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSN
4
+ # Descriptions of each Subcode as per RFC3463
5
+ class Message
6
+ def initialize(subcode)
7
+ @subcode = subcode
8
+ end
9
+
10
+ def summary
11
+ data.first
12
+ end
13
+
14
+ def body
15
+ data.last.gsub("\n", ' ').strip
16
+ end
17
+
18
+ def to_s
19
+ [summary, body].join("\n\n")
20
+ end
21
+
22
+ protected
23
+
24
+ attr_reader :subcode
25
+
26
+ private
27
+
28
+ def data
29
+ @data ||= data!
30
+ end
31
+
32
+ def data!
33
+ File.read(filepath).split("\n\n")
34
+ rescue Errno::ENOENT
35
+ raise InvalidSubcode, %("#{subcode}")
36
+ end
37
+
38
+ # TODO: Cleanup
39
+ def filepath
40
+ "#{__dir__}/data/#{subcode}"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSN
4
+ module Parser
5
+ # Parse DSN subcode componentds from a String
6
+ class String
7
+ def initialize(code)
8
+ @code = code
9
+ end
10
+
11
+ def class_subcode
12
+ parts[0]
13
+ end
14
+
15
+ def subject_subcode
16
+ parts[1]
17
+ end
18
+
19
+ def detail_subcode
20
+ parts[2]
21
+ end
22
+
23
+ def to_s
24
+ code
25
+ end
26
+
27
+ protected
28
+
29
+ attr_reader :code
30
+
31
+ private
32
+
33
+ def parts
34
+ @parts ||= parts!
35
+ end
36
+
37
+ def parts!
38
+ split_parts = code.split('.')
39
+ raise InvalidStatusCode unless split_parts.compact.size == 3
40
+
41
+ split_parts
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module DSN
6
+ # The full status code
7
+ class StatusCode
8
+ extend Forwardable
9
+
10
+ def self.from_string(code)
11
+ new(Parser::String.new(code))
12
+ end
13
+
14
+ def_delegators :class_subcode, :success?, :transient_failure?, :failed?
15
+
16
+ def initialize(code)
17
+ @code = code
18
+ @class_subcode = Subcode::ClassSubcode.new(code)
19
+ @subject_subcode = Subcode::SubjectSubcode.new(code)
20
+ @detail_subcode = Subcode::DetailSubcode.new(code)
21
+ end
22
+
23
+ def valid?
24
+ subcodes.all?(&:valid?)
25
+ end
26
+
27
+ # Returns the most detailed subcode that is valid
28
+ def subcode
29
+ raise InvalidStatusCode unless class_subcode.valid?
30
+
31
+ subcodes.select(&:valid?).last
32
+ end
33
+
34
+ def to_s
35
+ code.to_s
36
+ end
37
+
38
+ attr_reader :class_subcode
39
+ attr_reader :subject_subcode
40
+ attr_reader :detail_subcode
41
+
42
+ protected
43
+
44
+ attr_reader :code
45
+
46
+ private
47
+
48
+ def subcodes
49
+ [class_subcode, subject_subcode, detail_subcode]
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSN
4
+ module Subcode
5
+ # Shared behaviour for subcodes.
6
+ class Base
7
+ def initialize(status_code)
8
+ @status_code = status_code
9
+ end
10
+
11
+ def valid?
12
+ File.exist?(filepath)
13
+ rescue InvalidSubcode
14
+ false
15
+ end
16
+
17
+ def to_s
18
+ filename
19
+ end
20
+
21
+ def to_i
22
+ Integer(significant_parts.last)
23
+ rescue ArgumentError
24
+ raise InvalidSubcode
25
+ end
26
+
27
+ protected
28
+
29
+ attr_reader :status_code
30
+
31
+ private
32
+
33
+ def filename
34
+ format_string % significant_parts
35
+ rescue ArgumentError
36
+ raise InvalidSubcode
37
+ end
38
+
39
+ def format_string
40
+ raise NotImplementedError
41
+ end
42
+
43
+ def significant_parts
44
+ raise NotImplementedError
45
+ end
46
+
47
+ # TODO: Cleanup
48
+ def filepath
49
+ "#{__dir__}/../data/#{self}"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSN
4
+ module Subcode
5
+ # The class sub-code provides a broad classification of the status.
6
+ class ClassSubcode < Subcode::Base
7
+ SUCCESS_CODE = 2
8
+ TRANSIENT_FAILURE_CODE = 4
9
+ FAILURE_CODE = 5
10
+
11
+ def success?
12
+ to_i == SUCCESS_CODE
13
+ end
14
+
15
+ def transient_failure?
16
+ to_i == TRANSIENT_FAILURE_CODE
17
+ end
18
+
19
+ def failed?
20
+ to_i == FAILURE_CODE
21
+ end
22
+
23
+ private
24
+
25
+ def format_string
26
+ '%d.XXX.XXX'
27
+ end
28
+
29
+ def significant_parts
30
+ [status_code.class_subcode]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSN
4
+ module Subcode
5
+ # The detail value provides more information about the status and is defined
6
+ # relative to the subject of the status.
7
+ class DetailSubcode < Subcode::Base
8
+ private
9
+
10
+ def format_string
11
+ 'X.%d.%d'
12
+ end
13
+
14
+ def significant_parts
15
+ [status_code.subject_subcode, status_code.detail_subcode]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSN
4
+ module Subcode
5
+ # The subject sub-code classifies the status. This value applies to each of
6
+ # the three classifications.
7
+ class SubjectSubcode < Subcode::Base
8
+ private
9
+
10
+ def format_string
11
+ 'X.%d.XXX'
12
+ end
13
+
14
+ def significant_parts
15
+ [status_code.subject_subcode]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSN
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dsn
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gareth Rees
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-07-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ description:
28
+ email:
29
+ - gareth@garethrees.co.uk
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - ".travis.yml"
36
+ - CHANGELOG.md
37
+ - Gemfile
38
+ - Gemfile.lock
39
+ - README.md
40
+ - Rakefile
41
+ - bin/console
42
+ - bin/setup
43
+ - dsn.gemspec
44
+ - lib/dsn.rb
45
+ - lib/dsn/data/2.XXX.XXX
46
+ - lib/dsn/data/4.XXX.XXX
47
+ - lib/dsn/data/5.XXX.XXX
48
+ - lib/dsn/data/X.0.0
49
+ - lib/dsn/data/X.0.XXX
50
+ - lib/dsn/data/X.1.0
51
+ - lib/dsn/data/X.1.1
52
+ - lib/dsn/data/X.1.2
53
+ - lib/dsn/data/X.1.3
54
+ - lib/dsn/data/X.1.4
55
+ - lib/dsn/data/X.1.5
56
+ - lib/dsn/data/X.1.6
57
+ - lib/dsn/data/X.1.7
58
+ - lib/dsn/data/X.1.8
59
+ - lib/dsn/data/X.1.XXX
60
+ - lib/dsn/data/X.2.0
61
+ - lib/dsn/data/X.2.1
62
+ - lib/dsn/data/X.2.2
63
+ - lib/dsn/data/X.2.3
64
+ - lib/dsn/data/X.2.4
65
+ - lib/dsn/data/X.2.XXX
66
+ - lib/dsn/data/X.3.0
67
+ - lib/dsn/data/X.3.1
68
+ - lib/dsn/data/X.3.2
69
+ - lib/dsn/data/X.3.3
70
+ - lib/dsn/data/X.3.4
71
+ - lib/dsn/data/X.3.5
72
+ - lib/dsn/data/X.3.XXX
73
+ - lib/dsn/data/X.4.0
74
+ - lib/dsn/data/X.4.1
75
+ - lib/dsn/data/X.4.2
76
+ - lib/dsn/data/X.4.3
77
+ - lib/dsn/data/X.4.4
78
+ - lib/dsn/data/X.4.5
79
+ - lib/dsn/data/X.4.6
80
+ - lib/dsn/data/X.4.7
81
+ - lib/dsn/data/X.4.XXX
82
+ - lib/dsn/data/X.5.0
83
+ - lib/dsn/data/X.5.1
84
+ - lib/dsn/data/X.5.2
85
+ - lib/dsn/data/X.5.3
86
+ - lib/dsn/data/X.5.4
87
+ - lib/dsn/data/X.5.5
88
+ - lib/dsn/data/X.5.XXX
89
+ - lib/dsn/data/X.6.0
90
+ - lib/dsn/data/X.6.1
91
+ - lib/dsn/data/X.6.2
92
+ - lib/dsn/data/X.6.3
93
+ - lib/dsn/data/X.6.4
94
+ - lib/dsn/data/X.6.5
95
+ - lib/dsn/data/X.6.XXX
96
+ - lib/dsn/data/X.7.0
97
+ - lib/dsn/data/X.7.1
98
+ - lib/dsn/data/X.7.2
99
+ - lib/dsn/data/X.7.3
100
+ - lib/dsn/data/X.7.4
101
+ - lib/dsn/data/X.7.5
102
+ - lib/dsn/data/X.7.6
103
+ - lib/dsn/data/X.7.7
104
+ - lib/dsn/data/X.7.XXX
105
+ - lib/dsn/message.rb
106
+ - lib/dsn/parser/string.rb
107
+ - lib/dsn/status_code.rb
108
+ - lib/dsn/subcode/base.rb
109
+ - lib/dsn/subcode/class_subcode.rb
110
+ - lib/dsn/subcode/detail_subcode.rb
111
+ - lib/dsn/subcode/subject_subcode.rb
112
+ - lib/dsn/version.rb
113
+ homepage: https://github.com/garethrees/dsn
114
+ licenses:
115
+ - MIT
116
+ metadata:
117
+ homepage_uri: https://github.com/garethrees/dsn
118
+ source_code_uri: https://github.com/garethrees/dsn
119
+ changelog_uri: https://github.com/garethrees/dsn/blob/master/CHANGELOG.md
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: 2.3.0
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubygems_version: 3.1.2
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: Ruby parser for RFC 3463 Delivery Status Notification codes
139
+ test_files: []