diff --git a/lib/resources/http.rb b/lib/resources/http.rb index 82f02238e..c07985d34 100644 --- a/lib/resources/http.rb +++ b/lib/resources/http.rb @@ -203,7 +203,17 @@ module Inspec::Resources end def curl_command # rubocop:disable Metrics/AbcSize - cmd = ["curl -i -X #{http_method}"] + cmd = ['curl -i'] + + # Use curl's --head option when the method requested is HEAD. Otherwise, + # the user may experience a timeout when curl does not properly close + # the connection after the response is received. + if http_method.casecmp('HEAD') == 0 + cmd << '--head' + else + cmd << "-X #{http_method}" + end + cmd << "--connect-timeout #{open_timeout}" cmd << "--max-time #{open_timeout+read_timeout}" cmd << "--user \'#{username}:#{password}\'" unless username.nil? || password.nil? diff --git a/test/helper.rb b/test/helper.rb index 2fc28562a..bd116ed96 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -459,6 +459,7 @@ class MockLoader 'f77ebcedaf6fbe8f02d2f9d4735a90c12311d2ca4b43ece9efa2f2e396491747' => cmd.call('http-remote-post'), "curl -i -X GET --connect-timeout 60 --max-time 120 -H 'accept: application/json' -H 'foo: bar' 'http://www.example.com'" => cmd.call('http-remote-headers'), "curl -i -X GET --connect-timeout 60 --max-time 120 'http://www.example.com?a=b&c=d'" => cmd.call('http-remote-params'), + "curl -i --head --connect-timeout 60 --max-time 120 'http://www.example.com'" => cmd.call('http-remote-head-request'), # elasticsearch resource "curl -H 'Content-Type: application/json' http://localhost:9200/_nodes" => cmd.call('elasticsearch-cluster-nodes-default'), diff --git a/test/unit/mock/cmd/http-remote-head-request b/test/unit/mock/cmd/http-remote-head-request new file mode 100644 index 000000000..e97caa874 --- /dev/null +++ b/test/unit/mock/cmd/http-remote-head-request @@ -0,0 +1,10 @@ +HTTP/1.1 301 Moved Permanently +Location: http://www.google.com/ +Content-Type: text/html; charset=UTF-8 +Date: Mon, 27 Nov 2017 16:46:15 GMT +Expires: Wed, 27 Dec 2017 16:46:15 GMT +Cache-Control: public, max-age=2592000 +Server: gws +Content-Length: 219 +X-XSS-Protection: 1; mode=block +X-Frame-Options: SAMEORIGIN diff --git a/test/unit/resources/http_test.rb b/test/unit/resources/http_test.rb index cca00d30f..84128f7e8 100644 --- a/test/unit/resources/http_test.rb +++ b/test/unit/resources/http_test.rb @@ -118,5 +118,14 @@ describe 'Inspec::Resources::Http' do _(worker.body).must_equal 'params ok' end end + + describe 'a HEAD request' do + let(:http_method) { 'HEAD' } + + it 'returns correct data' do + _(worker.status).must_equal 301 + _(worker.response_headers['Location']).must_equal 'http://www.google.com/' + end + end end end