Module: PublicSuffix

Defined in:
lib/public_suffix.rb,
lib/public_suffix/list.rb,
lib/public_suffix/rule.rb,
lib/public_suffix/domain.rb,
lib/public_suffix/errors.rb,
lib/public_suffix/version.rb

Overview

Public Suffix

Domain name parser based on the Public Suffix List.

Copyright © 2009-2019 Simone Carletti <[email protected]>

Defined Under Namespace

Modules: Rule Classes: Domain, DomainInvalid, DomainNotAllowed, Error, List

Constant Summary collapse

DOT =
"."
BANG =
"!"
STAR =
"*"
VERSION =

The current library version.

"4.0.2"

Class Method Summary collapse

Class Method Details

.decompose(name, rule) ⇒ Object

private



151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/public_suffix.rb', line 151

def self.decompose(name, rule)
  left, right = rule.decompose(name)

  parts = left.split(DOT)
  # If we have 0 parts left, there is just a tld and no domain or subdomain
  # If we have 1 part  left, there is just a tld, domain and not subdomain
  # If we have 2 parts left, the last part is the domain, the other parts (combined) are the subdomain
  tld = right
  sld = parts.empty? ? nil : parts.pop
  trd = parts.empty? ? nil : parts.join(DOT)

  Domain.new(tld, sld, trd)
end

.domain(name, **options) ⇒ String

Attempt to parse the name and returns the domain, if valid.

This method doesn’t raise. Instead, it returns nil if the domain is not valid for whatever reason.

Parameters:

  • name (String, #to_s)

    The domain name or fully qualified domain name to parse.

  • list (PublicSuffix::List)

    The rule list to search, defaults to the default List

  • ignore_private (Boolean)

Returns:

  • (String)


142
143
144
145
146
# File 'lib/public_suffix.rb', line 142

def self.domain(name, **options)
  parse(name, **options).domain
rescue PublicSuffix::Error
  nil
end

.normalize(name) ⇒ Object

Pretend we know how to deal with user input.



166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/public_suffix.rb', line 166

def self.normalize(name)
  name = name.to_s.dup
  name.strip!
  name.chomp!(DOT)
  name.downcase!

  return DomainInvalid.new("Name is blank") if name.empty?
  return DomainInvalid.new("Name starts with a dot") if name.start_with?(DOT)
  return DomainInvalid.new("%s is not expected to contain a scheme" % name) if name.include?("://")

  name
end

.parse(name, list: List.default, default_rule: list.default_rule, ignore_private: false) ⇒ PublicSuffix::Domain

Parses name and returns the Domain instance.

Examples:

Parse a valid domain

PublicSuffix.parse("google.com")
# => #<PublicSuffix::Domain:0x007fec2e51e588 @sld="google", @tld="com", @trd=nil>

Parse a valid subdomain

PublicSuffix.parse("www.google.com")
# => #<PublicSuffix::Domain:0x007fec276d4cf8 @sld="google", @tld="com", @trd="www">

Parse a fully qualified domain

PublicSuffix.parse("google.com.")
# => #<PublicSuffix::Domain:0x007fec257caf38 @sld="google", @tld="com", @trd=nil>

Parse a fully qualified domain (subdomain)

PublicSuffix.parse("www.google.com.")
# => #<PublicSuffix::Domain:0x007fec27b6bca8 @sld="google", @tld="com", @trd="www">

Parse an invalid (unlisted) domain

PublicSuffix.parse("x.yz")
# => #<PublicSuffix::Domain:0x007fec2f49bec0 @sld="x", @tld="yz", @trd=nil>

Parse an invalid (unlisted) domain with strict checking (without applying the default * rule)

PublicSuffix.parse("x.yz", default_rule: nil)
# => PublicSuffix::DomainInvalid: `x.yz` is not a valid domain

Parse an URL (not supported, only domains)

PublicSuffix.parse("http://www.google.com")
# => PublicSuffix::DomainInvalid: http://www.google.com is not expected to contain a scheme

Parameters:

  • name (String, #to_s)

    The domain name or fully qualified domain name to parse.

  • list (PublicSuffix::List) (defaults to: List.default)

    The rule list to search, defaults to the default List

  • ignore_private (Boolean) (defaults to: false)

Returns:

Raises:



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/public_suffix.rb', line 69

def self.parse(name, list: List.default, default_rule: list.default_rule, ignore_private: false)
  what = normalize(name)
  raise what if what.is_a?(DomainInvalid)

  rule = list.find(what, default: default_rule, ignore_private: ignore_private)

  # rubocop:disable Style/IfUnlessModifier
  if rule.nil?
    raise DomainInvalid, "`#{what}` is not a valid domain"
  end
  if rule.decompose(what).last.nil?
    raise DomainNotAllowed, "`#{what}` is not allowed according to Registry policy"
  end

  # rubocop:enable Style/IfUnlessModifier

  decompose(what, rule)
end

.valid?(name, list: List.default, default_rule: list.default_rule, ignore_private: false) ⇒ Boolean

Checks whether domain is assigned and allowed, without actually parsing it.

This method doesn’t care whether domain is a domain or subdomain. The validation is performed using the default List.

Examples:

Validate a valid domain

PublicSuffix.valid?("example.com")
# => true

Validate a valid subdomain

PublicSuffix.valid?("www.example.com")
# => true

Validate a not-listed domain

PublicSuffix.valid?("example.tldnotlisted")
# => true

Validate a not-listed domain with strict checking (without applying the default * rule)

PublicSuffix.valid?("example.tldnotlisted")
# => true
PublicSuffix.valid?("example.tldnotlisted", default_rule: nil)
# => false

Validate a fully qualified domain

PublicSuffix.valid?("google.com.")
# => true
PublicSuffix.valid?("www.google.com.")
# => true

Check an URL (which is not a valid domain)

PublicSuffix.valid?("http://www.example.com")
# => false

Parameters:

  • name (String, #to_s)

    The domain name or fully qualified domain name to validate.

  • ignore_private (Boolean) (defaults to: false)

Returns:

  • (Boolean)


125
126
127
128
129
130
131
132
# File 'lib/public_suffix.rb', line 125

def self.valid?(name, list: List.default, default_rule: list.default_rule, ignore_private: false)
  what = normalize(name)
  return false if what.is_a?(DomainInvalid)

  rule = list.find(what, default: default_rule, ignore_private: ignore_private)

  !rule.nil? && !rule.decompose(what).last.nil?
end