require 'socket'
require 'timeout'
module IsItWorking
class PingCheck
# Check if a host is reachable and accepting connections on a specified port.
#
# The host and port to ping are specified with the :host and :port options. The port
# can be either a port number or port name for a well known port (i.e. "smtp" and 25 are
# equivalent). The default timeout to wait for a response is 2 seconds. This can be
# changed with the :timeout option.
#
# By default, the host name will be included in the output. If this could pose a security
# risk by making the existence of the host known to the world, you can supply the :alias
# option which will be used for output purposes. In general, you should supply this option
# unless the host is on a private network behind a firewall.
#
# === Example
#
# IsItWorking::Handler.new do |h|
# h.check :ping, :host => "example.com", :port => "ftp", :timeout => 4
# end
def initialize(options={})
@host = options[:host]
raise ArgumentError.new(":host not specified") unless @host
@port = options[:port]
raise ArgumentError.new(":port not specified") unless @port
@timeout = options[:timeout] || 2
@alias = options[:alias] || @host
end
def call(status)
begin
ping(@host, @port)
status.ok("#{@alias} is accepting connections on port #{@port.inspect}")
rescue Errno::ECONNREFUSED
status.fail("#{@alias} is not accepting connections on port #{@port.inspect}")
rescue SocketError => e
status.fail("connection to #{@alias} on port #{@port.inspect} failed with '#{e.message}'")
rescue Timeout::Error
status.fail("#{@alias} did not respond on port #{@port.inspect} within #{@timeout} seconds")
end
end
def ping(host, port)
timeout(@timeout) do
s = TCPSocket.new(host, port)
s.close
end
true
end
end
end