Class: HTTPX::Resolver::Native

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
ResolverMixin
Defined in:
lib/httpx/resolver/native.rb

Constant Summary collapse

RESOLVE_TIMEOUT =
5
RECORD_TYPES =
{
  "A" => Resolv::DNS::Resource::IN::A,
  "AAAA" => Resolv::DNS::Resource::IN::AAAA,
}.freeze
DEFAULTS =
if RUBY_VERSION < "2.2"
  {
    **Resolv::DNS::Config.default_config_hash,
    packet_size: 512,
    timeouts: RESOLVE_TIMEOUT,
    record_types: RECORD_TYPES.keys,
  }.freeze
else
  {
    nameserver: nil,
    **Resolv::DNS::Config.default_config_hash,
    packet_size: 512,
    timeouts: RESOLVE_TIMEOUT,
    record_types: RECORD_TYPES.keys,
  }.freeze
end
DNS_PORT =
53

Constants included from ResolverMixin

ResolverMixin::CHECK_IF_IP

Constants included from Loggable

Loggable::COLORS

Instance Method Summary collapse

Methods included from ResolverMixin

#uncache

Methods included from Loggable

#log, #log_exception

Methods included from Callbacks

#emit, #on, #once

Constructor Details

#initialize(options) ⇒ Native

Returns a new instance of Native.


50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/httpx/resolver/native.rb', line 50

def initialize(options)
  @options = Options.new(options)
  @ns_index = 0
  @resolver_options = Resolver::Options.new(DEFAULTS.merge(@options.resolver_options || {}))
  @nameserver = @resolver_options.nameserver
  @_timeouts = Array(@resolver_options.timeouts)
  @timeouts = Hash.new { |timeouts, host| timeouts[host] = @_timeouts.dup }
  @_record_types = Hash.new { |types, host| types[host] = @resolver_options.record_types.dup }
  @connections = []
  @queries = {}
  @read_buffer = Buffer.new(@resolver_options.packet_size)
  @write_buffer = Buffer.new(@resolver_options.packet_size)
  @state = :idle
end

Instance Method Details

#<<(connection) ⇒ Object


121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/httpx/resolver/native.rb', line 121

def <<(connection)
  return if early_resolve(connection)

  if @nameserver.nil?
    ex = ResolveError.new("Can't resolve #{connection.origin.host}: no nameserver")
    ex.set_backtrace(caller)
    emit(:error, connection, ex)
  else
    @connections << connection
    resolve
  end
end

#callObject


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/httpx/resolver/native.rb', line 85

def call
  case @state
  when :open
    consume
  end
  nil
rescue Errno::EHOSTUNREACH,
       NativeResolveError => e
  @ns_index += 1
  if @ns_index < @nameserver.size
    log(label: "resolver: ") do
      "failed resolving on nameserver #{@nameserver[@ns_index - 1]} (#{e.message})"
    end
    transition(:idle)
  else
    if e.respond_to?(:connection) &&
       e.respond_to?(:host)
      emit_resolve_error(e.connection, e.host, e)
    else
      @queries.each do |host, connection|
        emit_resolve_error(connection, host, e)
      end
    end
  end
end

#closeObject


65
66
67
# File 'lib/httpx/resolver/native.rb', line 65

def close
  transition(:closed)
end

#closed?Boolean

Returns:

  • (Boolean)

69
70
71
# File 'lib/httpx/resolver/native.rb', line 69

def closed?
  @state == :closed
end

#interestsObject


111
112
113
114
115
116
117
118
119
# File 'lib/httpx/resolver/native.rb', line 111

def interests
  readable = !@read_buffer.full?
  writable = !@write_buffer.empty?
  if readable
    writable ? :rw : :r
  else
    writable ? :w : :r
  end
end

#timeoutObject


134
135
136
137
138
# File 'lib/httpx/resolver/native.rb', line 134

def timeout
  @start_timeout = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  hosts = @queries.keys
  @timeouts.values_at(*hosts).reject(&:empty?).map(&:first).min
end

#to_ioObject


73
74
75
76
77
78
79
80
81
82
83
# File 'lib/httpx/resolver/native.rb', line 73

def to_io
  case @state
  when :idle
    transition(:open)
  when :closed
    transition(:idle)
    transition(:open)
  end
  resolve if @queries.empty?
  @io.to_io
end