Class: EmailAddress::Exchanger
- Inherits:
-
Object
- Object
- EmailAddress::Exchanger
- Includes:
- Enumerable
- Defined in:
- lib/email_address/exchanger.rb
Class Method Summary collapse
Instance Method Summary collapse
-
#domains ⇒ Object
Returns Array of domain names for the MX’ers, used to determine the Provider.
- #each(&block) ⇒ Object
-
#in_cidr?(cidr) ⇒ Boolean
Given a cidr (ip/bits) and ip address, returns true on match.
-
#initialize(host, config = {}) ⇒ Exchanger
constructor
A new instance of Exchanger.
-
#matches?(rules) ⇒ Boolean
Simple matcher, takes an array of CIDR addresses (ip/bits) and strings.
-
#mx_ips ⇒ Object
Returns an array of MX IP address (String) for the given email domain.
-
#mxers ⇒ Object
Returns: [[“mta7.am0.yahoodns.net”, “66.94.237.139”, 1], [“mta5.am0.yahoodns.net”, “67.195.168.230”, 1], [“mta6.am0.yahoodns.net”, “98.139.54.60”, 1]] If not found, returns [].
-
#provider ⇒ Object
Returns the provider name based on the MX-er host names, or nil if not matched.
Constructor Details
#initialize(host, config = {}) ⇒ Exchanger
Returns a new instance of Exchanger.
23 24 25 26 |
# File 'lib/email_address/exchanger.rb', line 23 def initialize(host, config={}) @host = host @config = config end |
Class Method Details
.cached(host) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/email_address/exchanger.rb', line 9 def self.cached(host) @host_cache ||= {} @cache_size ||= ENV['EMAIL_ADDRESS_CACHE_SIZE'].to_i || 100 if @host_cache.has_key?(host) o = @host_cache.delete(host) @host_cache[host] = o # LRU cache, move to end elsif @host_cache.size >= @cache_size @host_cache.delete(@host_cache.keys.first) @host_cache[host] = new(host) else @host_cache[host] = new(host) end end |
Instance Method Details
#domains ⇒ Object
Returns Array of domain names for the MX’ers, used to determine the Provider
66 67 68 |
# File 'lib/email_address/exchanger.rb', line 66 def domains @_domains ||= mxers.map {|m| EmailAddress::Host.new(m.first).domain_name }.sort.uniq end |
#each(&block) ⇒ Object
28 29 30 31 32 |
# File 'lib/email_address/exchanger.rb', line 28 def each(&block) mxers.each do |m| yield({host:m[0], ip:m[1], priority:m[2]}) end end |
#in_cidr?(cidr) ⇒ Boolean
Given a cidr (ip/bits) and ip address, returns true on match. Caches cidr object.
94 95 96 97 98 99 100 101 102 103 |
# File 'lib/email_address/exchanger.rb', line 94 def in_cidr?(cidr) c = NetAddr::CIDR.create(cidr) if cidr.include?(":") mx_ips.find { |ip| ip.include?(":") && c.matches?(ip) } ? true : false elsif cidr.include?(".") mx_ips.find { |ip| !ip.include?(":") && c.matches?(ip) } ? true : false else false end end |
#matches?(rules) ⇒ Boolean
Simple matcher, takes an array of CIDR addresses (ip/bits) and strings. Returns true if any MX IP matches the CIDR or host name ends in string. Ex: match?(%w(127.0.0.1/32 0:0:1/64 .yahoodns.net)) Note: Your networking stack may return IPv6 addresses instead of IPv4 when both are available. If matching on IP, be sure to include both IPv4 and IPv6 forms for matching for hosts running on IPv6 (like gmail).
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/email_address/exchanger.rb', line 81 def matches?(rules) rules = Array(rules) rules.each do |rule| if rule.include?("/") return rule if self.in_cidr?(rule) else self.each {|mx| return rule if mx[:host].end_with?(rule) } end end false end |
#mx_ips ⇒ Object
Returns an array of MX IP address (String) for the given email domain
71 72 73 |
# File 'lib/email_address/exchanger.rb', line 71 def mx_ips mxers.map {|m| m[1] } end |
#mxers ⇒ Object
Returns: [[“mta7.am0.yahoodns.net”, “66.94.237.139”, 1], [“mta5.am0.yahoodns.net”, “67.195.168.230”, 1], [“mta6.am0.yahoodns.net”, “98.139.54.60”, 1]] If not found, returns []
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/email_address/exchanger.rb', line 47 def mxers @mxers ||= Resolv::DNS.open do |dns| ress = dns.getresources(@host, Resolv::DNS::Resource::IN::MX) records = ress.map do |r| begin if r.exchange.to_s > " " [r.exchange.to_s, IPSocket::getaddress(r.exchange.to_s), r.preference] else nil end rescue SocketError # not found, but could also mean network not work or it could mean one record doesn't resolve an address nil end end records.compact end end |
#provider ⇒ Object
Returns the provider name based on the MX-er host names, or nil if not matched
35 36 37 38 39 40 41 42 43 |
# File 'lib/email_address/exchanger.rb', line 35 def provider return @provider if defined? @provider EmailAddress::Config.providers.each do |provider, config| if config[:exchanger_match] && self.matches?(config[:exchanger_match]) return @provider = provider end end @provider = :default end |