Module: HTTPX::Resolver
- Defined in:
- lib/httpx/resolver.rb
Defined Under Namespace
Classes: HTTPS, Multi, Native, Resolver, System
Constant Summary collapse
- RESOLVE_TIMEOUT =
[2, 3].freeze
Class Method Summary collapse
- .cached_lookup(hostname) ⇒ Object
- .cached_lookup_set(hostname, family, entries) ⇒ Object
- .decode_dns_answer(payload) ⇒ Object
- .encode_dns_query(hostname, type: Resolv::DNS::Resource::IN::A, message_id: generate_id) ⇒ Object
- .generate_id ⇒ Object
- .id_synchronize(&block) ⇒ Object
- .ip_resolve(hostname) ⇒ Object
-
.lookup(hostname, lookups, ttl) ⇒ Object
do not use directly!.
- .lookup_synchronize ⇒ Object
- .nolookup_resolve(hostname) ⇒ Object
- .resolver_for(resolver_type) ⇒ Object
- .system_resolve(hostname) ⇒ Object
Class Method Details
permalink .cached_lookup(hostname) ⇒ Object
[View source]
54 55 56 57 58 59 |
# File 'lib/httpx/resolver.rb', line 54 def cached_lookup(hostname) now = Utils.now lookup_synchronize do |lookups| lookup(hostname, lookups, now) end end |
permalink .cached_lookup_set(hostname, family, entries) ⇒ Object
[View source]
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/httpx/resolver.rb', line 61 def cached_lookup_set(hostname, family, entries) now = Utils.now entries.each do |entry| entry["TTL"] += now end lookup_synchronize do |lookups| case family when Socket::AF_INET6 lookups[hostname].concat(entries) when Socket::AF_INET lookups[hostname].unshift(*entries) end entries.each do |entry| next unless entry["name"] != hostname case family when Socket::AF_INET6 lookups[entry["name"]] << entry when Socket::AF_INET lookups[entry["name"]].unshift(entry) end end end end |
permalink .decode_dns_answer(payload) ⇒ Object
[View source]
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/httpx/resolver.rb', line 116 def decode_dns_answer(payload) begin = Resolv::DNS::Message.decode(payload) rescue Resolv::DNS::DecodeError => e return :decode_error, e end # no domain was found return :no_domain_found if .rcode == Resolv::DNS::RCode::NXDomain return :message_truncated if .tc == 1 return :dns_error, .rcode if .rcode != Resolv::DNS::RCode::NoError addresses = [] .each_answer do |question, _, value| case value when Resolv::DNS::Resource::IN::CNAME addresses << { "name" => question.to_s, "TTL" => value.ttl, "alias" => value.name.to_s, } when Resolv::DNS::Resource::IN::A, Resolv::DNS::Resource::IN::AAAA addresses << { "name" => question.to_s, "TTL" => value.ttl, "data" => value.address.to_s, } end end [:ok, addresses] end |
permalink .encode_dns_query(hostname, type: Resolv::DNS::Resource::IN::A, message_id: generate_id) ⇒ Object
[View source]
109 110 111 112 113 114 |
# File 'lib/httpx/resolver.rb', line 109 def encode_dns_query(hostname, type: Resolv::DNS::Resource::IN::A, message_id: generate_id) Resolv::DNS::Message.new().tap do |query| query.rd = 1 query.add_question(hostname, type) end.encode end |
permalink .generate_id ⇒ Object
[View source]
105 106 107 |
# File 'lib/httpx/resolver.rb', line 105 def generate_id id_synchronize { @identifier = (@identifier + 1) & 0xFFFF } end |
permalink .id_synchronize(&block) ⇒ Object
[View source]
157 158 159 |
# File 'lib/httpx/resolver.rb', line 157 def id_synchronize(&block) @identifier_mutex.synchronize(&block) end |
permalink .ip_resolve(hostname) ⇒ Object
[View source]
41 42 43 44 |
# File 'lib/httpx/resolver.rb', line 41 def ip_resolve(hostname) [IPAddr.new(hostname)] rescue ArgumentError end |
permalink .lookup(hostname, lookups, ttl) ⇒ Object
do not use directly!
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/httpx/resolver.rb', line 87 def lookup(hostname, lookups, ttl) return unless lookups.key?(hostname) entries = lookups[hostname] = lookups[hostname].select do |address| address["TTL"] > ttl end ips = entries.flat_map do |address| if address.key?("alias") lookup(address["alias"], lookups, ttl) else IPAddr.new(address["data"]) end end.compact ips unless ips.empty? end |
permalink .lookup_synchronize ⇒ Object
[View source]
153 154 155 |
# File 'lib/httpx/resolver.rb', line 153 def lookup_synchronize @lookup_mutex.synchronize { yield(@lookups) } end |
permalink .nolookup_resolve(hostname) ⇒ Object
[View source]
37 38 39 |
# File 'lib/httpx/resolver.rb', line 37 def nolookup_resolve(hostname) ip_resolve(hostname) || cached_lookup(hostname) || system_resolve(hostname) end |
permalink .resolver_for(resolver_type) ⇒ Object
[View source]
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/httpx/resolver.rb', line 25 def resolver_for(resolver_type) case resolver_type when :native then Native when :system then System when :https then HTTPS else return resolver_type if resolver_type.is_a?(Class) && resolver_type < Resolver raise Error, "unsupported resolver type (#{resolver_type})" end end |
permalink .system_resolve(hostname) ⇒ Object
[View source]
46 47 48 49 50 51 52 |
# File 'lib/httpx/resolver.rb', line 46 def system_resolve(hostname) ips = @system_resolver.getaddresses(hostname) return if ips.empty? ips.map { |ip| IPAddr.new(ip) } rescue IOError end |