Skip to content
This repository was archived by the owner on May 21, 2025. It is now read-only.

Commit c71c7a4

Browse files
Cache results of mx_server_is_in? to speed up disposable_mx_server? lookup for the same domain
1 parent 6f8f067 commit c71c7a4

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

lib/valid_email2/address.rb

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require "valid_email2"
44
require "mail"
55
require "valid_email2/dns"
6+
require "digest"
67

78
module ValidEmail2
89
class Address
@@ -11,6 +12,7 @@ class Address
1112
PROHIBITED_DOMAIN_CHARACTERS_REGEX = /[+!_\/\s'#`]/
1213
DEFAULT_RECIPIENT_DELIMITER = '+'
1314
DOT_DELIMITER = '.'
15+
@cache_mx_server_is_in = {}
1416

1517
def self.prohibited_domain_characters_regex
1618
@prohibited_domain_characters_regex ||= PROHIBITED_DOMAIN_CHARACTERS_REGEX
@@ -130,15 +132,24 @@ def domain_is_in?(domain_list)
130132
end
131133

132134
def mx_server_is_in?(domain_list)
133-
@dns.mx_servers(address.domain).any? { |mx_server|
135+
mx_servers = @dns.mx_servers(address.domain)
136+
137+
cache_key = generate_mx_cache_key(domain_list, mx_servers)
138+
139+
return self.class.cache_mx_server_is_in[cache_key] if !cache_key.nil? && self.class.cache_mx_server_is_in.key?(cache_key)
140+
141+
result = mx_servers.any? do |mx_server|
134142
return false unless mx_server.respond_to?(:exchange)
135143

136144
mx_server = mx_server.exchange.to_s
137145

138-
domain_list.any? { |domain|
146+
domain_list.any? do |domain|
139147
mx_server.end_with?(domain) && mx_server =~ /\A(?:.+\.)*?#{domain}\z/
140-
}
141-
}
148+
end
149+
end
150+
151+
self.class.cache_mx_server_is_in[cache_key] = result unless cache_key.nil?
152+
result
142153
end
143154

144155
def address_contain_multibyte_characters?
@@ -153,5 +164,18 @@ def null_mx?
153164
mx_servers = @dns.mx_servers(address.domain)
154165
mx_servers.length == 1 && mx_servers.first.preference == 0 && mx_servers.first.exchange.length == 0
155166
end
167+
168+
def generate_mx_cache_key(domain_list, mx_servers)
169+
return nil if mx_servers.length == 0 || domain_list.length == 0
170+
171+
mx_servers_str = mx_servers.map(&:exchange).map(&:to_s).sort.join
172+
return address.domain if mx_servers_str == ""
173+
174+
"#{domain_list.object_id}_#{domain_list.length}_#{mx_servers_str.downcase}"
175+
end
176+
177+
def self.cache_mx_server_is_in
178+
@cache_mx_server_is_in
179+
end
156180
end
157181
end

0 commit comments

Comments
 (0)