module ElbPing::HttpPinger
Responsible for all HTTP ping-like functionality
Public Class Methods
Check if a given host matches a cert’s pattern
Arguments:
-
cert: (object) of X.509 certificate
-
host: (string) of a hostname to compare
# File lib/elbping/pinger.rb, line 31 def self.cert_matches?(cert, host) File.fnmatch(cert_name(cert.subject).first, host) end
Extract CNs from a X509 subject string
Arguments:
-
x509_subject: (string) of cert subject
# File lib/elbping/pinger.rb, line 15 def self.cert_name(x509_subject) cn_bucket = Array.new x509_subject.to_a.each do |entry| if entry.first == 'CN' and entry[1] cn_bucket << entry[1] end end cn_bucket end
Make HTTP request to given node using custom request method and measure response time
Arguments:
-
node: (string) of node IP
-
host: (string) of hostname, used for checking SSL cert match
-
port: (string || Fixnum) of positive integer [1, 65535]
-
path: (string) of path to request, e.g. “/”
-
use_ssl: (boolean) Whether or not this is HTTPS
-
verb_len: (Fixnum) of positive integer, how long the custom HTTP verb should be
-
timeout: (Fixnum) of positive integer, how many seconds for connect and read timeouts
# File lib/elbping/pinger.rb, line 46 def self.ping_node(node, host, port, path, use_ssl, verb_len, timeout) ## # Build request class ping_request = Class.new(Net::HTTPRequest) do const_set :METHOD, "A" * verb_len const_set :REQUEST_HAS_BODY, false const_set :RESPONSE_HAS_BODY, false end ## # Configure http object start = Time.now.getutc http = Net::HTTP.new(node, port.to_s) http.open_timeout = timeout http.read_timeout = timeout http.continue_timeout = timeout # Enable SSL if it's to be used if use_ssl http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE http.ssl_timeout = timeout end ## # Make the HTTP request and handle any errors along the way error, exc = nil, nil req, response, cert = nil, nil, nil begin http.start do req = ping_request.new(path) cert = http.peer_cert response = http.request(req) end rescue OpenSSL::SSL::SSLError => e # This probably? won't happen with VERIFY_NONE error = :sslerror rescue Errno::ECONNREFUSED error = :econnrefused rescue Timeout::Error error = :timeout rescue Interrupt raise rescue SystemExit raise rescue StandardError => e exc = e # because I don't understand scope in ruby yet error = :exception end ssl_status = {} if use_ssl raise "No cert when SSL enabled?!" unless cert ssl_status = { :sslSubject => cert_name(cert.subject), :sslExpires => cert.not_after, :sslHostMatch => cert_matches?(cert, host) } end {:code => error || response.code, :exception => exc, :node => node, :duration => ((Time.now.getutc - start) * 1000).to_i, # returns in ms }.merge(ssl_status) end