Skip to content

Commit

Permalink
fix: translate unicode domain names to Punycode for compatibility wit…
Browse files Browse the repository at this point in the history
…h DNS (#2823)
  • Loading branch information
catphish committed Feb 29, 2024
1 parent ae30cc7 commit be0df7b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 27 deletions.
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -5,6 +5,7 @@ gem "authie"
gem "autoprefixer-rails"
gem "bcrypt"
gem "chronic"
gem "domain_name"
gem "dotenv"
gem "dynamic_form"
gem "encrypto_signo"
Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Expand Up @@ -101,6 +101,7 @@ GEM
date (3.3.4)
deep_merge (1.2.2)
diff-lcs (1.5.0)
domain_name (0.6.20240107)
dotenv (3.0.2)
dynamic_form (1.3.1)
actionview (> 5.2.0)
Expand Down Expand Up @@ -334,6 +335,7 @@ DEPENDENCIES
chronic
coffee-rails (~> 5.0)
database_cleaner
domain_name
dotenv
dynamic_form
encrypto_signo
Expand Down
51 changes: 24 additions & 27 deletions app/lib/dns_resolver.rb
Expand Up @@ -17,10 +17,8 @@ def initialize(nameservers: nil, timeout: 5)
# @param [String] name
# @return [Array<String>]
def a(name)
dns do |dns|
dns.getresources(name, Resolv::DNS::Resource::IN::A).map do |s|
s.address.to_s
end
get_resources(name, Resolv::DNS::Resource::IN::A).map do |s|
s.address.to_s
end
end

Expand All @@ -29,10 +27,8 @@ def a(name)
# @param [String] name
# @return [Array<String>]
def aaaa(name)
dns do |dns|
dns.getresources(name, Resolv::DNS::Resource::IN::AAAA).map do |s|
s.address.to_s
end
get_resources(name, Resolv::DNS::Resource::IN::AAAA).map do |s|
s.address.to_s
end
end

Expand All @@ -41,10 +37,8 @@ def aaaa(name)
# @param [String] name
# @return [Array<String>]
def txt(name)
dns do |dns|
dns.getresources(name, Resolv::DNS::Resource::IN::TXT).map do |s|
s.data.to_s.strip
end
get_resources(name, Resolv::DNS::Resource::IN::TXT).map do |s|
s.data.to_s.strip
end
end

Expand All @@ -53,10 +47,8 @@ def txt(name)
# @param [String] name
# @return [Array<String>]
def cname(name)
dns do |dns|
dns.getresources(name, Resolv::DNS::Resource::IN::CNAME).map do |s|
s.name.to_s.downcase
end
get_resources(name, Resolv::DNS::Resource::IN::CNAME).map do |s|
s.name.to_s.downcase
end
end

Expand All @@ -65,16 +57,14 @@ def cname(name)
# @param [String] name
# @return [Array<Array<Integer, String>>]
def mx(name)
dns do |dns|
records = dns.getresources(name, Resolv::DNS::Resource::IN::MX).map do |m|
[m.preference.to_i, m.exchange.to_s]
end
records.sort do |a, b|
if a[0] == b[0]
[-1, 1].sample
else
a[0] <=> b[0]
end
records = get_resources(name, Resolv::DNS::Resource::IN::MX).map do |m|
[m.preference.to_i, m.exchange.to_s]
end
records.sort do |a, b|
if a[0] == b[0]
[-1, 1].sample
else
a[0] <=> b[0]
end
end
end
Expand All @@ -90,7 +80,7 @@ def effective_ns(name)
(parts.size - 1).times do |n|
d = parts[n, parts.size - n + 1].join(".")

records = dns.getresources(d, Resolv::DNS::Resource::IN::NS).map do |s|
records = get_resources(d, Resolv::DNS::Resource::IN::NS).map do |s|
s.name.to_s
end

Expand Down Expand Up @@ -124,6 +114,13 @@ def dns
end
end

def get_resources(name, type)
encoded_name = DomainName::Punycode.encode_hostname(name)
dns do |dns|
dns.getresources(encoded_name, type)
end
end

class << self

# Return a resolver which will use the nameservers for the given domain
Expand Down
3 changes: 3 additions & 0 deletions spec/lib/dns_resolver_spec.rb
Expand Up @@ -14,6 +14,9 @@
it "returns a list of IP addresses" do
expect(resolver.a("www.test.postalserver.io").sort).to eq ["1.2.3.4", "2.3.4.5"]
end
it "resolves a domain name containing an emoji" do
expect(resolver.a("☺.test.postalserver.io").sort).to eq ["3.4.5.6"]
end
end

describe "#aaaa" do
Expand Down

0 comments on commit be0df7b

Please sign in to comment.