Class: MonoVM::Whois::DomainName
- Inherits:
-
Object
- Object
- MonoVM::Whois::DomainName
- Defined in:
- lib/monovm/whois/domain_name.rb
Overview
An immutable, normalised domain name.
This class knows about the name and nothing else: how to clean up what a
user pasted, how to move between Unicode and Punycode, and whether the
result is a legal host name. Deciding which part of it is the TLD needs the
server definitions, so that belongs to Registry::ServerRegistry — a name
cannot know on its own whether .co.uk is a suffix or two labels.
name = DomainName.parse(" HTTPS://WWW.MÜNCHEN.de:8080/path?q=1 ")
name.to_s # => "www.münchen.de"
name.ascii # => "www.xn--mnchen-3ya.de"
name.valid? # => true
Constant Summary collapse
- ACE_PREFIX =
"xn--"- MAX_LENGTH =
253- MAX_LABEL_LENGTH =
63- LABEL =
A single legal DNS label: alphanumeric ends, hyphens allowed inside.
/\A[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\z/
Instance Attribute Summary collapse
-
#ascii ⇒ Object
readonly
The ASCII (Punycode) form — what goes on the wire and into URLs.
-
#ascii_labels ⇒ Object
readonly
The ASCII (Punycode) form — what goes on the wire and into URLs.
-
#input ⇒ Object
readonly
Returns the value of attribute input.
-
#labels ⇒ Object
readonly
The ASCII (Punycode) form — what goes on the wire and into URLs.
-
#unicode ⇒ Object
readonly
Returns the value of attribute unicode.
Class Method Summary collapse
-
.parse(input) ⇒ DomainName
Normalise
inputinto a name. -
.parse!(input) ⇒ Object
Like DomainName.parse but raises when the result is not a usable host name.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#bare? ⇒ Boolean
True when the name carries no dot, so no TLD was supplied.
- #hash ⇒ Object
-
#idn? ⇒ Boolean
True when the name needed Punycode, i.e.
-
#initialize(input) ⇒ DomainName
constructor
Everything is computed here rather than memoised on demand, because the instance is frozen: a value object that lazily fills in an ivar would raise FrozenError the first time anyone asked for it.
- #inspect ⇒ Object
-
#join(suffix) ⇒ Object
Build a new name by appending
suffixto this one. -
#to_s ⇒ Object
The Unicode form — what a human reads.
-
#valid? ⇒ Boolean
True when every label is a legal DNS label and the whole name fits in a DNS query.
Constructor Details
#initialize(input) ⇒ DomainName
Everything is computed here rather than memoised on demand, because the instance is frozen: a value object that lazily fills in an ivar would raise FrozenError the first time anyone asked for it.
56 57 58 59 60 61 62 63 64 |
# File 'lib/monovm/whois/domain_name.rb', line 56 def initialize(input) @input = input @unicode = normalise(input).freeze @labels = @unicode.split(".", -1).freeze @ascii = @labels.map { |label| label_to_ascii(label) }.join(".").freeze @ascii_labels = @ascii.split(".", -1).freeze @valid = compute_valid? freeze end |
Instance Attribute Details
#ascii ⇒ Object (readonly)
The ASCII (Punycode) form — what goes on the wire and into URLs.
Registries are queried in this form by default: Verisign answers "No match" to a UTF-8 query, which would read as availability.
75 76 77 |
# File 'lib/monovm/whois/domain_name.rb', line 75 def ascii @ascii end |
#ascii_labels ⇒ Object (readonly)
The ASCII (Punycode) form — what goes on the wire and into URLs.
Registries are queried in this form by default: Verisign answers "No match" to a UTF-8 query, which would read as availability.
75 76 77 |
# File 'lib/monovm/whois/domain_name.rb', line 75 def ascii_labels @ascii_labels end |
#input ⇒ Object (readonly)
Returns the value of attribute input.
28 29 30 |
# File 'lib/monovm/whois/domain_name.rb', line 28 def input @input end |
#labels ⇒ Object (readonly)
The ASCII (Punycode) form — what goes on the wire and into URLs.
Registries are queried in this form by default: Verisign answers "No match" to a UTF-8 query, which would read as availability.
75 76 77 |
# File 'lib/monovm/whois/domain_name.rb', line 75 def labels @labels end |
#unicode ⇒ Object (readonly)
Returns the value of attribute unicode.
28 29 30 |
# File 'lib/monovm/whois/domain_name.rb', line 28 def unicode @unicode end |
Class Method Details
.parse(input) ⇒ DomainName
Normalise input into a name. Never raises: an unusable string yields
an instance whose #valid? is false, which is what bulk callers want so
one bad entry does not abort a batch.
37 38 39 40 41 |
# File 'lib/monovm/whois/domain_name.rb', line 37 def parse(input) raise InvalidDomainError, input unless input.is_a?(String) new(input) end |
.parse!(input) ⇒ Object
Like parse but raises when the result is not a usable host name.
46 47 48 49 50 |
# File 'lib/monovm/whois/domain_name.rb', line 46 def parse!(input) parse(input).tap do |name| raise InvalidDomainError, input unless name.valid? end end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
103 104 105 |
# File 'lib/monovm/whois/domain_name.rb', line 103 def ==(other) other.is_a?(DomainName) && other.unicode == unicode end |
#bare? ⇒ Boolean
True when the name carries no dot, so no TLD was supplied.
90 91 92 |
# File 'lib/monovm/whois/domain_name.rb', line 90 def !unicode.include?(".") end |
#hash ⇒ Object
108 109 110 |
# File 'lib/monovm/whois/domain_name.rb', line 108 def hash [self.class, unicode].hash end |
#idn? ⇒ Boolean
True when the name needed Punycode, i.e. it has non-ASCII labels.
85 86 87 |
# File 'lib/monovm/whois/domain_name.rb', line 85 def idn? ascii != unicode end |
#inspect ⇒ Object
112 113 114 |
# File 'lib/monovm/whois/domain_name.rb', line 112 def inspect "#<#{self.class.name} #{unicode.inspect}#{" invalid" unless valid?}>" end |
#join(suffix) ⇒ Object
Build a new name by appending suffix to this one.
DomainName.parse("monovm").join(".com").to_s # => "monovm.com"
97 98 99 100 101 |
# File 'lib/monovm/whois/domain_name.rb', line 97 def join(suffix) suffix = suffix.to_s suffix = ".#{suffix}" unless suffix.start_with?(".") self.class.parse("#{unicode}#{suffix}") end |
#to_s ⇒ Object
The Unicode form — what a human reads.
67 68 69 |
# File 'lib/monovm/whois/domain_name.rb', line 67 def to_s unicode end |
#valid? ⇒ Boolean
True when every label is a legal DNS label and the whole name fits in a DNS query. A single-label name like "monovm" is valid — callers append a TLD to it — so this deliberately does not require a dot.
80 81 82 |
# File 'lib/monovm/whois/domain_name.rb', line 80 def valid? @valid end |