class DomainNameValidator

The purpose of this class is to provide a simple capability for validating domain names represented in ASCII, a feature that seems to be missing or obscured in other more wide-ranging domain-related gems.

Constants

ERRS
MAX_DOMAIN_LENGTH
MAX_LABEL_LENGTH
MAX_LEVELS
MAX_TLD_LENGTH
MIN_LEVELS
MIN_TLD_LENGTH
VERSION

Public Instance Methods

validate(dn, errs = []) click to toggle source

Validates the proper formatting of a normalized domain name, i.e. - a domain that is represented in ASCII. Thus, international domain names are supported and validated, if they have undergone the required IDN conversion to ASCII. The validation rules are:

  1. The maximum length of a domain name is 253 characters.

  2. A domain name is divided into “labels” separated by periods. The maximum number of labels (including the top-level domain as a label) is 127.

  3. The maximum length of any label within a domain name is 63 characters.

  4. No label, including top-level domains, can begin or end with a dash.

  5. Top-level names cannot be all numeric.

  6. A domain name cannot begin with a period.

# File lib/domain_name_validator/validator.rb, line 52
def validate(dn, errs = [])
  if dn.nil?
    errs << ERRS[:zero_size]
  else
    dn = dn.strip
    errs << ERRS[:zero_size] if dn.size == 0
  end

  if errs.size == 0
    errs << ERRS[:max_domain_size] if dn.size > MAX_DOMAIN_LENGTH
    parts = dn.downcase.split('.')
    errs << ERRS[:max_level_size] if parts.size > MAX_LEVELS
    errs << ERRS[:min_level_size] if parts.size < MIN_LEVELS
    parts.each do |p|
      errs << ERRS[:max_label_size] if p.size > MAX_LABEL_LENGTH
      errs << ERRS[:label_dash_begin] if p[0] == '-'
      errs << ERRS[:label_dash_end] if p[-1] == '-'
      errs << ERRS[:illegal_chars] unless p.match(/^[a-z0-9\-\_]+$/)
    end
    errs << ERRS[:top_numerical] if parts.last.match(/^[0-9]+$/)
    if parts.last.size < MIN_TLD_LENGTH || parts.last.size > MAX_TLD_LENGTH
      unless parts.last == 'arpa' ||
             parts.last == 'aero' ||
             parts.last == 'asia' ||
             parts.last == 'coop' ||
             parts.last == 'info' ||
             parts.last == 'jobs' ||
             parts.last == 'mobi' ||
             parts.last == 'museum' ||
             parts.last == 'name' ||
             parts.last == 'post' ||
             parts.last == 'travel' ||
             parts.last.match(/^xn--/)
        errs << ERRS[:bogus_tld]   
      end
    end
    errs << ERRS[:illegal_start] if parts.first[0] == '.'
  end

  errs.size == 0   # TRUE if valid, FALSE otherwise
end