Base class for all internal internet name resolvers. It handles basic blocks from the Selectable API.
Methods
Public Class
Public Instance
Included modules
Constants
| FAMILY_TYPES | = | { Resolv::DNS::Resource::IN::AAAA => "AAAA", Resolv::DNS::Resource::IN::A => "A", }.freeze | ||
| RECORD_TYPES | = | { Socket::AF_INET6 => Resolv::DNS::Resource::IN::AAAA, Socket::AF_INET => Resolv::DNS::Resource::IN::A, }.freeze |
Public Instance Aliases
| terminate | -> | close |
Attributes
| current_selector | [W] | |
| current_session | [W] | |
| family | [R] | |
| multi | [RW] | |
| options | [R] |
Public Class methods
new(family, options)
[show source]
# File lib/httpx/resolver/resolver.rb 36 def initialize(family, options) 37 @family = family 38 @record_type = RECORD_TYPES[family] 39 @options = options 40 @connections = [] 41 end
Public Instance methods
each_connection(&block)
[show source]
# File lib/httpx/resolver/resolver.rb 43 def each_connection(&block) 44 enum_for(__method__) unless block 45 46 return unless @connections 47 48 @connections.each(&block) 49 end
early_resolve(connection, hostname: connection.peer.host)
[show source]
# File lib/httpx/resolver/resolver.rb 127 def early_resolve(connection, hostname: connection.peer.host) 128 addresses = @resolver_options[:cache] && (connection.addresses || HTTPX::Resolver.nolookup_resolve(hostname)) 129 130 return false unless addresses 131 132 addresses = addresses.select { |addr| addr.family == @family } 133 134 return false if addresses.empty? 135 136 emit_addresses(connection, @family, addresses, true) 137 138 true 139 end
emit_addresses(connection, family, addresses, early_resolve = false)
[show source]
# File lib/httpx/resolver/resolver.rb 73 def emit_addresses(connection, family, addresses, early_resolve = false) 74 addresses.map! { |address| address.is_a?(Resolver::Entry) ? address : Resolver::Entry.new(address) } 75 76 # double emission check, but allow early resolution to work 77 conn_addrs = connection.addresses 78 return if !early_resolve && conn_addrs && (!conn_addrs.empty? && !addresses.intersect?(conn_addrs)) 79 80 log do 81 "resolver #{FAMILY_TYPES[RECORD_TYPES[family]]}: " \ 82 "answer #{connection.peer.host}: #{addresses.inspect} (early resolve: #{early_resolve})" 83 end 84 85 # do not apply resolution delay for non-dns name resolution 86 if !early_resolve && 87 # just in case... 88 @current_selector && 89 # resolution delay only applies to IPv4 90 family == Socket::AF_INET && 91 # connection already has addresses and initiated/ended handshake 92 !connection.io && 93 # no need to delay if not supporting dual stack / multi-homed IP 94 (connection.options.ip_families || Resolver.supported_ip_families).size > 1 && 95 # connection URL host is already the IP (early resolve included perhaps?) 96 addresses.first.to_s != connection.peer.host.to_s 97 log { "resolver #{FAMILY_TYPES[RECORD_TYPES[family]]}: applying resolution delay..." } 98 99 @current_selector.after(0.05) do 100 # double emission check 101 unless connection.addresses && addresses.intersect?(connection.addresses) 102 emit_resolved_connection(connection, addresses, early_resolve) 103 end 104 end 105 else 106 emit_resolved_connection(connection, addresses, early_resolve) 107 end 108 end
force_close(*args)
[show source]
# File lib/httpx/resolver/resolver.rb 55 def force_close(*args) 56 while (connection = @connections.shift) 57 connection.force_close(*args) 58 end 59 end
handle_error(error)
[show source]
# File lib/httpx/resolver/resolver.rb 110 def handle_error(error) 111 if error.respond_to?(:connection) && 112 error.respond_to?(:host) 113 @connections.delete(error.connection) 114 emit_resolve_error(error.connection, error.host, error) 115 else 116 while (connection = @connections.shift) 117 emit_resolve_error(connection, connection.peer.host, error) 118 end 119 end 120 end
on_error(error)
[show source]
# File lib/httpx/resolver/resolver.rb 122 def on_error(error) 123 handle_error(error) 124 disconnect 125 end