summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanielsdeleo <dan@opscode.com>2013-11-26 11:58:12 -0800
committerdanielsdeleo <dan@opscode.com>2013-11-26 12:29:23 -0800
commit168d2102fb11c9617cd8a981166c8adc30a6e915 (patch)
treeb9c2be671289d327a50b5ee9b02d21bcf75a6c90
parent73e39236edec704079383cb93914887acf65f0e2 (diff)
downloadchef-168d2102fb11c9617cd8a981166c8adc30a6e915.tar.gz
Always set a correct Host header to avoid net/http bug
Net::HTTP fails to surround IPv6 addresses in brackets when constructing a Host header. Net::HTTP respects any user-supplied Host header, so we ensure that the Host header is correctly formatted by setting it manually for all requests.
-rw-r--r--lib/chef/http/http_request.rb7
-rw-r--r--spec/unit/rest/auth_credentials_spec.rb5
-rw-r--r--spec/unit/rest_spec.rb15
3 files changed, 23 insertions, 4 deletions
diff --git a/lib/chef/http/http_request.rb b/lib/chef/http/http_request.rb
index e0ec2233b9..90b805e73f 100644
--- a/lib/chef/http/http_request.rb
+++ b/lib/chef/http/http_request.rb
@@ -58,6 +58,8 @@ class Chef
SLASH = "/".freeze
+ HOST_LOWER = "host".freeze
+
def self.user_agent=(ua)
@user_agent = ua
end
@@ -79,6 +81,10 @@ class Chef
@url.hostname
end
+ def uri_safe_host
+ @url.host
+ end
+
def port
@url.port
end
@@ -132,6 +138,7 @@ class Chef
# No response compression unless we asked for it explicitly:
@headers[HTTPRequest::ACCEPT_ENCODING] ||= "identity"
@headers['X-Chef-Version'] = ::Chef::VERSION
+ @headers['Host'] = "#{uri_safe_host}:#{port}" unless @headers.keys.any? {|k| k.downcase.to_s == HOST_LOWER }
@headers
end
diff --git a/spec/unit/rest/auth_credentials_spec.rb b/spec/unit/rest/auth_credentials_spec.rb
index 7aa68deab4..2c84c1e1bb 100644
--- a/spec/unit/rest/auth_credentials_spec.rb
+++ b/spec/unit/rest/auth_credentials_spec.rb
@@ -135,7 +135,10 @@ describe Chef::REST::RESTRequest do
@auth_credentials = Chef::REST::AuthCredentials.new("client-name", CHEF_SPEC_DATA + '/ssl/private_key.pem')
@url = URI.parse("http://chef.example.com:4000/?q=chef_is_awesome")
@req_body = '{"json_data":"as_a_string"}'
- @headers = {"Content-type" =>"application/json", "Accept"=>"application/json", "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
+ @headers = { "Content-type" =>"application/json",
+ "Accept"=>"application/json",
+ "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ "Host" => "chef.example.com:4000" }
@request = Chef::REST::RESTRequest.new(:POST, @url, @req_body, @headers)
end
diff --git a/spec/unit/rest_spec.rb b/spec/unit/rest_spec.rb
index 0281bd22ec..23279eddb7 100644
--- a/spec/unit/rest_spec.rb
+++ b/spec/unit/rest_spec.rb
@@ -212,6 +212,8 @@ describe Chef::REST do
Chef::Config[:ssl_client_key] = nil
@url = URI.parse("https://one:80/?foo=bar")
+ @host_header = "one:80"
+
@http_response = Net::HTTPSuccess.new("1.1", "200", "successful rest req")
@http_response.stub(:read_body)
@http_response.stub(:body).and_return("ninja")
@@ -240,7 +242,10 @@ describe Chef::REST do
end
it "should build a new HTTP GET request without the application/json accept header" do
- expected_headers = {'Accept' => "*/*", 'X-Chef-Version' => Chef::VERSION, 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
+ expected_headers = {'Accept' => "*/*",
+ 'X-Chef-Version' => Chef::VERSION,
+ 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ 'Host' => @host_header}
Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
@rest.streaming_request(@url, {})
end
@@ -286,7 +291,8 @@ describe Chef::REST do
@base_headers = {"Accept" => "application/json",
"X-Chef-Version" => Chef::VERSION,
- "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE
+ "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ "Host" => @host_header
}
end
@@ -485,7 +491,10 @@ describe Chef::REST do
end
it " build a new HTTP GET request without the application/json accept header" do
- expected_headers = {'Accept' => "*/*", 'X-Chef-Version' => Chef::VERSION, 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
+ expected_headers = {'Accept' => "*/*",
+ 'X-Chef-Version' => Chef::VERSION,
+ 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ 'Host' => @host_header}
Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
@rest.streaming_request(@url, {})
end