PageRenderTime 41ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/bundle/ruby/1.9.1/gems/domain_name-0.5.3/lib/domain_name.rb

https://bitbucket.org/mulligan/extractext
Ruby | 236 lines | 170 code | 23 blank | 43 comment | 23 complexity | 65bd9d2f10babe943aa15601fd5b11e3 MD5 | raw file
Possible License(s): Apache-2.0, MIT, GPL-3.0, GPL-2.0, BSD-3-Clause, MPL-2.0-no-copyleft-exception, BSD-2-Clause, JSON
  1. # -*- coding: utf-8 -*-
  2. #
  3. # domain_name.rb - Domain Name manipulation library for Ruby
  4. #
  5. # Copyright (C) 2011 Akinori MUSHA, All rights reserved.
  6. #
  7. require 'domain_name/punycode'
  8. require 'domain_name/etld_data'
  9. require 'unf'
  10. require 'ipaddr'
  11. # Represents a domain name ready for extracting its registered domain
  12. # and TLD.
  13. class DomainName
  14. # The full host name normalized, ASCII-ized and downcased using the
  15. # Unicode NFC rules and the Punycode algorithm. If initialized with
  16. # an IP address, the string representation of the IP address
  17. # suitable for opening a connection to.
  18. attr_reader :hostname
  19. # The least "universally original" domain part of this domain name.
  20. # For example, "example.co.uk" for "www.sub.example.co.uk".
  21. attr_reader :domain
  22. # The TLD part of this domain name. For example, if the hostname is
  23. # "www.sub.example.co.uk", the TLD part is "uk". This property is
  24. # nil only if +ipaddr?+ is true.
  25. attr_reader :tld
  26. # Returns an IPAddr object if this is an IP address.
  27. attr_reader :ipaddr
  28. # Returns true if this is an IP address, such as "192.168.0.1" and
  29. # "[::1]".
  30. def ipaddr?
  31. @ipaddr ? true : false
  32. end
  33. # Returns a host name representation suitable for use in the host
  34. # name part of a URI. A host name, an IPv4 address, or a IPv6
  35. # address enclosed in square brackets.
  36. attr_reader :uri_host
  37. # Returns true if this domain name has a canonical TLD.
  38. def canonical_tld?
  39. @canonical_tld_p
  40. end
  41. # Returns true if this domain name has a canonical registered
  42. # domain.
  43. def canonical?
  44. @canonical_tld_p && (@domain ? true : false)
  45. end
  46. DOT = '.'.freeze # :nodoc:
  47. # Parses _hostname_ into a DomainName object. An IP address is also
  48. # accepted. An IPv6 address may be enclosed in square brackets.
  49. def initialize(hostname)
  50. hostname.is_a?(String) or
  51. (hostname.respond_to?(:to_str) && (hostname = hostname.to_str).is_a?(String)) or
  52. raise TypeError, "#{hostname.class} is not a String"
  53. if hostname.start_with?(DOT)
  54. raise ArgumentError, "domain name must not start with a dot: #{hostname}"
  55. end
  56. case hostname
  57. when /\A([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\z/
  58. @ipaddr = IPAddr.new($1)
  59. @uri_host = @hostname = @ipaddr.to_s
  60. @domain = @tld = nil
  61. return
  62. when /\A([0-9A-Fa-f:]*:[0-9A-Fa-f:]*:[0-9A-Fa-f:]*)\z/,
  63. /\A\[([0-9A-Fa-f:]*:[0-9A-Fa-f:]*:[0-9A-Fa-f:]*)\]\z/
  64. @ipaddr = IPAddr.new($1)
  65. @hostname = @ipaddr.to_s
  66. @uri_host = "[#{@hostname}]"
  67. @domain = @tld = nil
  68. return
  69. end
  70. @ipaddr = nil
  71. @hostname = DomainName.normalize(hostname)
  72. @uri_host = @hostname
  73. if last_dot = @hostname.rindex(DOT)
  74. @tld = @hostname[(last_dot + 1)..-1]
  75. else
  76. @tld = @hostname
  77. end
  78. etld_data = DomainName.etld_data
  79. if @canonical_tld_p = etld_data.key?(@tld)
  80. subdomain = domain = nil
  81. parent = @hostname
  82. loop {
  83. case etld_data[parent]
  84. when 0
  85. @domain = domain if domain
  86. return
  87. when -1
  88. @domain = subdomain if subdomain
  89. return
  90. when 1
  91. @domain = parent
  92. return
  93. end
  94. subdomain = domain
  95. domain = parent
  96. pos = @hostname.index(DOT, -domain.length) or break
  97. parent = @hostname[(pos + 1)..-1]
  98. }
  99. else
  100. # unknown/local TLD
  101. if last_dot
  102. # fallback - accept cookies down to second level
  103. # cf. http://www.dkim-reputation.org/regdom-libs/
  104. if penultimate_dot = @hostname.rindex(DOT, last_dot - 1)
  105. @domain = @hostname[(penultimate_dot + 1)..-1]
  106. else
  107. @domain = @hostname
  108. end
  109. else
  110. # no domain part - must be a local hostname
  111. @domain = @tld
  112. end
  113. end
  114. end
  115. # Checks if the server represented by _domain_ is qualified to send
  116. # and receive cookies for _domain_.
  117. def cookie_domain?(domain)
  118. domain = DomainName.new(domain) unless DomainName === domain
  119. if ipaddr?
  120. # RFC 6265 #5.1.3
  121. # Do not perform subdomain matching against IP addresses.
  122. @hostname == domain.hostname
  123. else
  124. # RFC 6265 #4.1.1
  125. # Domain-value must be a subdomain.
  126. @domain && self <= domain && domain <= @domain ? true : false
  127. end
  128. end
  129. def ==(other)
  130. other = DomainName.new(other) unless DomainName === other
  131. other.hostname == @hostname
  132. end
  133. def <=>(other)
  134. other = DomainName.new(other) unless DomainName === other
  135. othername = other.hostname
  136. if othername == @hostname
  137. 0
  138. elsif @hostname.end_with?(othername) && @hostname[-othername.size - 1, 1] == DOT
  139. # The other is higher
  140. -1
  141. elsif othername.end_with?(@hostname) && othername[-@hostname.size - 1, 1] == DOT
  142. # The other is lower
  143. 1
  144. else
  145. nil
  146. end
  147. end
  148. def <(other)
  149. case self <=> other
  150. when -1
  151. true
  152. when nil
  153. nil
  154. else
  155. false
  156. end
  157. end
  158. def >(other)
  159. case self <=> other
  160. when 1
  161. true
  162. when nil
  163. nil
  164. else
  165. false
  166. end
  167. end
  168. def <=(other)
  169. case self <=> other
  170. when -1, 0
  171. true
  172. when nil
  173. nil
  174. else
  175. false
  176. end
  177. end
  178. def >=(other)
  179. case self <=> other
  180. when 1, 0
  181. true
  182. when nil
  183. nil
  184. else
  185. false
  186. end
  187. end
  188. def to_s
  189. @hostname
  190. end
  191. alias to_str to_s
  192. def inspect
  193. str = '#<%s:%s' % [self.class.name, @hostname]
  194. if @ipaddr
  195. str << ' (ipaddr)'
  196. else
  197. str << ' domain=' << @domain if @domain
  198. str << ' tld=' << @tld if @tld
  199. end
  200. str << '>'
  201. end
  202. class << self
  203. # Normalizes a _domain_ using the Punycode algorithm as necessary.
  204. # The result will be a downcased, ASCII-only string.
  205. def normalize(domain)
  206. DomainName::Punycode.encode_hostname(domain.chomp(DOT).to_nfc).downcase
  207. end
  208. end
  209. end
  210. # Short hand for DomainName.new().
  211. def DomainName(hostname)
  212. DomainName.new(hostname)
  213. end