Class: MonoVM::Whois::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/monovm/whois/client.rb

Overview

Looks up one domain, end to end.

The client owns the sequence — resolve the TLD, pick an endpoint, fetch, classify, parse, maybe follow a referral — and none of the policy. Which server serves a TLD is the registry's business, how to talk to it is the transport's, what the answer means is the analyzer's, and what the record says is the parser's. Every one of them arrives by injection, so a spec can replace any single step without touching the others.

client = MonoVM::Whois::Client.new
client.lookup("monovm.com").status  # => :registered

Constant Summary collapse

REGISTRAR_WINS =

Fields where the registrar's copy is the better one, used when a thin registry's record is merged with the registrar's. Everywhere else the registry wins, because it is authoritative for whether the name exists, what state it is in and when it expires — and registrars are frequently stale on exactly those. The registrant and the contact block are the reverse: a thin registry never has them at all.

i[registrant contacts].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config: nil, server_registry: nil, transport_factory: nil, analyzer: nil, parsers: nil, follower: nil) ⇒ Client

Every argument defaults from config; pass one to replace that collaborator.



35
36
37
38
39
40
41
42
43
# File 'lib/monovm/whois/client.rb', line 35

def initialize(config: nil, server_registry: nil, transport_factory: nil,
               analyzer: nil, parsers: nil, follower: nil)
  @config = config || Configuration.new
  @server_registry = server_registry || @config.server_registry
  @transport_factory = transport_factory || @config.transport_factory
  @analyzer = analyzer || @config.analyzer
  @parsers = parsers || @config.parsers
  @follower = follower || default_follower
end

Instance Attribute Details

#analyzerObject (readonly)

Returns the value of attribute analyzer.



32
33
34
# File 'lib/monovm/whois/client.rb', line 32

def analyzer
  @analyzer
end

#configObject (readonly)

Returns the value of attribute config.



32
33
34
# File 'lib/monovm/whois/client.rb', line 32

def config
  @config
end

#followerObject (readonly)

Returns the value of attribute follower.



32
33
34
# File 'lib/monovm/whois/client.rb', line 32

def follower
  @follower
end

#parsersObject (readonly)

Returns the value of attribute parsers.



32
33
34
# File 'lib/monovm/whois/client.rb', line 32

def parsers
  @parsers
end

#server_registryObject (readonly)

Returns the value of attribute server_registry.



32
33
34
# File 'lib/monovm/whois/client.rb', line 32

def server_registry
  @server_registry
end

#transport_factoryObject (readonly)

Returns the value of attribute transport_factory.



32
33
34
# File 'lib/monovm/whois/client.rb', line 32

def transport_factory
  @transport_factory
end

Instance Method Details

#available?(domain) ⇒ Boolean

Returns true only when the lookup positively established availability.

Returns:

  • true only when the lookup positively established availability



66
67
68
# File 'lib/monovm/whois/client.rb', line 66

def available?(domain)
  lookup(domain).available?
end

#explain(domain) ⇒ Hash

Why a lookup came out the way it did, including every rule consulted.

Returns:



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/monovm/whois/client.rb', line 73

def explain(domain)
  result = lookup(domain)

  {
    domain: result.name,
    status: result.status,
    tld: result.tld,
    reason: result.reason,
    trace: result.verdict&.trace || [],
    endpoint: result.response&.endpoint&.to_s,
    record: result.record&.to_h
  }
end

#lookup(domain) ⇒ Result

Returns never raises for a lookup failure; the failure is the result.

Parameters:

Returns:

  • never raises for a lookup failure; the failure is the result



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/monovm/whois/client.rb', line 47

def lookup(domain)
  name = domain.is_a?(DomainName) ? domain : DomainName.parse(domain)

  return Result.invalid(name, reason: "#{name} is not a valid domain name") unless name.valid?

  if name.bare?
    return Result.invalid(
      name,
      reason: "#{name} has no TLD; give one, or use Checker to try popular TLDs"
    )
  end

  resolution = server_registry.resolve(name)
  return Result.invalid(name, reason: "no WHOIS or RDAP server is known for #{name}") if resolution.nil?

  perform(name, resolution)
end