Class: HTTPX::DomainName

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/httpx/domain_name.rb

Overview

Represents a domain name ready for extracting its registered domain and TLD.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hostname) ⇒ DomainName

Parses hostname into a DomainName object. An IP address is also accepted. An IPv6 address may be enclosed in square brackets.

Raises:

  • (ArgumentError)


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/httpx/domain_name.rb', line 75

def initialize(hostname)
  hostname = String(hostname)

  raise ArgumentError, "domain name must not start with a dot: #{hostname}" if hostname.start_with?(".")

  begin
    @ipaddr = IPAddr.new(hostname)
    @hostname = @ipaddr.to_s
    return
  rescue IPAddr::Error
    nil
  end

  @hostname = DomainName.normalize(hostname)
  tld = if (last_dot = @hostname.rindex("."))
    @hostname[(last_dot + 1)..-1]
  else
    @hostname
  end

  # unknown/local TLD
  @domain = if last_dot
    # fallback - accept cookies down to second level
    # cf. http://www.dkim-reputation.org/regdom-libs/
    if (penultimate_dot = @hostname.rindex(".", last_dot - 1))
      @hostname[(penultimate_dot + 1)..-1]
    else
      @hostname
    end
  else
    # no domain part - must be a local hostname
    tld
  end
end

Instance Attribute Details

#domainObject (readonly)

The least “universally original” domain part of this domain name. For example, “example.co.uk” for “www.sub.example.co.uk”. This may be nil if the hostname does not have one, like when it is an IP address, an effective TLD or higher itself, or of a non-canonical domain.



52
53
54
# File 'lib/httpx/domain_name.rb', line 52

def domain
  @domain
end

#hostnameObject (readonly)

The full host name normalized, ASCII-ized and downcased using the Unicode NFC rules and the Punycode algorithm. If initialized with an IP address, the string representation of the IP address suitable for opening a connection to.



41
42
43
# File 'lib/httpx/domain_name.rb', line 41

def hostname
  @hostname
end

Class Method Details

.new(domain) ⇒ Object



55
56
57
58
59
# File 'lib/httpx/domain_name.rb', line 55

def new(domain)
  return domain if domain.is_a?(self)

  super(domain)
end

.normalize(domain) ⇒ Object

Normalizes a domain using the Punycode algorithm as necessary. The result will be a downcased, ASCII-only string.



63
64
65
66
67
68
69
70
# File 'lib/httpx/domain_name.rb', line 63

def normalize(domain)
  unless domain.ascii_only?
    domain = domain.chomp(".").unicode_normalize(:nfc)
    domain = Punycode.encode_hostname(domain)
  end

  domain.downcase
end

Instance Method Details

#<=>(other) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/httpx/domain_name.rb', line 131

def <=>(other)
  other = DomainName.new(other)
  othername = other.hostname
  if othername == @hostname
    0
  elsif @hostname.end_with?(othername) && @hostname[-othername.size - 1, 1] == "."
    # The other is higher
    -1
  else
    # The other is lower
    1
  end
end

Checks if the server represented by this domain is qualified to send and receive cookies with a domain attribute value of domain. A true value given as the second argument represents cookies without a domain attribute value, in which case only hostname equality is checked.

Returns:

  • (Boolean)


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/httpx/domain_name.rb', line 115

def cookie_domain?(domain, host_only = false)
  # RFC 6265 #5.3
  # When the user agent "receives a cookie":
  return self == @domain if host_only

  domain = DomainName.new(domain)

  # RFC 6265 #5.1.3
  # Do not perform subdomain matching against IP addresses.
  @hostname == domain.hostname if @ipaddr

  # RFC 6265 #4.1.1
  # Domain-value must be a subdomain.
  @domain && self <= domain && domain <= @domain
end