summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanielsdeleo <dan@opscode.com>2013-12-04 15:19:41 -0800
committerdanielsdeleo <dan@opscode.com>2013-12-04 15:24:35 -0800
commit9db2c80b98f3a5d807a205d6966cb9c1818714d1 (patch)
tree239e21f701325b79edcce3d2b383c808a3dffcb1
parent8a1a44bfebe0482348a20eeb577be24ead39a066 (diff)
downloadchef-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.rb6
-rw-r--r--chef/spec/unit/rest_spec.rb15
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"}')