Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor,
# operating system or environment, you probably want to add a global ignore instead:
# git config --global core.excludesfile '~/.gitignore_global'

data/*.zone
data/*.txt

spec/examples.txt

coverage
3 changes: 3 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--color
--order random
--format progress
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language: ruby
script: bundle exec rake zones:update && bundle exec rspec spec
40 changes: 30 additions & 10 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,43 @@ PATH
remote: .
specs:
domain_name_validator (0.5)
zonefile

GEM
remote: http://rubygems.org/
specs:
diff-lcs (1.2.4)
rspec (2.13.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
rspec-core (2.13.1)
rspec-expectations (2.13.0)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.13.1)
diff-lcs (1.2.5)
docile (1.1.5)
json (1.8.3)
rake (10.4.2)
rspec (3.3.0)
rspec-core (~> 3.3.0)
rspec-expectations (~> 3.3.0)
rspec-mocks (~> 3.3.0)
rspec-core (3.3.2)
rspec-support (~> 3.3.0)
rspec-expectations (3.3.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.3.0)
rspec-mocks (3.3.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.3.0)
rspec-support (3.3.0)
simplecov (0.10.0)
docile (~> 1.1.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
zonefile (1.04)

PLATFORMS
x86-mingw32
ruby

DEPENDENCIES
domain_name_validator!
rake
rspec
simplecov

BUNDLED WITH
1.10.6
18 changes: 14 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
require 'bundler'
Bundler::GemHelper.install_tasks
# or....
# require 'bundler/gem_tasks'
$:.unshift(File.expand_path("../lib", __FILE__))
require 'domain_name_validator/update_zones'

task default: :prepare

task :prepare do
Rake::Task['zones:update'].invoke
end

namespace :zones do
task :update do
DomainNameValidator.update_zones
end
end
9 changes: 9 additions & 0 deletions bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

# Bundle
bundle install

# Update data
rake zones:update
Empty file added data/.gitkeep
Empty file.
39 changes: 23 additions & 16 deletions domain_name_validator.gemspec
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "domain_name_validator/version"
$:.push File.expand_path('../lib', __FILE__)
require 'domain_name_validator/version'

Gem::Specification.new do |gem|
gem.name = "domain_name_validator"
gem.version = DomainNameValidator::VERSION
gem.platform = Gem::Platform::RUBY
gem.authors = ["David Keener"]
gem.email = ["[email protected]"]
gem.homepage = "http://www.keenertech.com"
gem.summary = %q{Domain Name Validator}
gem.description = %q{Checks the validity of domain names.}
gem.license = 'MIT'

gem.add_development_dependency "rspec"
gem.name = 'domain_name_validator'
gem.version = DomainNameValidator::VERSION
gem.platform = Gem::Platform::RUBY
gem.authors = ['David Keener']
gem.email = ['[email protected]']
gem.homepage = 'http://www.keenertech.com'
gem.summary = %q{Domain Name Validator}
gem.description = %q{Checks the validity of domain names.}
gem.license = 'MIT'
gem.bindir = 'exe'
gem.require_paths = ['lib']

gem.rubyforge_project = "domain_name_validator"
gem.extensions = ['Rakefile']

gem.add_dependency 'zonefile'
gem.add_development_dependency 'rspec'
gem.add_development_dependency 'rake'
gem.add_development_dependency 'simplecov'

gem.rubyforge_project = 'domain_name_validator'

gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
gem.executables = gem.files.grep(%r{^exe/}) { |f| File.basename(f) }

#gem.rdoc_options = ["--charset=UTF-8"]
#gem.extra_rdoc_files = %w[README.rdoc LICENSE Changelog.rdoc]

gem.require_paths = ["lib"]
gem.require_paths = ['lib']
end
5 changes: 5 additions & 0 deletions exe/update-zones
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env ruby
$:.unshift(File.expand_path("../../lib", __FILE__))
require 'domain_name_validator/update_zones'

DomainNameValidator.update_zones
1 change: 1 addition & 0 deletions lib/domain_name_validator.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'domain_name_validator/config'
require 'domain_name_validator/validator'
require 'domain_name_validator/version'

Expand Down
31 changes: 31 additions & 0 deletions lib/domain_name_validator/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class DomainNameValidator
ROOT_ZONE_URL = 'http://data.iana.org/TLD/tlds-alpha-by-domain.txt'
TLD_FILE = File.expand_path('../../../data/tlds-alpha-by-domain.txt', __FILE__)
MAX_DOMAIN_LENGTH = 253
MAX_LABEL_LENGTH = 63
MAX_LEVELS = 127
MIN_LEVELS = 2

ERRS = {
:bogus_tld =>
'Malformed TLD: Could not possibly match any valid TLD',
:illegal_chars =>
'Domain label contains an illegal character',
:illegal_start =>
'No domain name may start with a period',
:label_dash_begin =>
'No domain label may begin with a dash',
:label_dash_end =>
'No domain label may end with a dash',
:max_domain_size =>
'Maximum domain length of 253 exceeded',
:max_label_size =>
'Maximum domain label length of 63 exceeded',
:max_level_size =>
'Maximum domain level limit of 127 exceeded',
:min_level_size =>
'Minimum domain level limit of 2 not achieved',
:zero_size =>
'Zero-length domain name'
}
end
44 changes: 44 additions & 0 deletions lib/domain_name_validator/update_zones.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'domain_name_validator/config'
require 'zonefile'
require 'net/http'
require 'uri'

class DomainNameValidator

def self.update_zones
uri = URI(ROOT_ZONE_URL)
dnv = DomainNameValidator.new
dnv.download_zone_file(uri)
end

def download_zone_file(uri)
puts "# Downloading zones from #{ROOT_ZONE_URL}"
amount_downloaded = 0
current_width = 0
print ' #> 000%'
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Get.new uri.to_s
http.request request do |response|
file_size = response['content-length'].to_i
open TLD_FILE, 'w' do |io|
response.read_body do |chunk|
io.write chunk
amount_downloaded += chunk.size
diff = status_bar(file_size, amount_downloaded, current_width)
current_width += diff
end
end
end
end
puts ' ok'
end

def status_bar(file_size, amount_downloaded, current_width)
percentage = (amount_downloaded.to_f / file_size * 100)
diff = (percentage.to_i/2-current_width)
if (current_width+percentage.to_i/2 > current_width+1 )
print "\b" * 6 + '=' * diff.to_i + "> #{percentage.to_i.to_s.rjust(3, "0")}%"
end
return diff
end
end
53 changes: 2 additions & 51 deletions lib/domain_name_validator/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,6 @@
# obscured in other more wide-ranging domain-related gems.

class DomainNameValidator

MAX_DOMAIN_LENGTH = 253
MAX_LABEL_LENGTH = 63
MAX_LEVELS = 127
MAX_TLD_LENGTH = 3 # Except for "aero", "arpa", "info" and "museum"
MIN_LEVELS = 2
MIN_TLD_LENGTH = 2

ERRS = {
:bogus_tld =>
'Malformed TLD: Could not possibly match any valid TLD',
:illegal_chars =>
'Domain label contains an illegal character',
:illegal_start =>
'No domain name may start with a period',
:label_dash_begin =>
'No domain label may begin with a dash',
:label_dash_end =>
'No domain label may end with a dash',
:max_domain_size =>
'Maximum domain length of 253 exceeded',
:max_label_size =>
'Maximum domain label length of 63 exceeded',
:max_level_size =>
'Maximum domain level limit of 127 exceeded',
:min_level_size =>
'Minimum domain level limit of 2 not achieved',
:top_numerical =>
'The top-level domain (TLD) cannot be numerical',
:zero_size =>
'Zero-length domain name'
}

# 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
Expand Down Expand Up @@ -69,27 +36,11 @@ def validate(dn, errs = [])
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[:bogus_tld] unless File.readlines(TLD_FILE).map{
|line| line.chomp.downcase }.include?(parts.last)
errs << ERRS[:illegal_start] if parts.first[0] == '.'
end

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

end
Loading