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"]