Class: MonoVM::Whois::Availability::Context

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

Overview

Everything a rule needs to reach a verdict, prepared once.

Ten rules run over the same response, and most of them want the same derived forms of it: downcased, split into lines, stripped of registry commentary. Computing those here rather than in each rule keeps the rules to a few lines each and stops the same regexp work happening ten times per lookup.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(response:, tld: nil, definition: nil) ⇒ Context

Returns a new instance of Context.

Parameters:

  • response (Response, nil)

    nil when no server was reached

  • tld (String, nil) (defaults to: nil)

    the matched suffix, with a leading dot

  • definition (Registry::Definition, nil) (defaults to: nil)


20
21
22
23
24
# File 'lib/monovm/whois/availability/context.rb', line 20

def initialize(response:, tld: nil, definition: nil)
  @response = response
  @tld = tld
  @definition = definition
end

Instance Attribute Details

#definitionObject (readonly)

Returns the value of attribute definition.



15
16
17
# File 'lib/monovm/whois/availability/context.rb', line 15

def definition
  @definition
end

#responseObject (readonly)

Returns the value of attribute response.



15
16
17
# File 'lib/monovm/whois/availability/context.rb', line 15

def response
  @response
end

#tldObject (readonly)

Returns the value of attribute tld.



15
16
17
# File 'lib/monovm/whois/availability/context.rb', line 15

def tld
  @tld
end

Instance Method Details

#count(patterns, source: :text) ⇒ Integer

Returns how many of patterns appear at least once.

Returns:

  • (Integer)

    how many of patterns appear at least once



100
101
102
103
# File 'lib/monovm/whois/availability/context.rb', line 100

def count(patterns, source: :text)
  subject = subject_for(source)
  patterns.count { |pattern| pattern.match?(subject) }
end

#empty?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/monovm/whois/availability/context.rb', line 35

def empty?
  text.strip.empty?
end

#find(patterns, source: :text) ⇒ String?

Returns the matched text, for use as verdict evidence.

Returns:

  • (String, nil)

    the matched text, for use as verdict evidence



84
85
86
87
88
89
90
91
92
93
# File 'lib/monovm/whois/availability/context.rb', line 84

def find(patterns, source: :text)
  subject = subject_for(source)

  patterns.each do |pattern|
    match = pattern.match(subject)
    return trim(match[0]) if match
  end

  nil
end

#find_keyword(keywords, source: :significant) ⇒ String?

Substring search, for the plain keyword list.

Returns:

  • (String, nil)

    the keyword that matched



108
109
110
111
# File 'lib/monovm/whois/availability/context.rb', line 108

def find_keyword(keywords, source: :significant)
  subject = source == :significant ? significant_lower : lower
  keywords.find { |keyword| subject.include?(keyword) }
end

#http_statusObject



52
53
54
# File 'lib/monovm/whois/availability/context.rb', line 52

def http_status
  response&.status
end

#jsonObject

The parsed RDAP document, or nil.



44
45
46
# File 'lib/monovm/whois/availability/context.rb', line 44

def json
  response&.json
end

#lengthObject



39
40
41
# File 'lib/monovm/whois/availability/context.rb', line 39

def length
  text.length
end

#linesObject



56
57
58
# File 'lib/monovm/whois/availability/context.rb', line 56

def lines
  @lines ||= text.split("\n").map(&:strip)
end

#lowerObject



31
32
33
# File 'lib/monovm/whois/availability/context.rb', line 31

def lower
  @lower ||= text.downcase
end

#match?(patterns, source: :text) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/monovm/whois/availability/context.rb', line 95

def match?(patterns, source: :text)
  !find(patterns, source: source).nil?
end

#preview(limit = 200) ⇒ Object

A short excerpt for diagnostics, so a surprising verdict can be explained without dumping a whole record into a log.



115
116
117
118
# File 'lib/monovm/whois/availability/context.rb', line 115

def preview(limit = 200)
  collapsed = text.strip.gsub(/\s+/, " ")
  collapsed.length > limit ? "#{collapsed[0, limit]}..." : collapsed
end

#rdap?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/monovm/whois/availability/context.rb', line 48

def rdap?
  response ? response.rdap? : false
end

#significant_linesObject

Lines that carry record data rather than registry commentary.

This matters more than it looks. Registries put phrases like "not found" and "no match" in their legal preamble, and a keyword scan over the raw text picks those up and calls a registered domain free. Stripping comment prefixes and known boilerplate first is what makes the keyword rules safe enough to use at all.



67
68
69
70
71
72
73
# File 'lib/monovm/whois/availability/context.rb', line 67

def significant_lines
  @significant_lines ||= lines.reject do |line|
    line.empty? ||
      Patterns::COMMENT_PREFIXES.any? { |prefix| line.start_with?(prefix) } ||
      Patterns::BOILERPLATE.any? { |pattern| pattern.match?(line) }
  end
end

#significant_lowerObject



79
80
81
# File 'lib/monovm/whois/availability/context.rb', line 79

def significant_lower
  @significant_lower ||= significant_text.downcase
end

#significant_textObject



75
76
77
# File 'lib/monovm/whois/availability/context.rb', line 75

def significant_text
  @significant_text ||= significant_lines.join("\n")
end

#textObject

The response text with line endings normalised, or "" when absent.



27
28
29
# File 'lib/monovm/whois/availability/context.rb', line 27

def text
  @text ||= response ? response.text : ""
end