Modiy HTTP::Params.[] to fetch all params (#328)

This commit is contained in:
Serdar Dogruyol 2017-03-13 16:52:42 +02:00 committed by GitHub
parent d0c034b911
commit 1177619da9
3 changed files with 88 additions and 98 deletions

View file

@ -2,101 +2,98 @@ require "./spec_helper"
describe "ParamParser" do
it "parses query params" do
route = Route.new "POST", "/" do |env|
hasan = env.params.query["hasan"]
"Hello #{hasan}"
end
request = HTTP::Request.new("POST", "/?hasan=cemal")
query_params = Kemal::ParamParser.new(request).query
query_params["hasan"].should eq "cemal"
end
it "parses multiple values for query params" do
route = Route.new "POST", "/" do |env|
hasan = env.params.query["hasan"]
"Hello #{hasan}"
end
request = HTTP::Request.new("POST", "/?hasan=cemal&hasan=lamec")
query_params = Kemal::ParamParser.new(request).query
query_params.fetch_all("hasan").should eq ["cemal", "lamec"]
end
it "parses url params" do
kemal = Kemal::RouteHandler::INSTANCE
kemal.add_route "POST", "/hello/:hasan" do |env|
"hello #{env.params.url["hasan"]}"
end
request = HTTP::Request.new("POST", "/hello/cemal")
# Radix tree MUST be run to parse url params.
io_with_context = create_request_and_return_io(kemal, request)
url_params = Kemal::ParamParser.new(request).url
url_params["hasan"].should eq "cemal"
end
it "decodes url params" do
kemal = Kemal::RouteHandler::INSTANCE
kemal.add_route "POST", "/hello/:email/:money/:spanish" do |env|
email = env.params.url["email"]
money = env.params.url["money"]
spanish = env.params.url["spanish"]
"Hello, #{email}. You have #{money}. The spanish word of the day is #{spanish}."
end
request = HTTP::Request.new("POST", "/hello/sam%2Bspec%40gmail.com/%2419.99/a%C3%B1o")
# Radix tree MUST be run to parse url params.
io_with_context = create_request_and_return_io(kemal, request)
url_params = Kemal::ParamParser.new(request).url
url_params["email"].should eq "sam+spec@gmail.com"
url_params["money"].should eq "$19.99"
url_params["spanish"].should eq "año"
end
it "parses request body" do
route = Route.new "POST", "/" do |env|
name = env.params.query["name"]
age = env.params.query["age"]
hasan = env.params.body["hasan"]
"Hello #{name} #{hasan} #{age}"
end
request = HTTP::Request.new(
"POST",
"/?hasan=cemal",
body: "name=serdar&age=99",
headers: HTTP::Headers{"Content-Type" => "application/x-www-form-urlencoded"},
)
query_params = Kemal::ParamParser.new(request).query
{"hasan" => "cemal"}.each do |k, v|
query_params[k].should eq(v)
end
body_params = Kemal::ParamParser.new(request).body
{"name" => "serdar", "age" => "99"}.each do |k, v|
body_params[k].should eq(v)
context "#query" do
it "parses multiple values for query params" do
request = HTTP::Request.new("POST", "/?hasan=cemal&hasan=lamec")
query_params = Kemal::ParamParser.new(request).query
query_params["hasan"].should eq ["cemal", "lamec"]
end
end
it "parses multiple values in request body" do
route = Route.new "POST", "/" do |env|
hasan = env.params.body["hasan"]
"Hello #{hasan}"
context "#url" do
it "parses url params" do
kemal = Kemal::RouteHandler::INSTANCE
kemal.add_route "POST", "/hello/:hasan" do |env|
"hello #{env.params.url["hasan"]}"
end
request = HTTP::Request.new("POST", "/hello/cemal")
# Radix tree MUST be run to parse url params.
io_with_context = create_request_and_return_io(kemal, request)
url_params = Kemal::ParamParser.new(request).url
url_params["hasan"].should eq "cemal"
end
request = HTTP::Request.new(
"POST",
"/",
body: "hasan=cemal&hasan=lamec",
headers: HTTP::Headers{"Content-Type" => "application/x-www-form-urlencoded"},
)
body_params = Kemal::ParamParser.new(request).body
body_params.fetch_all("hasan").should eq(["cemal", "lamec"])
it "decodes url params" do
kemal = Kemal::RouteHandler::INSTANCE
kemal.add_route "POST", "/hello/:email/:money/:spanish" do |env|
email = env.params.url["email"]
money = env.params.url["money"]
spanish = env.params.url["spanish"]
"Hello, #{email}. You have #{money}. The spanish word of the day is #{spanish}."
end
request = HTTP::Request.new("POST", "/hello/sam%2Bspec%40gmail.com/%2419.99/a%C3%B1o")
# Radix tree MUST be run to parse url params.
io_with_context = create_request_and_return_io(kemal, request)
url_params = Kemal::ParamParser.new(request).url
url_params["email"].should eq "sam+spec@gmail.com"
url_params["money"].should eq "$19.99"
url_params["spanish"].should eq "año"
end
end
context "when content type is application/json" do
context "#body" do
it "parses request body" do
route = Route.new "POST", "/" { }
request = HTTP::Request.new(
"POST",
"/?hasan=cemal",
body: "name=serdar&age=99",
headers: HTTP::Headers{"Content-Type" => "application/x-www-form-urlencoded"},
)
query_params = Kemal::ParamParser.new(request).query
{"hasan" => "cemal"}.each do |k, v|
query_params[k].should eq(v)
end
body_params = Kemal::ParamParser.new(request).body
{"name" => "serdar", "age" => "99"}.each do |k, v|
body_params[k].should eq(v)
end
end
it "parses multiple values in request body" do
request = HTTP::Request.new(
"POST",
"/",
body: "hasan=cemal&hasan=lamec",
headers: HTTP::Headers{"Content-Type" => "application/x-www-form-urlencoded"},
)
body_params = Kemal::ParamParser.new(request).body
body_params["hasan"].should eq(["cemal", "lamec"])
end
it "parses array values in request body" do
request = HTTP::Request.new(
"POST",
"/",
body: "framework=kemal&feats[]=fast&feats[]=effective&feats[]=simple",
headers: HTTP::Headers{"Content-Type" => "application/x-www-form-urlencoded"},
)
body_params = Kemal::ParamParser.new(request).body
body_params["framework"].should eq("kemal")
body_params["feats[]"].should eq(["fast", "effective", "simple"])
end
end
context "#json" do
it "parses request body" do
request = HTTP::Request.new(
"POST",
"/",
@ -109,8 +106,6 @@ describe "ParamParser" do
end
it "parses request body when passed charset" do
route = Route.new "POST", "/" { }
request = HTTP::Request.new(
"POST",
"/",
@ -123,8 +118,6 @@ describe "ParamParser" do
end
it "parses request body for array" do
route = Route.new "POST", "/" { }
request = HTTP::Request.new(
"POST",
"/",
@ -137,8 +130,6 @@ describe "ParamParser" do
end
it "parses request body and query params" do
route = Route.new "POST", "/" { }
request = HTTP::Request.new(
"POST",
"/?foo=bar",
@ -156,8 +147,6 @@ describe "ParamParser" do
end
it "handles no request body" do
route = Route.new "GET", "/" { }
request = HTTP::Request.new(
"GET",
"/",
@ -180,13 +169,6 @@ describe "ParamParser" do
context "when content type is incorrect" do
it "does not parse request body" do
route = Route.new "POST", "/" do |env|
name = env.params.body["name"]
age = env.params.body["age"]
hasan = env.params.query["hasan"]
"Hello #{name} #{hasan} #{age}"
end
request = HTTP::Request.new(
"POST",
"/?hasan=cemal",

8
src/kemal/ext/params.cr Normal file
View file

@ -0,0 +1,8 @@
module HTTP
struct Params
def [](name)
params = raw_params[name]
params.size == 1 ? params.first : params
end
end
end

View file

@ -1,5 +1,5 @@
class HTTP::Request
property override_method
property override_method : String?
property url_params : Hash(String, String)?
getter param_parser : Kemal::ParamParser?
@ -21,7 +21,7 @@ class HTTP::Request
@param_parser = Kemal::ParamParser.new(self)
params = @param_parser.not_nil!.body
if params.has_key?("_method") && HTTP::Request.override_method_valid?(params["_method"])
@override_method = params["_method"]
@override_method = params["_method"].as(String)
end
end
@override_method