Class: PublicSuffixService::RuleList

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/public_suffix_service/rule_list.rb

Overview

Rule List

A PublicSuffixService::RuleList is a collection of one or more PublicSuffixService::Rule.

Given a RuleList, you can add or remove PublicSuffixService::Rule, iterate all items in the list or search for the first rule which matches a specific domain name.

# Create a new list
list =  PublicSuffixService::RuleList.new

# Push two rules to the list
list << PublicSuffixService::Rule.factory("it")
list << PublicSuffixService::Rule.factory("com")

# Get the size of the list
list.size
# => 2

# Search for the rule matching given domain
list.find("example.com")
# => #<PublicSuffixService::Rule::Normal>
list.find("example.org")
# => nil

You can create as many PublicSuffixService::RuleList you want. The PublicSuffixService::RuleList.default rule list is used by DomainName to tokenize and validate a domain.

PublicSuffixService::RuleList implements Enumerable module.

Constant Summary collapse

@@default =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ RuleList

Initializes an empty PublicSuffixService::RuleList. If block is given, yields on self.

Yields:

  • (_self)

Yield Parameters:



67
68
69
70
71
72
# File 'lib/public_suffix_service/rule_list.rb', line 67

def initialize(&block) # :yields: self
  @list    = []
  @indexes = {}
  yield(self) if block_given?
  create_index!
end

Instance Attribute Details

#indexesObject (readonly)

Gets the naive index, a hash that with the keys being the first label of every rule pointing to an array of integers (indexes of the rules in @list)



62
63
64
# File 'lib/public_suffix_service/rule_list.rb', line 62

def indexes
  @indexes
end

#listObject (readonly)

Gets the list of rules.

Returns the Array of rule instances. Each rule is an instance of the proper corresponding of PublicSuffixService::Rule::Base.



58
59
60
# File 'lib/public_suffix_service/rule_list.rb', line 58

def list
  @list
end

Class Method Details

.clearObject

Sets the default PublicSuffixService::RuleList to nil.

Returns self.



227
228
229
230
# File 'lib/public_suffix_service/rule_list.rb', line 227

def clear
  self.default = nil
  self
end

.defaultObject

Gets the default PublicSuffixService::RuleList. Initializes a new PublicSuffixService::RuleList parsing the content of PublicSuffixService::RuleList.default_definition, if required.

Returns a PublicSuffixService::RuleList.



211
212
213
# File 'lib/public_suffix_service/rule_list.rb', line 211

def default
  @@default ||= parse(default_definition)
end

.default=(value) ⇒ Object

Sets the default PublicSuffixService::RuleList to value.

value - The new PublicSuffixService::RuleList.

Returns the PublicSuffixService::RuleList.



220
221
222
# File 'lib/public_suffix_service/rule_list.rb', line 220

def default=(value)
  @@default = value
end

.default_definitionObject

Gets the default definition list. Can be any IOStream including a File or a simple String. The object must respond to #each_line.

Returns a File.



246
247
248
# File 'lib/public_suffix_service/rule_list.rb', line 246

def default_definition
  File.new(File.join(File.dirname(__FILE__), "definitions.dat"))
end

.parse(input) ⇒ Object

Parse given input treating the content as Public Suffic List. See publicsuffix.org/format/ for more details about input format.

Returns an Array of rule instances. Each rule is an instance of the corresponding subclass of PublicSuffixService::Rule::Base.



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/public_suffix_service/rule_list.rb', line 257

def parse(input)
  new do |list|
    input.each_line do |line|
      line.strip!

      # strip blank lines
      if line.empty?
        next
      # strip comments
      elsif line =~ %r{^//}
        next
      # append rule
      else
        list << Rule.factory(line)
      end
    end
  end
end

.reloadObject

Resets the default PublicSuffixService::RuleList and reinitialize it parsing the content of PublicSuffixService::RuleList.default_definition.

Returns a PublicSuffixService::RuleList.



236
237
238
# File 'lib/public_suffix_service/rule_list.rb', line 236

def reload
  self.clear.default
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Checks whether two lists are equal. RuleList one is equal to two, if two is an instance of PublicSuffixService::RuleList and each PublicSuffixService::Rule::Base in list one is available in list two, in the same order.

other - The PublicSuffixService::RuleList to compare.

Returns true if self is equal to other.



102
103
104
105
106
# File 'lib/public_suffix_service/rule_list.rb', line 102

def ==(other)
  return false unless other.is_a?(RuleList)
  self.equal?(other) ||
  self.list == other.list
end

#add(rule) ⇒ Object Also known as: <<

Adds the given object to the list.

rule - The rule to add to the list.

Expected to be a subclass of PublicSuffixService::Rule::Base.

Returns self.



129
130
131
132
# File 'lib/public_suffix_service/rule_list.rb', line 129

def add(rule)
  @list << rule
  self
end

#clearObject

Removes all elements.

Returns self.



153
154
155
156
# File 'lib/public_suffix_service/rule_list.rb', line 153

def clear
  @list.clear
  self
end

#create_index!Object

Creates a naive index for @list. Just a hash that will tell us where the elements of @list are relative to its first Rule#labels element.

For instance if @list and @list are the only elements of the list where Rule#labels.first is ‘us’ @indexes #=> [5,4], that way in select we can avoid mapping every single rule against the candidate domain.

Returns nothing.



83
84
85
86
87
88
89
90
91
# File 'lib/public_suffix_service/rule_list.rb', line 83

def create_index!
  @list.map{|l| l.labels.first }.each_with_index do |elm, inx|
    if !@indexes.has_key?(elm)
      @indexes[elm] = [inx]
    else
      @indexes[elm] << inx
    end
  end
end

#each(*args, &block) ⇒ Object

Iterates each rule in the list.

Returns nothing.



112
113
114
# File 'lib/public_suffix_service/rule_list.rb', line 112

def each(*args, &block)
  @list.each(*args, &block)
end

#empty?Boolean

Checks whether the list is empty.

Returns true if the list contains no elements.

Returns:

  • (Boolean)


146
147
148
# File 'lib/public_suffix_service/rule_list.rb', line 146

def empty?
  @list.empty?
end

#find(domain) ⇒ Object

Returns the most appropriate rule for domain.

From the Public Suffix List documentation:

  • If a hostname matches more than one rule in the file, the longest matching rule (the one with the most levels) will be used.

  • An exclamation mark (!) at the start of a rule marks an exception to a previous wildcard rule. An exception rule takes priority over any other matching rule.

Algorithm description

  • Match domain against all rules and take note of the matching ones.

  • If no rules match, the prevailing rule is “*”.

  • If more than one rule matches, the prevailing rule is the one which is an exception rule.

  • If there is no matching exception rule, the prevailing rule is the one with the most labels.

  • If the prevailing rule is a exception rule, modify it by removing the leftmost label.

  • The public suffix is the set of labels from the domain which directly match the labels of the prevailing rule (joined by dots).

  • The registered domain is the public suffix plus one additional label.

Note: This might not be the most efficient algorithm.

Returns a PublicSuffixService::Rule::Base instance or nil.



182
183
184
185
186
# File 'lib/public_suffix_service/rule_list.rb', line 182

def find(domain)
  rules = select(domain)
  rules.select { |r|   r.type == :exception }.first ||
  rules.inject { |t,r| t.length > r.length ? t : r }
end

#select(domain) ⇒ Object

Selects all the rules matching given domain.

Will use @indexes to try only the rules that share the same first label, that will speed up things when using RuleList.find(‘foo’) a lot.

Returns an Array of rule instances. Each rule is an instance of the corresponding subclass of PublicSuffixService::Rule::Base.



196
197
198
199
# File 'lib/public_suffix_service/rule_list.rb', line 196

def select(domain)
  indices = (@indexes[ Domain.domain_to_labels(domain).first ] || [])
  @list.values_at(*indices).select { |rule| rule.match?(domain) }
end

#sizeObject Also known as: length

Gets the number of elements in the list.

Returns an Integer.



138
139
140
# File 'lib/public_suffix_service/rule_list.rb', line 138

def size
  @list.size
end

#to_aObject

Gets the list as Array.

Return an Array.



119
120
121
# File 'lib/public_suffix_service/rule_list.rb', line 119

def to_a
  @list
end