Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Use HTTP head instead of GET by default #11

Merged
merged 1 commit into from

2 participants

@bkutil

Second try :)

Balazs Kutil Use HTTP head instead of GET by default
This patch replaces the http GET request with HEAD. HEAD requests should
be handled identically, but the response does not contain message
body. GET will still be used when @get_request option is set to true.

Replacing the get_response (which calls GET internally) with a new
http HEAD request would mean code duplication. Thus, the part that does
the actual ping is refactored to a separate private method.
This also means that new requests resulting from redirections are
now subject to timeout limit and they'll correctly use https.

Signed-off-by: Balazs Kutil <kutil.balazs@gmail.com>
ff721cd
@djberg96 djberg96 merged commit 1c8b682 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 4, 2011
  1. Use HTTP head instead of GET by default

    Balazs Kutil authored
    This patch replaces the http GET request with HEAD. HEAD requests should
    be handled identically, but the response does not contain message
    body. GET will still be used when @get_request option is set to true.
    
    Replacing the get_response (which calls GET internally) with a new
    http HEAD request would mean code duplication. Thus, the part that does
    the actual ping is refactored to a separate private method.
    This also means that new requests resulting from redirections are
    now subject to timeout limit and they'll correctly use https.
    
    Signed-off-by: Balazs Kutil <kutil.balazs@gmail.com>
This page is out of date. Refresh to see the latest.
Showing with 72 additions and 43 deletions.
  1. +63 −41 lib/net/ping/http.rb
  2. +9 −2 test/test_net_ping_http.rb
View
104 lib/net/ping/http.rb
@@ -30,6 +30,9 @@ class Ping::HTTP < Ping
# OpenSSL certificate verification mode. The default is VERIFY_NONE.
attr_accessor :ssl_verify_mode
+ # Use GET request instead HEAD. The default is false.
+ attr_accessor :get_request
+
# Creates and returns a new Ping::HTTP object. The default port is the
# port associated with the URI. The default timeout is 5 seconds.
#
@@ -37,6 +40,7 @@ def initialize(uri=nil, port=nil, timeout=5)
@follow_redirect = true
@redirect_limit = 5
@ssl_verify_mode = OpenSSL::SSL::VERIFY_NONE
+ @get_request = false
port ||= URI.parse(uri).port if uri
@@ -64,51 +68,35 @@ def ping(host = @host)
start_time = Time.now
- begin
- response = nil
- uri_path = uri.path.empty? ? '/' : uri.path
- headers = { }
- headers["User-Agent"] = user_agent unless user_agent.nil?
- Timeout.timeout(@timeout) do
- http = Net::HTTP.new(uri.host, uri.port)
- if uri.scheme == 'https'
- http.use_ssl = true
- http.verify_mode = @ssl_verify_mode
- end
- request = Net::HTTP::Get.new(uri_path)
- response = http.start{ |h| h.request(request) }
- end
- rescue Exception => err
- @exception = err.message
- else
- if response.is_a?(Net::HTTPSuccess)
- bool = true
- else
- if @follow_redirect
- @warning = response.message
- rlimit = 0
-
- # Any response code in the 300 range is a redirect
- while response.code.to_i >= 300 && response.code.to_i < 400
- if rlimit >= redirect_limit
- @exception = "Redirect limit exceeded"
- break
- end
- redirect = URI.parse(response['location'])
- redirect = uri + redirect if redirect.relative?
- response = Net::HTTP.get_response(redirect.host, redirect.path, @port)
- rlimit += 1
- end
+ response = do_ping(uri)
+
+ if response.is_a?(Net::HTTPSuccess)
+ bool = true
+ elsif redirect?(response) # Check code, HTTPRedirection does not always work
+ if @follow_redirect
+ @warning = response.message
+ rlimit = 0
- if response.is_a?(Net::HTTPSuccess)
- bool = true
- else
- @warning = nil
- @exception ||= response.message
+ while redirect?(response)
+ if rlimit >= redirect_limit
+ @exception = "Redirect limit exceeded"
+ break
end
+ redirect = URI.parse(response['location'])
+ redirect = uri + redirect if redirect.relative?
+ response = do_ping(redirect)
+ rlimit += 1
+ end
+
+ if response.is_a?(Net::HTTPSuccess)
+ bool = true
else
- @exception = response.message
+ @warning = nil
+ @exception ||= response.message
end
+
+ else
+ @exception = response.message
end
end
@@ -123,5 +111,39 @@ def ping(host = @host)
alias follow_redirect? follow_redirect
alias uri host
alias uri= host=
+
+ private
+
+ def redirect?(response)
+ response && response.code.to_i >= 300 && response.code.to_i < 400
+ end
+
+ def do_ping(uri)
+ response = nil
+ begin
+ uri_path = uri.path.empty? ? '/' : uri.path
+ headers = { }
+ headers["User-Agent"] = user_agent unless user_agent.nil?
+ Timeout.timeout(@timeout) do
+ http = Net::HTTP.new(uri.host, uri.port)
+
+ if uri.scheme == 'https'
+ http.use_ssl = true
+ http.verify_mode = @ssl_verify_mode
+ end
+
+ if @get_request == true
+ request = Net::HTTP::Get.new(uri_path)
+ else
+ request = Net::HTTP::Head.new(uri_path)
+ end
+
+ response = http.start{ |h| h.request(request) }
+ end
+ rescue Exception => err
+ @exception = err.message
+ end
+ response
+ end
end
end
View
11 test/test_net_ping_http.rb
@@ -16,8 +16,9 @@ def setup
@uri_https = 'https://encrypted.google.com'
FakeWeb.register_uri(:get, @uri, :body => "PONG")
- FakeWeb.register_uri(:get, @uri_https, :body => "PONG")
- FakeWeb.register_uri(:get, "http://jigsaw.w3.org/HTTP/300/302.html",
+ FakeWeb.register_uri(:head, @uri, :body => "PONG")
+ FakeWeb.register_uri(:head, @uri_https, :body => "PONG")
+ FakeWeb.register_uri(:head, "http://jigsaw.w3.org/HTTP/300/302.html",
:body => "PONG",
:location => "#{@uri}",
:status => ["302", "Found"])
@@ -168,6 +169,12 @@ def setup
assert_true(@http.ping)
end
+ test 'ping with get option' do
+ @http = Net::Ping::HTTP.new(@uri)
+ @http.get_request = true
+ assert_true(@http.ping)
+ end
+
def teardown
@uri = nil
@http = nil
Something went wrong with that request. Please try again.