Methods
Public Instance
Classes and Modules
Constants
RESOLVE_TIMEOUT | = | [2, 3].freeze |
Public Instance methods
cached_lookup(hostname)
[show source]
# File lib/httpx/resolver.rb 73 def cached_lookup(hostname) 74 now = Utils.now 75 lookup_synchronize do |lookups| 76 lookup(hostname, lookups, now) 77 end 78 end
cached_lookup_evict(hostname, ip)
[show source]
# File lib/httpx/resolver.rb 101 def cached_lookup_evict(hostname, ip) 102 ip = ip.to_s 103 104 lookup_synchronize do |lookups| 105 entries = lookups[hostname] 106 107 return unless entries 108 109 lookups.delete_if { |entry| entry["data"] == ip } 110 end 111 end
cached_lookup_set(hostname, family, entries)
[show source]
# File lib/httpx/resolver.rb 80 def cached_lookup_set(hostname, family, entries) 81 lookup_synchronize do |lookups| 82 case family 83 when Socket::AF_INET6 84 lookups[hostname].concat(entries) 85 when Socket::AF_INET 86 lookups[hostname].unshift(*entries) 87 end 88 entries.each do |entry| 89 next unless entry["name"] != hostname 90 91 case family 92 when Socket::AF_INET6 93 lookups[entry["name"]] << entry 94 when Socket::AF_INET 95 lookups[entry["name"]].unshift(entry) 96 end 97 end 98 end 99 end
decode_dns_answer(payload)
[show source]
# File lib/httpx/resolver.rb 143 def decode_dns_answer(payload) 144 begin 145 message = Resolv::DNS::Message.decode(payload) 146 rescue Resolv::DNS::DecodeError => e 147 return :decode_error, e 148 end 149 150 # no domain was found 151 return :no_domain_found if message.rcode == Resolv::DNS::RCode::NXDomain 152 153 return :message_truncated if message.tc == 1 154 155 return :dns_error, message.rcode if message.rcode != Resolv::DNS::RCode::NoError 156 157 addresses = [] 158 159 now = Utils.now 160 message.each_answer do |question, _, value| 161 case value 162 when Resolv::DNS::Resource::IN::CNAME 163 addresses << { 164 "name" => question.to_s, 165 "TTL" => (now + value.ttl), 166 "alias" => value.name.to_s, 167 } 168 when Resolv::DNS::Resource::IN::A, 169 Resolv::DNS::Resource::IN::AAAA 170 addresses << { 171 "name" => question.to_s, 172 "TTL" => (now + value.ttl), 173 "data" => value.address.to_s, 174 } 175 end 176 end 177 178 [:ok, addresses] 179 end
encode_dns_query(hostname, type: Resolv::DNS::Resource::IN::A, message_id: generate_id)
[show source]
# File lib/httpx/resolver.rb 136 def encode_dns_query(hostname, type: Resolv::DNS::Resource::IN::A, message_id: generate_id) 137 Resolv::DNS::Message.new(message_id).tap do |query| 138 query.rd = 1 139 query.add_question(hostname, type) 140 end.encode 141 end
generate_id()
[show source]
# File lib/httpx/resolver.rb 132 def generate_id 133 id_synchronize { @identifier = (@identifier + 1) & 0xFFFF } 134 end
hosts_resolve(hostname)
matches hostname
to entries in the hosts file, returns <tt>nil</nil> if none is found, or there is no hosts file.
[show source]
# File lib/httpx/resolver.rb 65 def hosts_resolve(hostname) 66 ips = @hosts_resolver.getaddresses(hostname) 67 return if ips.empty? 68 69 ips.map { |ip| Entry.new(ip) } 70 rescue IOError 71 end
id_synchronize(&block)
[show source]
# File lib/httpx/resolver.rb 185 def id_synchronize(&block) 186 @identifier_mutex.synchronize(&block) 187 end
ip_resolve(hostname)
tries to convert hostname
into an IPAddr, returns nil
otherwise.
[show source]
# File lib/httpx/resolver.rb 58 def ip_resolve(hostname) 59 [Entry.new(hostname)] 60 rescue ArgumentError 61 end
lookup(hostname, lookups, ttl)
do not use directly!
[show source]
# File lib/httpx/resolver.rb 114 def lookup(hostname, lookups, ttl) 115 return unless lookups.key?(hostname) 116 117 entries = lookups[hostname] = lookups[hostname].select do |address| 118 address["TTL"] > ttl 119 end 120 121 ips = entries.flat_map do |address| 122 if (als = address["alias"]) 123 lookup(als, lookups, ttl) 124 else 125 Entry.new(address["data"], address["TTL"]) 126 end 127 end.compact 128 129 ips unless ips.empty? 130 end
lookup_synchronize()
[show source]
# File lib/httpx/resolver.rb 181 def lookup_synchronize 182 @lookup_mutex.synchronize { yield(@lookups) } 183 end
nolookup_resolve(hostname)
[show source]
# File lib/httpx/resolver.rb 53 def nolookup_resolve(hostname) 54 ip_resolve(hostname) || cached_lookup(hostname) || hosts_resolve(hostname) 55 end
resolver_for(resolver_type, options)
[show source]
# File lib/httpx/resolver.rb 40 def resolver_for(resolver_type, options) 41 case resolver_type 42 when Symbol 43 meth = :"resolver_#{resolver_type}_class" 44 45 return options.__send__(meth) if options.respond_to?(meth) 46 when Class 47 return resolver_type if resolver_type < Resolver 48 end 49 50 raise Error, "unsupported resolver type (#{resolver_type})" 51 end
supported_ip_families()
[show source]
# File lib/httpx/resolver.rb 26 def supported_ip_families 27 @supported_ip_families ||= begin 28 # https://github.com/ruby/resolv/blob/095f1c003f6073730500f02acbdbc55f83d70987/lib/resolv.rb#L408 29 list = Socket.ip_address_list 30 if list.any? { |a| a.ipv6? && !a.ipv6_loopback? && !a.ipv6_linklocal? } 31 [Socket::AF_INET6, Socket::AF_INET] 32 else 33 [Socket::AF_INET] 34 end 35 rescue NotImplementedError 36 [Socket::AF_INET] 37 end.freeze 38 end