Skip to content

Commit

Permalink
return 400 bad request when failed parse as json (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
sawanoboly authored and mpalmer committed Aug 29, 2017
1 parent 1b9e47b commit 624bf9b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
5 changes: 5 additions & 0 deletions lib/rack/contrib/post_body_content_type_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ def call(env)
env.update(FORM_HASH => JSON.parse(body, :create_additions => false), FORM_INPUT => env[POST_BODY])
end
@app.call(env)
rescue JSON::ParserError
bad_request('failed to parse body as JSON')
end

def bad_request(body = 'Bad Request')
[ 400, { 'Content-Type' => 'text/plain', 'Content-Length' => body.size.to_s }, [body] ]
end
end
end
21 changes: 19 additions & 2 deletions test/spec_rack_post_body_content_type_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
params = params_for_request '{"key":"value"}', "application/json; charset=utf-8"
params['key'].must_equal "value"
end

specify "should parse 'application/json' requests with empty body" do
params = params_for_request "", "application/json"
params.must_equal({})
Expand All @@ -33,14 +33,31 @@
result.must_be_empty
end

describe "contradiction between body and type" do
def assert_failed_to_parse_as_json(response)
response.wont_equal nil
status, headers, body = response
status.must_equal 400
body.must_equal ["failed to parse body as JSON"]
end

specify "should return bad request with invalid JSON" do
test_body = '"bar":"foo"}'
env = Rack::MockRequest.env_for "/", {:method => "POST", :input => test_body, "CONTENT_TYPE" => 'application/json'}
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, Rack::Request.new(env).POST] }
response = Rack::PostBodyContentTypeParser.new(app).call(env)

assert_failed_to_parse_as_json(response)
end
end
end

def params_for_request(body, content_type)
env = Rack::MockRequest.env_for "/", {:method => "POST", :input => body, "CONTENT_TYPE" => content_type}
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, Rack::Request.new(env).POST] }
Rack::PostBodyContentTypeParser.new(app).call(env).last
end

rescue LoadError => e
# Missing dependency JSON, skipping tests.
STDERR.puts "WARN: Skipping Rack::PostBodyContentTypeParser tests (json not installed)"
Expand Down

0 comments on commit 624bf9b

Please sign in to comment.