diff --git a/lib/committee/request_unpacker.rb b/lib/committee/request_unpacker.rb index bbb4337b..25ffea6b 100644 --- a/lib/committee/request_unpacker.rb +++ b/lib/committee/request_unpacker.rb @@ -78,11 +78,12 @@ def parse_json(request) return nil if request.request_method == "GET" && !@allow_get_body return nil if request.body.nil? + rewind_body(request.body) body = request.body.read # if request body is empty, we just have empty params return nil if body.length == 0 - request.body.rewind + rewind_body(request.body) hash = JSON.parse(body) # We want a hash specifically. '42', 42, and [42] will all be # decoded properly, but we can't use them here. @@ -91,5 +92,9 @@ def parse_json(request) end self.class.indifferent_params(hash) end + + def rewind_body(body) + body.rewind if body.respond_to?(:rewind) + end end end diff --git a/test/request_unpacker_test.rb b/test/request_unpacker_test.rb index a70862d5..71c3761d 100644 --- a/test/request_unpacker_test.rb +++ b/test/request_unpacker_test.rb @@ -10,6 +10,14 @@ assert_equal([{ "x" => "y" }, false], unpacker.unpack_request_params(request)) end + it "unpacks JSON on Content-Type: application/json if the body was not rewound first" do + env = { "CONTENT_TYPE" => "application/json", "rack.input" => StringIO.new('{"x":"y"}'), } + request = Rack::Request.new(env) + request.body.read + unpacker = Committee::RequestUnpacker.new + assert_equal([{ "x" => "y" }, false], unpacker.unpack_request_params(request)) + end + it "unpacks JSON on Content-Type: application/vnd.api+json" do env = { "CONTENT_TYPE" => "application/vnd.api+json", "rack.input" => StringIO.new('{"x":"y"}'), } request = Rack::Request.new(env)