diff options
author | danielsdeleo <dan@opscode.com> | 2013-11-26 11:58:12 -0800 |
---|---|---|
committer | danielsdeleo <dan@opscode.com> | 2013-11-26 12:29:23 -0800 |
commit | 168d2102fb11c9617cd8a981166c8adc30a6e915 (patch) | |
tree | b9c2be671289d327a50b5ee9b02d21bcf75a6c90 | |
parent | 73e39236edec704079383cb93914887acf65f0e2 (diff) | |
download | chef-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.rb | 7 | ||||
-rw-r--r-- | spec/unit/rest/auth_credentials_spec.rb | 5 | ||||
-rw-r--r-- | spec/unit/rest_spec.rb | 15 |
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 |