em-whois 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +24 -0
- data/README.md +34 -0
- data/Rakefile +10 -0
- data/VERSION.yml +4 -0
- data/examples/async_whois.rb +24 -0
- data/examples/sync_whois.rb +13 -0
- data/lib/em-whois.rb +52 -0
- data/spec/em-whois_spec.rb +49 -0
- data/spec/helper/all.rb +5 -0
- metadata +89 -0
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-I.
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
diff-lcs (1.1.3)
|
|
5
|
+
em-synchrony (1.0.0)
|
|
6
|
+
eventmachine (>= 1.0.0.beta.1)
|
|
7
|
+
eventmachine (1.0.0.beta.4)
|
|
8
|
+
rspec (2.9.0)
|
|
9
|
+
rspec-core (~> 2.9.0)
|
|
10
|
+
rspec-expectations (~> 2.9.0)
|
|
11
|
+
rspec-mocks (~> 2.9.0)
|
|
12
|
+
rspec-core (2.9.0)
|
|
13
|
+
rspec-expectations (2.9.0)
|
|
14
|
+
diff-lcs (~> 1.1.3)
|
|
15
|
+
rspec-mocks (2.9.0)
|
|
16
|
+
whois (2.5.0)
|
|
17
|
+
|
|
18
|
+
PLATFORMS
|
|
19
|
+
ruby
|
|
20
|
+
|
|
21
|
+
DEPENDENCIES
|
|
22
|
+
em-synchrony
|
|
23
|
+
rspec
|
|
24
|
+
whois (= 2.5.0)
|
data/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# em-whois
|
|
2
|
+
|
|
3
|
+
This is a container for the synchronous WHOIS gem which replaces socket communications
|
|
4
|
+
with the EventMachine equivalent. The result is a gem permitting asynchronous WHOIS
|
|
5
|
+
lookups.
|
|
6
|
+
|
|
7
|
+
`em-whois` is EventMachine-aware, meaning that it'll use asynchronous sockets when called
|
|
8
|
+
inside the reactor, and fallback to original sockets outside the reactor context.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
Simple example to grab whois info within the EventMachine loop:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
EM.synchrony do
|
|
17
|
+
|
|
18
|
+
# Async domain availability lookup via WHOIS info
|
|
19
|
+
whois = Whois.whois(ARGV[0] || "github.com")
|
|
20
|
+
puts whois.properties[:available?] ? "Domain Available" : "Domain Taken"
|
|
21
|
+
|
|
22
|
+
EM.stop
|
|
23
|
+
end
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## TODO
|
|
28
|
+
|
|
29
|
+
* More elegant approach to reading from the EM::Synchrony::TcpSocket in Whois::Server::Adapters::Base#ask_the_socket
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## License & Notes
|
|
33
|
+
|
|
34
|
+
The MIT License - Copyright (c) 2012 [Mike Jarema](http://mikejarema.com)
|
data/Rakefile
ADDED
data/VERSION.yml
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
|
2
|
+
require 'em-whois'
|
|
3
|
+
|
|
4
|
+
# Asynchronous WHOIS lookup -- em-whois should opt to use EM-based TcpSocket
|
|
5
|
+
|
|
6
|
+
EM.synchrony do
|
|
7
|
+
|
|
8
|
+
# EM pulse
|
|
9
|
+
EM.add_periodic_timer(0.1) do
|
|
10
|
+
STDERR.print "."
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Async WHOIS lookup
|
|
14
|
+
domain = ARGV[0] || "github.com"
|
|
15
|
+
|
|
16
|
+
r = Whois.whois(domain)
|
|
17
|
+
|
|
18
|
+
puts "\r#{domain}\n#{"-" * domain.length}"
|
|
19
|
+
[:available?, :status, :expires_on].each do |k|
|
|
20
|
+
puts "#{k}: #{r.properties[k]}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
EM.stop
|
|
24
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
|
2
|
+
require 'em-whois'
|
|
3
|
+
|
|
4
|
+
# Synchronous WHOIS lookup -- em-whois should opt to use original TcpSocket
|
|
5
|
+
|
|
6
|
+
domain = ARGV[0] || "github.com"
|
|
7
|
+
|
|
8
|
+
r = Whois.whois(domain)
|
|
9
|
+
|
|
10
|
+
puts "\r#{domain}\n#{"-" * domain.length}"
|
|
11
|
+
[:available?, :status, :expires_on].each do |k|
|
|
12
|
+
puts "#{k}: #{r.properties[k]}"
|
|
13
|
+
end
|
data/lib/em-whois.rb
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'whois'
|
|
2
|
+
require 'em-synchrony'
|
|
3
|
+
|
|
4
|
+
module Whois
|
|
5
|
+
class Server
|
|
6
|
+
module Adapters
|
|
7
|
+
class Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# This method handles the lowest connection
|
|
11
|
+
# to the WHOIS server.
|
|
12
|
+
#
|
|
13
|
+
# This is for internal use only!
|
|
14
|
+
#
|
|
15
|
+
# @api internal
|
|
16
|
+
|
|
17
|
+
alias :orig_ask_the_socket :ask_the_socket
|
|
18
|
+
|
|
19
|
+
def ask_the_socket(*args)
|
|
20
|
+
defined?(EM) && EM.reactor_running? ? em_ask_the_socket(*args) : orig_ask_the_socket(*args)
|
|
21
|
+
end # ask_the_socket
|
|
22
|
+
|
|
23
|
+
def em_ask_the_socket(query, *args)
|
|
24
|
+
client = EventMachine::Synchrony::TCPSocket.new(*args)
|
|
25
|
+
client.write("#{query}\r\n") # I could use put(foo) and forget the \n
|
|
26
|
+
# but write/read is more symmetric than puts/read
|
|
27
|
+
# and I really want to use read instead of gets.
|
|
28
|
+
|
|
29
|
+
response = ""
|
|
30
|
+
|
|
31
|
+
# Synchrony TCPSocket behaves a little differently, seems to require
|
|
32
|
+
# polling until an IO exception is thrown.
|
|
33
|
+
# TODO: There's gotta be a more elegant way to achieve this.
|
|
34
|
+
while true do
|
|
35
|
+
begin
|
|
36
|
+
response += client.read
|
|
37
|
+
rescue IOError => e
|
|
38
|
+
break
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
response
|
|
43
|
+
|
|
44
|
+
ensure
|
|
45
|
+
client.close if client # If != client something went wrong.
|
|
46
|
+
|
|
47
|
+
end # em_ask_the_socket
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require "spec/helper/all"
|
|
2
|
+
|
|
3
|
+
describe "Asynchronous WHOIS" do
|
|
4
|
+
|
|
5
|
+
it "should not use synchronous socket methods" do
|
|
6
|
+
|
|
7
|
+
EM.synchrony do
|
|
8
|
+
Whois::Server::Adapters::Base.any_instance.should_not_receive(:orig_ask_the_socket)
|
|
9
|
+
|
|
10
|
+
whois = Whois.whois("google.com")
|
|
11
|
+
whois.should_not be_available # Sanity check
|
|
12
|
+
|
|
13
|
+
whois = Whois.whois("#{rand(Time.now.to_i)}-alskdjflkasjd.com")
|
|
14
|
+
whois.should be_available # Sanity check
|
|
15
|
+
|
|
16
|
+
EM.stop
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should match synchronous WHOIS results" do
|
|
22
|
+
async_whois = nil
|
|
23
|
+
sync_whois = nil
|
|
24
|
+
|
|
25
|
+
EM.synchrony do
|
|
26
|
+
async_whois = Whois.whois("github.com")
|
|
27
|
+
EM.stop
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
sync_whois = Whois.whois("github.com")
|
|
31
|
+
|
|
32
|
+
async_whois.properties.should == sync_whois.properties
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe "Synchronous WHOIS" do
|
|
38
|
+
|
|
39
|
+
it "should not use asynchronous socket methods" do
|
|
40
|
+
Whois::Server::Adapters::Base.any_instance.should_not_receive(:em_ask_the_socket)
|
|
41
|
+
|
|
42
|
+
whois = Whois.whois("google.com")
|
|
43
|
+
whois.should_not be_available # Sanity check
|
|
44
|
+
|
|
45
|
+
whois = Whois.whois("#{rand(Time.now.to_i)}-alskdjflkasjd.com")
|
|
46
|
+
whois.should be_available # Sanity check
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
data/spec/helper/all.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: em-whois
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Mike Jarema
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2012-04-01 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: eventmachine
|
|
16
|
+
requirement: &70096718694400 !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: *70096718694400
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: whois
|
|
27
|
+
requirement: &70096718692400 !ruby/object:Gem::Requirement
|
|
28
|
+
none: false
|
|
29
|
+
requirements:
|
|
30
|
+
- - =
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 2.5.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: *70096718692400
|
|
36
|
+
- !ruby/object:Gem::Dependency
|
|
37
|
+
name: em-synchrony
|
|
38
|
+
requirement: &70096718675440 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ! '>='
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
type: :runtime
|
|
45
|
+
prerelease: false
|
|
46
|
+
version_requirements: *70096718675440
|
|
47
|
+
description: Wrapper around whois gem providing asynchronous WHOIS queries via EventMachine
|
|
48
|
+
email: mike@jarema.com
|
|
49
|
+
executables: []
|
|
50
|
+
extensions: []
|
|
51
|
+
extra_rdoc_files: []
|
|
52
|
+
files:
|
|
53
|
+
- VERSION.yml
|
|
54
|
+
- README.md
|
|
55
|
+
- .rspec
|
|
56
|
+
- Gemfile
|
|
57
|
+
- Gemfile.lock
|
|
58
|
+
- Rakefile
|
|
59
|
+
- examples/async_whois.rb
|
|
60
|
+
- examples/sync_whois.rb
|
|
61
|
+
- lib/em-whois.rb
|
|
62
|
+
- spec/em-whois_spec.rb
|
|
63
|
+
- spec/helper/all.rb
|
|
64
|
+
homepage: http://github.com/mikejarema/em-whois
|
|
65
|
+
licenses: []
|
|
66
|
+
post_install_message:
|
|
67
|
+
rdoc_options:
|
|
68
|
+
- --charset=UTF-8
|
|
69
|
+
require_paths:
|
|
70
|
+
- lib
|
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
|
+
none: false
|
|
73
|
+
requirements:
|
|
74
|
+
- - ! '>='
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
|
+
none: false
|
|
79
|
+
requirements:
|
|
80
|
+
- - ! '>='
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
requirements: []
|
|
84
|
+
rubyforge_project:
|
|
85
|
+
rubygems_version: 1.8.11
|
|
86
|
+
signing_key:
|
|
87
|
+
specification_version: 3
|
|
88
|
+
summary: Query WHOIS servers using native EventMachine connection classes.
|
|
89
|
+
test_files: []
|