Class: Coppertone::Utils::DomainUtils

Inherits:
Object
  • Object
show all
Defined in:
lib/coppertone/utils/domain_utils.rb

Overview

A utility class that includes methods for working with domain names.

Constant Summary collapse

NO_DASH_NONNUMERIC_REGEXP =
/\A[a-zA-Z0-9]*[a-zA-Z]+[a-zA-Z0-9]*\z/.freeze
NO_DASH_REGEXP =
/\A[a-zA-Z0-9]+\z/.freeze
DASH_REGEXP =
/\A[a-zA-Z0-9]+-[a-zA-Z0-9\-]*[a-zA-Z0-9]+\z/.freeze

Class Method Summary collapse

Class Method Details

.labels_valid?(labels) ⇒ Boolean

Returns:

  • (Boolean)


15
16
17
18
19
20
21
# File 'lib/coppertone/utils/domain_utils.rb', line 15

def self.labels_valid?(labels)
  return false if labels.length <= 1
  return false if labels.first == '*'
  return false unless valid_tld?(labels.last)

  labels.all? { |l| valid_label?(l) }
end

.macro_expanded_domain(domain) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/coppertone/utils/domain_utils.rb', line 72

def self.macro_expanded_domain(domain)
  return nil if domain.blank?

  labels = to_ascii_labels(domain)
  domain = labels.join('.')
  while domain.length > 253
    labels = labels.drop(1)
    domain = labels.join('.')
  end
  domain
end

.normalized_domain(domain) ⇒ Object



39
40
41
# File 'lib/coppertone/utils/domain_utils.rb', line 39

def self.normalized_domain(domain)
  to_ascii_labels(domain).join('.')
end

.parent_domain(domain) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/coppertone/utils/domain_utils.rb', line 27

def self.parent_domain(domain)
  labels = to_labels(domain)
  return '.' if labels.size == 1

  labels.shift
  labels.join('.')
end

.subdomain_of?(subdomain_candidate, domain) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
88
89
90
91
# File 'lib/coppertone/utils/domain_utils.rb', line 84

def self.subdomain_of?(subdomain_candidate, domain)
  subdomain_labels = to_ascii_labels(subdomain_candidate)
  domain_labels = to_ascii_labels(domain)
  num_labels_in_domain = domain_labels.length
  return false if subdomain_labels.length <= domain_labels.length

  subdomain_labels.last(num_labels_in_domain) == domain_labels
end

.subdomain_or_same?(candidate, domain) ⇒ Boolean

Returns:

  • (Boolean)


93
94
95
96
97
98
# File 'lib/coppertone/utils/domain_utils.rb', line 93

def self.subdomain_or_same?(candidate, domain)
  return false unless valid?(domain) && valid?(candidate)
  return true if normalized_domain(domain) == normalized_domain(candidate)

  subdomain_of?(candidate, domain)
end

.to_ascii_labels(domain) ⇒ Object



35
36
37
# File 'lib/coppertone/utils/domain_utils.rb', line 35

def self.to_ascii_labels(domain)
  Addressable::IDNA.to_ascii(domain).split('.').map(&:downcase)
end

.to_labels(domain) ⇒ Object



23
24
25
# File 'lib/coppertone/utils/domain_utils.rb', line 23

def self.to_labels(domain)
  domain.split('.')
end

.valid?(domain) ⇒ Boolean

Returns:

  • (Boolean)


8
9
10
11
12
13
# File 'lib/coppertone/utils/domain_utils.rb', line 8

def self.valid?(domain)
  return false if domain.blank?
  return false if domain.length > 253

  labels_valid?(to_ascii_labels(domain))
end

.valid_hostname_label?(l) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
51
# File 'lib/coppertone/utils/domain_utils.rb', line 47

def self.valid_hostname_label?(l)
  return false unless valid_label?(l)

  NO_DASH_REGEXP.match(l) || DASH_REGEXP.match(l)
end

.valid_label?(l) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/coppertone/utils/domain_utils.rb', line 68

def self.valid_label?(l)
  !l.empty? && (l.length <= 63) && !l.match(/(\s|@)/)
end

.valid_ldh_domain?(domain) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
64
65
66
# File 'lib/coppertone/utils/domain_utils.rb', line 59

def self.valid_ldh_domain?(domain)
  return false unless valid?(domain)

  labels = to_ascii_labels(domain)
  return false unless valid_tld?(labels.last)

  labels.all? { |l| valid_hostname_label?(l) }
end

.valid_tld?(l) ⇒ Boolean

Returns:

  • (Boolean)


53
54
55
56
57
# File 'lib/coppertone/utils/domain_utils.rb', line 53

def self.valid_tld?(l)
  return false unless valid_label?(l)

  NO_DASH_NONNUMERIC_REGEXP.match(l) || DASH_REGEXP.match(l)
end