Class: HTTPX::Resolver
- Inherits:
-
Object
- Object
- HTTPX::Resolver
- Extended by:
- Forwardable
- Includes:
- Loggable
- Defined in:
- lib/httpx/io/resolver.rb
Constant Summary collapse
- MAX_PACKET_SIZE =
Maximum UDP packet we’ll accept
512
- DNS_PORT =
53
Constants included from Loggable
Class Method Summary collapse
Instance Method Summary collapse
- #call ⇒ Object
- #dread(wsize = MAX_PACKET_SIZE) ⇒ Object
-
#initialize(options) ⇒ Resolver
constructor
A new instance of Resolver.
- #resolve(hostname, &action) ⇒ Object
- #to_io ⇒ Object
Methods included from Loggable
Constructor Details
#initialize(options) ⇒ Resolver
Returns a new instance of Resolver.
27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/httpx/io/resolver.rb', line 27 def initialize() @options = Options.new() # early return for edge case when there are no nameservers configured # but we still want to be able to static lookups using #resolve_hostname (@nameservers = self.class.nameservers) || return server = IPAddr.new(@nameservers.sample) @io = UDP.new(server, DNS_PORT) @read_buffer = "".b @addresses = {} @hostnames = [] @callbacks = [] @state = :idle end |
Class Method Details
.generate_id ⇒ Object
18 19 20 |
# File 'lib/httpx/io/resolver.rb', line 18 def self.generate_id @mutex.synchronize { @identifier = (@identifier + 1) & 0xFFFF } end |
.nameservers ⇒ Object
22 23 24 |
# File 'lib/httpx/io/resolver.rb', line 22 def self.nameservers Resolv::DNS::Config.default_config_hash[:nameserver] end |
Instance Method Details
#call ⇒ Object
61 62 63 64 65 |
# File 'lib/httpx/io/resolver.rb', line 61 def call return if @state == :closed return if @hostnames.empty? dread end |
#dread(wsize = MAX_PACKET_SIZE) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/httpx/io/resolver.rb', line 67 def dread(wsize = MAX_PACKET_SIZE) loop do siz = @io.read(wsize, @read_buffer) throw(:close, self) unless siz return if siz.zero? log { "READ: #{siz} bytes..." } addrs = parse(@read_buffer) @read_buffer.clear next if addrs.empty? hostname = @hostnames.shift callback = @callbacks.shift addr = addrs.index(addrs.rand(addrs.size)) log { "resolved #{hostname}: #{addr}" } @addresses[hostname] = addr callback.call(addr) end end |
#resolve(hostname, &action) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/httpx/io/resolver.rb', line 45 def resolve(hostname, &action) if host = resolve_hostname(hostname) unless ip_address = resolve_host(host) raise Resolv::ResolvError, "invalid entry in hosts file: #{host}" end @addresses[hostname] = ip_address action.call(ip_address) end @hostnames << hostname @callbacks << action query = build_query(hostname).encode log { "resolving #{hostname}: #{query.inspect}" } siz = @io.write(query) log { "WRITE: #{siz} bytes..." } end |
#to_io ⇒ Object
41 42 43 |
# File 'lib/httpx/io/resolver.rb', line 41 def to_io @io.to_io end |