lib/httpx/resolver/https.rb in httpx-0.10.0 vs lib/httpx/resolver/https.rb in httpx-0.10.1
- old
+ new
@@ -19,39 +19,40 @@
}.freeze
DEFAULTS = {
uri: NAMESERVER,
use_get: false,
+ record_types: RECORD_TYPES.keys,
}.freeze
def_delegator :@connections, :empty?
def_delegators :@resolver_connection, :connecting?, :to_io, :call, :close
def initialize(options)
@options = Options.new(options)
- @resolver_options = Resolver::Options.new(DEFAULTS.merge(@options.resolver_options || {}))
- @_record_types = Hash.new { |types, host| types[host] = RECORD_TYPES.keys.dup }
+ @resolver_options = DEFAULTS.merge(@options.resolver_options)
+ @_record_types = Hash.new { |types, host| types[host] = @resolver_options[:record_types].dup }
@queries = {}
@requests = {}
@connections = []
- @uri = URI(@resolver_options.uri)
+ @uri = URI(@resolver_options[:uri])
@uri_addresses = nil
end
def <<(connection)
return if @uri.origin == connection.origin.to_s
@uri_addresses ||= Resolv.getaddresses(@uri.host)
if @uri_addresses.empty?
- ex = ResolveError.new("Can't resolve #{connection.origin.host}")
+ ex = ResolveError.new("Can't resolve DNS server #{@uri.host}")
ex.set_backtrace(caller)
- emit(:error, connection, ex)
- else
- early_resolve(connection) || resolve(connection)
+ throw(:resolve_error, ex)
end
+
+ early_resolve(connection) || resolve(connection)
end
def timeout
@connections.map(&:timeout).min
end
@@ -68,16 +69,10 @@
resolver_connection.__send__(__method__)
end
private
- def connect
- return if @queries.empty?
-
- resolver_connection.__send__(__method__)
- end
-
def pool
Thread.current[:httpx_connection_pool] ||= Pool.new
end
def resolver_connection
@@ -98,14 +93,16 @@
if hostname.nil?
hostname = connection.origin.host
log { "resolver: resolve IDN #{connection.origin.non_ascii_hostname} as #{hostname}" } if connection.origin.non_ascii_hostname
end
- type = @_record_types[hostname].first
+ type = @_record_types[hostname].first || "A"
log { "resolver: query #{type} for #{hostname}" }
begin
request = build_request(hostname, type)
+ request.on(:response, &method(:on_response).curry[request])
+ request.on(:promise, &method(:on_promise))
@requests[request] = connection
resolver_connection.send(request)
@queries[hostname] = connection
@connections << connection
rescue Resolv::DNS::EncodeError, JSON::JSONError => e
@@ -116,13 +113,11 @@
def on_response(request, response)
response.raise_for_status
rescue StandardError => e
connection = @requests[request]
hostname = @queries.key(connection)
- error = ResolveError.new("Can't resolve #{hostname}: #{e.message}")
- error.set_backtrace(e.backtrace)
- emit(:error, connection, error)
+ emit_resolve_error(connection, hostname, e)
else
parse(response)
ensure
@requests.delete(request)
end
@@ -141,11 +136,11 @@
@queries.delete(host)
emit_resolve_error(connection, host, e)
return
end
end
- if answers.empty?
+ if answers.nil? || answers.empty?
host, connection = @queries.first
@_record_types[host].shift
if @_record_types[host].empty?
@queries.delete(host)
@_record_types.delete(host)
@@ -175,11 +170,11 @@
hostname = hostname[0..-2] if hostname.end_with?(".")
connection = @queries.delete(hostname)
next unless connection # probably a retried query for which there's an answer
@connections.delete(connection)
- Resolver.cached_lookup_set(hostname, addresses) if @resolver_options.cache
+ Resolver.cached_lookup_set(hostname, addresses) if @resolver_options[:cache]
emit_addresses(connection, addresses.map { |addr| addr["data"] })
end
end
return if @connections.empty?
@@ -189,22 +184,20 @@
def build_request(hostname, type)
uri = @uri.dup
rklass = @options.request_class
payload = Resolver.encode_dns_query(hostname, type: RECORD_TYPES[type])
- if @resolver_options.use_get
+ if @resolver_options[:use_get]
params = URI.decode_www_form(uri.query.to_s)
params << ["type", type]
params << ["dns", Base64.urlsafe_encode64(payload, padding: false)]
uri.query = URI.encode_www_form(params)
request = rklass.new("GET", uri, @options)
else
request = rklass.new("POST", uri, @options.merge(body: [payload]))
request.headers["content-type"] = "application/dns-message"
end
request.headers["accept"] = "application/dns-message"
- request.on(:response, &method(:on_response).curry[request])
- request.on(:promise, &method(:on_promise))
request
end
def decode_response_body(response)
case response.headers["content-type"]