rdap 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a812f4f58d5435ffd4a7b6d85d0373b1d7eb7914fb87854f48f2142009ff0f3f
4
+ data.tar.gz: f039922723968ba123c0697e5254e07220bce7a85015f2783bcaca17f2c87e37
5
+ SHA512:
6
+ metadata.gz: d3fdb2df158c5a13d0a479fba0760e766c12f707cb82bb4214f7e9e95629d84700ab788d7b2591233367862b3f79e2f8eb34fa44a13fb8bfecdecde83f6d164b
7
+ data.tar.gz: 3a2219bfb23a0fa4e3a3204db935024b6a2ec2f733f57e5541fec37b3e917c41cd54231f418d91f5bf30e12bbccd4ac2f5b68a5d8ac001ba12d07e03e3ae3c32
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.5.7
6
+ - 2.6.5
7
+ - 2.7.5
8
+ - 3.0.3
9
+ before_install: gem install bundler -v 2.1.4
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rdap.gemspec
4
+ gemspec
5
+
6
+ gem "rake", ">= 12.0"
7
+ gem "rspec", "~> 3.0"
8
+ gem "vcr", "~> 6.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rdap (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.4.4)
10
+ rake (13.0.6)
11
+ rspec (3.10.0)
12
+ rspec-core (~> 3.10.0)
13
+ rspec-expectations (~> 3.10.0)
14
+ rspec-mocks (~> 3.10.0)
15
+ rspec-core (3.10.1)
16
+ rspec-support (~> 3.10.0)
17
+ rspec-expectations (3.10.1)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.10.0)
20
+ rspec-mocks (3.10.2)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.10.0)
23
+ rspec-support (3.10.3)
24
+ vcr (6.0.0)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ rake (>= 12.0)
31
+ rdap!
32
+ rspec (~> 3.0)
33
+ vcr (~> 6.0)
34
+
35
+ BUNDLED WITH
36
+ 2.1.4
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # RDAP
2
+
3
+ A minimal Ruby client to query RDAP APIs though a bootstrap server.
4
+ No dependencies, no caching or bootstrap file (the query is routed through a bootstrap server first).
5
+
6
+ [RDAP](https://en.wikipedia.org/wiki/Registration_Data_Access_Protocol) is a new protocol destined to replace WHOIS to query informations about domains, IPs, ASNs, etc.
7
+ Not all TLDs support RDAP at the moment, but the deployment is going well: https://deployment.rdap.org
8
+
9
+ This library is optimal for low volume queries (the [bootstrap server we used here](https://about.rdap.org/) enforces [some throttling](https://about.rdap.org/#rate-limits)).
10
+ If you need to perform a lot of queries, you should either:
11
+ - avoid bootstrap servers and use a caching client like [nicinfo](https://github.com/arineng/nicinfo)
12
+ - or run [your own bootstrap server](https://github.com/arineng/rdap_bootstrap_server).
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'rdap'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle install
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install rdap
29
+
30
+ ## Usage
31
+
32
+ You can use `bin/console` from this repository for an interactive prompt.
33
+
34
+ ```ruby
35
+ RDAP.domain("google.com")
36
+ # => {"objectClassName"=>"domain",
37
+ # "handle"=>"2138514_DOMAIN_COM-VRSN",
38
+ # "ldhName"=>"GOOGLE.COM",
39
+ # "links"=>[...],
40
+ # "status"=>[...],
41
+ # "entities"=>[...],
42
+ # "events"=>
43
+ # [{"eventAction"=>"registration", "eventDate"=>"1997-09-15T04:00:00Z"},
44
+ # {"eventAction"=>"expiration", "eventDate"=>"2028-09-14T04:00:00Z"},
45
+ # {"eventAction"=>"last update of RDAP database", "eventDate"=>"2021-12-17T11:35:32Z"}],
46
+ # "secureDNS"=>{"delegationSigned"=>false},
47
+ # "nameservers"=>
48
+ # [{"objectClassName"=>"nameserver", "ldhName"=>"NS1.GOOGLE.COM"},
49
+ # {"objectClassName"=>"nameserver", "ldhName"=>"NS2.GOOGLE.COM"},
50
+ # {"objectClassName"=>"nameserver", "ldhName"=>"NS3.GOOGLE.COM"},
51
+ # {"objectClassName"=>"nameserver", "ldhName"=>"NS4.GOOGLE.COM"}],
52
+ # "rdapConformance"=>
53
+ # ["rdap_level_0", "icann_rdap_technical_implementation_guide_0", "icann_rdap_response_profile_0"],
54
+ # "notices"=>[...]}
55
+ RDAP.ip("8.8.8.8") # IPv4
56
+ RDAP.ip("2620:119:35::35") # or IPv6
57
+ RDAP.as("16276") # AS Number ("autnum" in RDAP phraseology)
58
+
59
+ # there is also a lower level method accepting a type (:domain, :ip, :autnum) if needed
60
+ RDAP.query("16276", type: :autnum)
61
+
62
+ # Options
63
+ RDAP.domain("google.com", server: "https://rdap-bootstrap.arin.net/bootstrap") # Specify an alternative bootstrap server
64
+ RDAP.domain("google.com", server: "https://rdap.verisign.com/com/v1") # Or directly the target RDAP server if you know it
65
+ RDAP.domain("google.com", timeout: 20) # Customize open and read timeouts (default = 5 sec each)
66
+
67
+ # Error handling
68
+ RDAP.domain("test.fr") # TLD not supported yet
69
+ # => RDAP::NotFound ([404] domain test.fr not found in IANA boostrap file)
70
+ RDAP.domain("jsiqpmcurt.design") # Domain not found
71
+ # => RDAP::NotFound ([404] Object not found)
72
+ RDAP.domain("jsiqpmcurt.com") # The message is not always exactly the same
73
+ # => RDAP::NotFound ([404] Not Found)
74
+ RDAP.domain("u$&~(!*@&@^#}") # Invalid URI
75
+ # => URI::InvalidURIError (bad URI(is not URI?): "https://rdap.org/domain/u$&~(!*@&@^#}")
76
+ RDAP.domain("broken") # Other type of unexpected server response
77
+ # => RDAP::ServerError ([500] Internal Server Error)
78
+ ```
79
+
80
+ ## How does it work
81
+
82
+ The gem make a query to one of the publicly available RDAP bootstrap server (their responsibility is simply to check the [bootstrap files](https://data.iana.org/rdap/dns.json) and redirect you to the proper RDAP server), then it does the query to the target RDAP server and returns the JSON parsed. The gem currently use this public bootstrap server: https://rdap.org/ but it's possible to change for another one in case of problem or limitation. For example ARIN has it's own bootstrap server too: https://rdap-bootstrap.arin.net/bootstrap. It's also possible to host your own bootstrap server.
83
+
84
+ ## Changelog
85
+
86
+ **0.1.0** (2021-12-17) - Initial version
87
+
88
+ ## Contributing
89
+
90
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jarthod/rdap.
91
+
92
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
93
+
94
+ Tests are using the `vcr` gem to record server responses so we don't hit them too quickly/often. This is nice and fast but if the server API even changes we may not notice it. So from time to time it can be intereting to re-record the responses: `rm -R spec/fixtures && rake spec`
95
+
96
+ ## Alternatives
97
+
98
+ If you're looking for a command line tool, you can check the excellent [nicinfo](https://github.com/arineng/nicinfo) (also written in Ruby).
99
+ Also if you're just looking for one-off debugging and scripts, you can query a bootstrap endpoint directly using `curl -L`, example:
100
+
101
+ ```
102
+ > curl -L https://rdap-bootstrap.arin.net/bootstrap/domain/google.com
103
+ {"objectClassName":"domain","handle":"2138514_DOMAIN_COM-VRSN","ldhName":"GOOGLE.COM","links":[{"value":"https:\/\/rdap.verisign.com\/com\/v1\/domain\/GOOGLE.COM","rel":"self","href":"https:\/\/rdap.verisign.com\/com\/v1\/domain\/GOOGLE.COM","type":"application\/rdap+json"},{"value":"https:\/\/rdap.markmonitor.com\/rdap\/domain\/GOOGLE.COM","rel":"related","href":"https:\/\/rdap.markmonitor.com\/rdap\/domain\/GOOGLE.COM","type":"application\/rdap+json"}],"status":["client delete prohibited","client transfer prohibited","client update prohibited","server delete prohibited","server transfer prohibited","server update prohibited"],"entities":[{"objectClassName":"entity","handle":"292","roles":["registrar"],"publicIds":[{"type":"IANA Registrar ID","identifier":"292"}],"vcardArray":["vcard",[["version",{},"text","4.0"],["fn",{},"text","MarkMonitor Inc."]]],"entities":[{"objectClassName":"entity","roles":["abuse"],"vcardArray":["vcard",[["version",{},"text","4.0"],["fn",{},"text",""],["tel",{"type":"voice"},"uri","tel:+1.2083895740"],["email",{},"text","abusecomplaints@markmonitor.com"]]]}]}],"events":[{"eventAction":"registration","eventDate":"1997-09-15T04:00:00Z"},{"eventAction":"expiration","eventDate":"2028-09-14T04:00:00Z"},{"eventAction":"last update of RDAP database","eventDate":"2021-12-17T11:35:32Z"}],"secureDNS":{"delegationSigned":false},"nameservers":[{"objectClassName":"nameserver","ldhName":"NS1.GOOGLE.COM"},{"objectClassName":"nameserver","ldhName":"NS2.GOOGLE.COM"},{"objectClassName":"nameserver","ldhName":"NS3.GOOGLE.COM"},{"objectClassName":"nameserver","ldhName":"NS4.GOOGLE.COM"}],"rdapConformance":["rdap_level_0","icann_rdap_technical_implementation_guide_0","icann_rdap_response_profile_0"],"notices":[{"title":"Terms of Use","description":["Service subject to Terms of Use."],"links":[{"href":"https:\/\/www.verisign.com\/domain-names\/registration-data-access-protocol\/terms-service\/index.xhtml","type":"text\/html"}]},{"title":"Status Codes","description":["For more information on domain status codes, please visit https:\/\/icann.org\/epp"],"links":[{"href":"https:\/\/icann.org\/epp","type":"text\/html"}]},{"title":"RDDS Inaccuracy Complaint Form","description":["URL of the ICANN RDDS Inaccuracy Complaint Form: https:\/\/icann.org\/wicf"],"links":[{"href":"https:\/\/icann.org\/wicf","type":"text\/html"}]}]}
104
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rdap"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/lib/rdap.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'json'
2
+ require 'net/http'
3
+
4
+ module RDAP
5
+ VERSION = "0.1.0"
6
+ BOOTSTRAP = "https://rdap.org/"
7
+ TYPES = [:domain, :ip, :autnum]
8
+
9
+ class Error < StandardError; end
10
+ class ServerError < Error; end
11
+ class NotFound < Error; end
12
+
13
+ def self.domain name, **opts
14
+ query name, type: :domain, **opts
15
+ end
16
+
17
+ def self.ip name, **opts
18
+ query name, type: :ip, **opts
19
+ end
20
+
21
+ def self.as name, **opts
22
+ query name, type: :autnum, **opts
23
+ end
24
+
25
+ def self.query name, type:, timeout: 5, server: BOOTSTRAP
26
+ TYPES.include?(type) or raise ArgumentError.new("RDAP: Invalid query type: #{type}, supported types: #{TYPES}")
27
+ uri = URI("#{server.chomp('/')}/#{type}/#{name}")
28
+ get_follow_redirects(uri, timeout: timeout)
29
+ end
30
+
31
+ private
32
+
33
+ def self.get_follow_redirects uri, timeout: 5, redirection_limit: 5
34
+ raise ServerError.new("Too many redirections (> #{redirection_limit}) at #{uri}") if redirection_limit == 0
35
+
36
+ http = Net::HTTP.new(uri.host, uri.port)
37
+ http.open_timeout = timeout
38
+ http.read_timeout = timeout
39
+ http.use_ssl = true
40
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
41
+
42
+ response = http.get(uri.path, "Accept" => "application/rdap+json")
43
+ case response
44
+ when Net::HTTPSuccess
45
+ document = JSON.parse(response.body)
46
+ if document["errorCode"]
47
+ raise ServerError.new("[#{document["errorCode"]}] #{document["title"]} (#{uri})")
48
+ end
49
+ document
50
+ when Net::HTTPNotFound
51
+ # 404 sometimes return details in the JSON body so we threat them later
52
+ if response.body.size > 0 and (document = JSON.parse(response.body) rescue nil)
53
+ raise NotFound.new("[#{document["errorCode"]}] #{document["title"]}")
54
+ else
55
+ raise NotFound.new("[#{response.code}] #{response.message}")
56
+ end
57
+ when Net::HTTPRedirection
58
+ get_follow_redirects(URI(response["location"]), timeout: timeout, redirection_limit: redirection_limit - 1)
59
+ else
60
+ raise ServerError.new("[#{response.code}] #{response.message}")
61
+ end
62
+ end
63
+ end
data/rdap.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ require_relative 'lib/rdap'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "rdap"
5
+ spec.version = RDAP::VERSION
6
+ spec.authors = ["Adrien Rey-Jarthon"]
7
+ spec.email = ["jobs@adrienjarthon.com"]
8
+
9
+ spec.summary = %q{A minimal Ruby client to query RDAP APIs though a bootstrap server}
10
+ spec.homepage = "https://github.com/jarthod/rdap"
11
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
12
+
13
+ # Specify which files should be added to the gem when it is released.
14
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
15
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
16
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ end
18
+ spec.require_paths = ["lib"]
19
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdap
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Adrien Rey-Jarthon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-12-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - jobs@adrienjarthon.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - ".travis.yml"
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - README.md
25
+ - Rakefile
26
+ - bin/console
27
+ - lib/rdap.rb
28
+ - rdap.gemspec
29
+ homepage: https://github.com/jarthod/rdap
30
+ licenses: []
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.3.0
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.1.2
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: A minimal Ruby client to query RDAP APIs though a bootstrap server
51
+ test_files: []