Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Customizable query handler #189

Closed
wants to merge 2 commits into
from
Jump to file or symbol
Failed to load files and symbols.
+114 −111
Split
@@ -18,22 +18,57 @@ module Adapters
class Base
+ # The SocketHandler is the default query handler provided with the
+ # Whois library. It performs the WHOIS query using a synchronous
+ # socket connection.
+ class SocketHandler
+
+ # Array of connection errors to rescue
+ # and wrap into a {Whois::ConnectionError}
+ RESCUABLE_CONNECTION_ERRORS = [
+ Errno::ECONNRESET,
+ Errno::EHOSTUNREACH,
+ Errno::ECONNREFUSED,
+ SocketError,
+ ]
+
+ # TODO: *args might probably be a Hash
+ def call(query, *args)
+ execute(query, *args)
+ rescue *RESCUABLE_CONNECTION_ERRORS => error
+ raise ConnectionError, "#{error.class}: #{error.message}"
+ end
+
+ # Executes the low-level Socket connection.
+ #
+ # It opens the socket passing given +args+,
+ # sends the +query+ and reads the response.
+ #
+ # This is for internal use only!
+ #
+ # @param [String] query
+ # @param [Array] args
+ # @return [String]
+ #
+ # @api private
+ def execute(query, *args)
+ client = TCPSocket.new(*args)
+ client.write("#{query}\r\n") # I could use put(foo) and forget the \n
+ client.read # but write/read is more symmetric than puts/read
+ ensure # and I really want to use read instead of gets.
+ client.close if client # If != client something went wrong.
+ end
+ end
+
# Default WHOIS request port.
DEFAULT_WHOIS_PORT = 43
-
# Default bind hostname.
DEFAULT_BIND_HOST = "0.0.0.0"
- # Array of connection errors to rescue and wrap into a {Whois::ConnectionError}
- RESCUABLE_CONNECTION_ERRORS = [
- Errno::ECONNRESET,
- Errno::EHOSTUNREACH,
- Errno::ECONNREFUSED,
- SocketError,
- ]
-
+ class_attribute :query_handler
+ self.query_handler = SocketHandler.new
- # @return [Symbol] The type of WHOIS server
+ # @return [Symbol] The type of WHOIS server.
attr_reader :type
# @return [String] The allocation this server is responsible for.
attr_reader :allocation
@@ -135,16 +170,14 @@ def request(string)
end
- private
+ private
# Store a record part in {#buffer}.
#
# @param [String] body
# @param [String] host
# @return [void]
#
- # @api public
- #
def buffer_append(body, host)
@buffer << Whois::Record::Part.new(:body => body, :host => host)
end
@@ -157,8 +190,7 @@ def buffer_start
result
end
- # @api public
- def query_the_socket(query, host, port = nil)
+ def query_prepare(query, host, port = nil)
args = []
args.push(host)
args.push(port || options[:port] || DEFAULT_WHOIS_PORT)
@@ -178,25 +210,10 @@ def query_the_socket(query, host, port = nil)
args.push(options[:bind_port]) if options[:bind_port]
end
- ask_the_socket(query, *args)
-
- rescue *RESCUABLE_CONNECTION_ERRORS => error
- raise ConnectionError, "#{error.class}: #{error.message}"
+ self.class.query_handler.call(query, *args)
end
- # This method handles the lowest connection
- # to the WHOIS server.
- #
- # This is for internal use only!
- #
- # @api private
- def ask_the_socket(query, *args)
- client = TCPSocket.new(*args)
- client.write("#{query}\r\n") # I could use put(foo) and forget the \n
- client.read # but write/read is more symmetric than puts/read
- ensure # and I really want to use read instead of gets.
- client.close if client # If != client something went wrong.
- end
+ alias :query_the_socket :query_prepare
end
View
@@ -8,10 +8,10 @@
it "works" do
with_definitions do
Whois::Server.define(:tld, ".it", "whois.nic.it")
- Whois::Server::Adapters::Standard.any_instance \
- .expects(:ask_the_socket) \
- .with("example.it", "whois.nic.it", 43) \
- .returns(response)
+ Whois::Server::Adapters::Base.
+ query_handler.expects(:call).
+ with("example.it", "whois.nic.it", 43).
+ returns(response)
record = Whois.query("example.it")
@@ -29,10 +29,10 @@
it "binds the WHOIS query to given host and port" do
with_definitions do
Whois::Server.define(:tld, ".it", "whois.nic.it")
- Whois::Server::Adapters::Standard.any_instance \
- .expects(:ask_the_socket) \
- .with("example.it", "whois.nic.it", 43, "192.168.1.1", 3000) \
- .returns(response)
+ Whois::Server::Adapters::Base.
+ query_handler.expects(:call).
+ with("example.it", "whois.nic.it", 43, "192.168.1.1", 3000).
+ returns(response)
client = Whois::Client.new(:bind_host => "192.168.1.1", :bind_port => 3000)
client.query("example.it")
@@ -44,10 +44,10 @@
it "binds the WHOIS query to given port and defaults host" do
with_definitions do
Whois::Server.define(:tld, ".it", "whois.nic.it")
- Whois::Server::Adapters::Standard.any_instance \
- .expects(:ask_the_socket) \
- .with("example.it", "whois.nic.it", 43, Whois::Server::Adapters::Base::DEFAULT_BIND_HOST, 3000) \
- .returns(response)
+ Whois::Server::Adapters::Base.
+ query_handler.expects(:call).
+ with("example.it", "whois.nic.it", 43, Whois::Server::Adapters::Base::DEFAULT_BIND_HOST, 3000).
+ returns(response)
client = Whois::Client.new(:bind_port => 3000)
client.query("example.it")
@@ -59,8 +59,8 @@
it "forces the WHOIS query to given host" do
with_definitions do
Whois::Server.define(:tld, ".it", "whois.nic.it")
- Whois::Server::Adapters::Standard.any_instance.
- expects(:ask_the_socket).
+ Whois::Server::Adapters::Base.
+ query_handler.expects(:call).
with("example.it", "whois.example.com", 43).
returns(response)
@@ -11,7 +11,7 @@ def fixture(*names)
File.join(SPEC_ROOT, "fixtures", *names)
end
-private
+ private
# Temporary resets Server @@definitions
# to let the test setup a custom definition list.
@@ -2,20 +2,18 @@
describe Whois::Server::Adapters::Afilias do
- before(:each) do
- @definition = [:tld, ".test", "whois.afilias-grs.info", {}]
- @server = klass.new(*@definition)
- end
+ let(:definition) { [:tld, ".test", "whois.afilias-grs.info", {}] }
+ let(:server) { klass.new(*definition) }
describe "#query" do
context "without referral" do
it "returns the WHOIS record" do
response = "No match for DOMAIN.TEST."
expected = response
- @server.expects(:ask_the_socket).with("domain.test", "whois.afilias-grs.info", 43).returns(response)
+ server.query_handler.expects(:call).with("domain.test", "whois.afilias-grs.info", 43).returns(response)
- record = @server.query("domain.test")
+ record = server.query("domain.test")
record.to_s.should == expected
record.parts.should have(1).part
record.parts.should == [Whois::Record::Part.new(:body => response, :host => "whois.afilias-grs.info")]
@@ -27,10 +25,10 @@
referral = File.read(fixture("referrals/afilias.bz.txt"))
response = "Match for DOMAIN.TEST."
expected = referral + "\n" + response
- @server.expects(:ask_the_socket).with("domain.test", "whois.afilias-grs.info", 43).returns(referral)
- @server.expects(:ask_the_socket).with("domain.test", "whois.belizenic.bz", 43).returns(response)
+ server.query_handler.expects(:call).with("domain.test", "whois.afilias-grs.info", 43).returns(referral)
+ server.query_handler.expects(:call).with("domain.test", "whois.belizenic.bz", 43).returns(response)
- record = @server.query("domain.test")
+ record = server.query("domain.test")
record.to_s.should == expected
record.parts.should have(2).parts
record.parts.should == [Whois::Record::Part.new(:body => referral, :host => "whois.afilias-grs.info"), Whois::Record::Part.new(:body => response, :host => "whois.belizenic.bz")]
@@ -114,52 +114,46 @@
describe "#query_the_socket" do
[ Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, SocketError ].each do |error|
it "re-raises #{error} as Whois::ConnectionError" do
- klass.any_instance.expects(:ask_the_socket).raises(error)
+ klass.query_handler.expects(:execute).raises(error)
expect {
klass.new(*definition).send(:query_the_socket, "example.com", "whois.test")
}.to raise_error(Whois::ConnectionError, "#{error}: #{error.new.message}")
end
end
context "without :bind_host or :bind_port options" do
- before(:each) do
- @base = klass.new(:tld, ".test", "whois.test", {})
- end
+ let(:server) { klass.new(:tld, ".test", "whois.test", {}) }
it "does not bind the WHOIS query" do
- @base \
- .expects(:ask_the_socket) \
- .with("example.test", "whois.test", 43)
+ klass.
+ query_handler.expects(:call).
+ with("example.test", "whois.test", 43)
- @base.send(:query_the_socket, "example.test", "whois.test", 43)
+ server.send(:query_the_socket, "example.test", "whois.test", 43)
end
end
context "with :bind_host and :bind_port options" do
- before(:each) do
- @base = klass.new(:tld, ".test", "whois.test", { :bind_host => "192.168.1.1", :bind_port => 3000 })
- end
+ let(:server) { klass.new(:tld, ".test", "whois.test", { :bind_host => "192.168.1.1", :bind_port => 3000 }) }
it "binds the WHOIS query to given host and port" do
- @base \
- .expects(:ask_the_socket) \
- .with("example.test", "whois.test", 43, "192.168.1.1", 3000)
+ klass.
+ query_handler.expects(:call).
+ with("example.test", "whois.test", 43, "192.168.1.1", 3000)
- @base.send(:query_the_socket, "example.test", "whois.test", 43)
+ server.send(:query_the_socket, "example.test", "whois.test", 43)
end
end
context "with :bind_port and without :bind_host options" do
- before(:each) do
- @base = klass.new(:tld, ".test", "whois.test", { :bind_port => 3000 })
- end
+ let(:server) { klass.new(:tld, ".test", "whois.test", { :bind_port => 3000 }) }
it "binds the WHOIS query to given port and defaults host" do
- @base \
- .expects(:ask_the_socket) \
- .with("example.test", "whois.test", 43, klass::DEFAULT_BIND_HOST, 3000)
+ klass.
+ query_handler.expects(:call).
+ with("example.test", "whois.test", 43, klass::DEFAULT_BIND_HOST, 3000)
- @base.send(:query_the_socket, "example.test", "whois.test", 43)
+ server.send(:query_the_socket, "example.test", "whois.test", 43)
end
end
end
@@ -2,17 +2,15 @@
describe Whois::Server::Adapters::Formatted do
- before(:each) do
- @definition = [:tld, ".de", "whois.denic.de", { :format => "-T dn,ace -C US-ASCII %s" }]
- end
+ let(:definition) { [:tld, ".de", "whois.denic.de", { :format => "-T dn,ace -C US-ASCII %s" }] }
describe "#query" do
it "returns the WHOIS record" do
response = "Whois Response"
expected = response
- server = klass.new(*@definition)
- server.expects(:ask_the_socket).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 43).returns(response)
+ server = klass.new(*definition)
+ server.query_handler.expects(:call).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 43).returns(response)
record = server.query("domain.de")
record.to_s.should == expected
@@ -23,7 +21,7 @@
it "raises an error" do
lambda do
server = klass.new(*[:tld, ".de", "whois.denic.de", {}])
- server.expects(:ask_the_socket).never
+ server.query_handler.expects(:call).never
server.query("domain.de")
end.should raise_error(Whois::ServerError)
end
@@ -33,7 +31,7 @@
it "sends the request to given port" do
response = "Whois Response"
server = klass.new(:tld, ".de", "whois.denic.de", { :format => "-T dn,ace -C US-ASCII %s", :port => 20 })
- server.expects(:ask_the_socket).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 20).returns(response)
+ server.query_handler.expects(:call).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 20).returns(response)
server.query("domain.de")
end
@@ -44,7 +42,7 @@
response = "Whois Response"
server = klass.new(:tld, ".de", "whois.denic.de", { :format => "-T dn,ace -C US-ASCII %s" })
server.configure(:bind_host => "192.168.1.1", :bind_port => 3000)
- server.expects(:ask_the_socket).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 43, "192.168.1.1", 3000).returns(response)
+ server.query_handler.expects(:call).with("-T dn,ace -C US-ASCII domain.de", "whois.denic.de", 43, "192.168.1.1", 3000).returns(response)
server.query("domain.de")
end
@@ -2,17 +2,15 @@
describe Whois::Server::Adapters::Standard do
- before(:each) do
- @definition = [:tld, ".test", "whois.test", {}]
- end
+ let(:definition) { [:tld, ".test", "whois.test", {}] }
describe "#query" do
it "returns the WHOIS record" do
response = "Whois Response"
expected = response
- server = klass.new(*@definition)
- server.expects(:ask_the_socket).with("domain.test", "whois.test", 43).returns(response)
+ server = klass.new(*definition)
+ server.query_handler.expects(:call).with("domain.test", "whois.test", 43).returns(response)
record = server.query("domain.test")
record.to_s.should == expected
@@ -23,7 +21,7 @@
it "sends the request to given port" do
response = "Whois Response"
server = klass.new(:tld, ".test", "whois.test", { :port => 20 })
- server.expects(:ask_the_socket).with("domain.test", "whois.test", 20).returns(response)
+ server.query_handler.expects(:call).with("domain.test", "whois.test", 20).returns(response)
server.query("domain.test")
end
@@ -34,7 +32,7 @@
response = "Whois Response"
server = klass.new(:tld, ".test", "whois.test", { :port => 20 })
server.configure(:bind_host => "192.168.1.100", :bind_port => 3000)
- server.expects(:ask_the_socket).with("domain.test", "whois.test", 20, "192.168.1.100", 3000).returns(response)
+ server.query_handler.expects(:call).with("domain.test", "whois.test", 20, "192.168.1.100", 3000).returns(response)
server.query("domain.test")
end
Oops, something went wrong.