class PAK::ValidatesHostname::HostnameValidator

Public Class Methods

new(options) click to toggle source
Calls superclass method
# File lib/validates_hostname.rb, line 166
def initialize(options)
  opts = {
    :allow_underscore        => false,
    :require_valid_tld       => false,
    :valid_tlds              => ALLOWED_TLDS,
    :allow_numeric_hostname  => false,
    :allow_wildcard_hostname => false,
    :allow_root_label        => false
  }.merge(options)
  super(opts)
end

Public Instance Methods

add_error(record, attr_name, message, *interpolators) click to toggle source
# File lib/validates_hostname.rb, line 236
def add_error(record, attr_name, message, *interpolators)
  args = {
    :default => [DEFAULT_ERROR_MSG[message], options[:message]],
    :scope   => [:errors, :messages]
  }.merge(interpolators.last.is_a?(Hash) ? interpolators.pop : {})
  record.errors.add(attr_name, I18n.t( message, args ))
end
validate_each(record, attribute, value) click to toggle source
# File lib/validates_hostname.rb, line 178
def validate_each(record, attribute, value)
  value ||= ''

  # maximum hostname length: 255 characters
  add_error(record, attribute, :invalid_hostname_length) unless value.length.between?(1, 255)

  # split each hostname into labels and do various checks
  if value.is_a?(String)
    labels = value.split '.'
    labels.each_with_index do |label, index|
      # CHECK 1: hostname label cannot be longer than 63 characters
      add_error(record, attribute, :invalid_label_length) unless label.length.between?(1, 63)

      # CHECK 2: hostname label cannot begin or end with hyphen
      add_error(record, attribute, :label_begins_or_ends_with_hyphen) if label =~ /^[-]/i or label =~ /[-]$/

      # Take care of wildcard first label
      next if options[:allow_wildcard_hostname] and label == '*' and index == 0

      # CHECK 3: hostname can only contain characters:
      #          a-z, 0-9, hyphen, optional underscore, optional asterisk
      valid_chars = 'a-z0-9\-'
      valid_chars << '_' if options[:allow_underscore] == true
      add_error(record, attribute, :label_contains_invalid_characters, :valid_chars => valid_chars) unless label =~ /^[#{valid_chars}]+$/i
    end

    # CHECK 4: the unqualified hostname portion cannot consist of
    #          numeric values only
    if options[:allow_numeric_hostname] == false and labels.length > 0
      is_numeric_only = labels[0] =~ /\A\d+\z/
      add_error(record, attribute, :hostname_label_is_numeric) if is_numeric_only
    end

    # CHECK 5: in order to be fully qualified, the full hostname's
    #          TLD must be valid
    if options[:require_valid_tld] == true
      my_tld = value == '.' ? value : labels.last
      my_tld ||= ''
      has_tld = options[:valid_tlds].select {
        |tld| tld =~ /^#{Regexp.escape(my_tld)}$/i
      }.empty? ? false : true
      add_error(record, attribute, :hostname_is_not_fqdn) unless has_tld
    end

    # CHECK 6: hostname may not contain consecutive dots
    if value =~ /\.\./
      add_error(record, attribute, :hostname_contains_consecutive_dots)
    end

    # CHECK 7: do not allow trailing dot unless option is set
    if options[:allow_root_label] == false
      if value =~ /\.$/
        add_error(record, attribute, :hostname_ends_with_dot)
      end
    end
  end
end