diff --git a/spec/param_parser_spec.cr b/spec/param_parser_spec.cr index 0f9db64..805db8d 100644 --- a/spec/param_parser_spec.cr +++ b/spec/param_parser_spec.cr @@ -18,8 +18,36 @@ describe "ParamParser" do hasan = env.params["hasan"] "Hello #{name} #{hasan} #{age}" end - request = HTTP::Request.new("POST", "/?hasan=cemal", body: "name=serdar&age=99") + + request = HTTP::Request.new( + "POST", + "/?hasan=cemal", + body: "name=serdar&age=99", + headers: HTTP::Headers{"Content-Type": "application/x-www-form-urlencoded"}, + ) + params = Kemal::ParamParser.new(route, request).parse params.should eq({"hasan" => "cemal", "name" => "serdar", "age" => "99"}) end + + context "when content type is incorrect" do + it "does not parse request body" do + route = Route.new "POST", "/" do |env| + name = env.params["name"] + age = env.params["age"] + hasan = env.params["hasan"] + "Hello #{name} #{hasan} #{age}" + end + + request = HTTP::Request.new( + "POST", + "/?hasan=cemal", + body: "name=serdar&age=99", + headers: HTTP::Headers{"Content-Type": "text/plain"}, + ) + + params = Kemal::ParamParser.new(route, request).parse + params.should eq({"hasan" => "cemal"}) + end + end end diff --git a/src/kemal/param_parser.cr b/src/kemal/param_parser.cr index 87b2181..2735e4c 100644 --- a/src/kemal/param_parser.cr +++ b/src/kemal/param_parser.cr @@ -2,6 +2,8 @@ # and converts them into a params hash which you can within the environment # context. class Kemal::ParamParser + URL_ENCODED_FORM = "application/x-www-form-urlencoded" + def initialize(@route, @request) @route_components = route.components @request_components = request.path.not_nil!.split "/" @@ -14,16 +16,27 @@ class Kemal::ParamParser end def parse_request - {% for part in %w(query body) %} - if {{part.id}} = @request.{{part.id}} - HTTP::Params.parse({{part.id}}) do |key, value| - @params[key] ||= value - end - end - {% end %} + parse_query + parse_body @params end + def parse_body + return unless @request.headers["Content-Type"]? == URL_ENCODED_FORM + parse_part(@request.body) + end + + def parse_query + parse_part(@request.query) + end + + def parse_part(part) + return unless part + HTTP::Params.parse(part) do |key, value| + @params[key] ||= value + end + end + def parse_components @route_components.zip(@request_components) do |route_component, req_component| if route_component.starts_with? ':'