diff options
author | danielsdeleo <dan@opscode.com> | 2013-12-04 15:19:41 -0800 |
---|---|---|
committer | danielsdeleo <dan@opscode.com> | 2013-12-04 15:24:35 -0800 |
commit | 9db2c80b98f3a5d807a205d6966cb9c1818714d1 (patch) | |
tree | 239e21f701325b79edcce3d2b383c808a3dffcb1 | |
parent | 8a1a44bfebe0482348a20eeb577be24ead39a066 (diff) | |
download | chef-9db2c80b98f3a5d807a205d6966cb9c1818714d1.tar.gz |
Do not attempt to JSON parse the body of a 204 response.
An HTTP 204 No Content response may have a Content-Type header even
though it has no content--this is not disallowed by the RFC. Update
Chef::REST to handle this case and not attempt to parse the (nil)
response.
-rw-r--r-- | chef/lib/chef/rest.rb | 6 | ||||
-rw-r--r-- | chef/spec/unit/rest_spec.rb | 15 |
2 files changed, 20 insertions, 1 deletions
diff --git a/chef/lib/chef/rest.rb b/chef/lib/chef/rest.rb index 48ef218e87..14bff6a304 100644 --- a/chef/lib/chef/rest.rb +++ b/chef/lib/chef/rest.rb @@ -267,7 +267,11 @@ class Chef response_body = decompress_body(response) - if response.kind_of?(Net::HTTPSuccess) + # 204 is successful, Net::HTTP returns nil response body. + # Don't attempt to parse it. + if response.kind_of?(Net::HTTPNoContent) + response_body + elsif response.kind_of?(Net::HTTPSuccess) if response['content-type'] =~ /json/ Chef::JSONCompat.from_json(response_body.chomp) else diff --git a/chef/spec/unit/rest_spec.rb b/chef/spec/unit/rest_spec.rb index f24ef1a08d..c3385df2c0 100644 --- a/chef/spec/unit/rest_spec.rb +++ b/chef/spec/unit/rest_spec.rb @@ -422,6 +422,21 @@ describe Chef::REST do @rest.api_request(:GET, @url).should == "ninja" end + it "returns nil when the response is a 204 and the content-type is JSON" do + + @http_response = Net::HTTPNoContent.new("1.1", "204", "successful rest req") + @http_response.stub!(:read_body) + @http_response.stub!(:body).and_return(nil) + @http_response.add_field("Content-Length", "0") + @http_response.add_field("Content-Type", "application/json") + + @http_client = Net::HTTP.new(@url.host, @url.port) + Net::HTTP.stub!(:new).and_return(@http_client) + @http_client.stub!(:request).and_yield(@http_response).and_return(@http_response) + + @rest.api_request(:GET, @url).should be_nil + end + it "should inflate the body as to an object if JSON is returned" do @http_response.add_field('content-type', "application/json") @http_response.stub!(:body).and_return('{"ohai2u":"json_api"}') |