Added param parser

This commit is contained in:
Sdogruyol 2015-10-28 20:30:27 +02:00
parent a8ad95aa67
commit 3cc50e0a7e
8 changed files with 72 additions and 52 deletions

View file

@ -50,17 +50,4 @@ describe "Kemal::Handler" do
response = kemal.call(request)
response.headers["Content-Type"].should eq("application/json")
end
it "parses POST body" do
kemal = Kemal::Handler.new
kemal.add_route "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=kemal&age=99")
response = kemal.call(request)
response.body.should eq("Hello kemal cemal 99")
end
end

View file

@ -1,13 +1,11 @@
require "./spec_helper"
describe "Logger" do
it "logs stuff" do
IO.pipe do |r,w|
IO.pipe do |r, w|
logger = Kemal::Logger.new(w)
logger.info "Info from logger"
r.gets.should match(/Info from logger/)
end
end
end

16
spec/param_parser_spec.cr Normal file
View file

@ -0,0 +1,16 @@
require "./spec_helper"
describe "ParamParser" do
it "parses params" do
kemal = Kemal::Handler.new
kemal.add_route "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=kemal&age=99")
response = kemal.call(request)
response.body.should eq("Hello kemal cemal 99")
end
end

View file

@ -4,18 +4,21 @@ describe "Route" do
describe "match" do
it "doesn't match because of route" do
route = Route.new("GET", "/foo/bar") { "" }
route.match("GET", "/foo/baz".split("/")).should be_nil
request = HTTP::Request.new("GET", "/world?message=coco")
route.match?(request).should be_nil
end
it "doesn't match because of method" do
route = Route.new("GET", "/foo/bar") { "" }
route.match("POST", "/foo/bar".split("/")).should be_nil
request = HTTP::Request.new("POST", "/foo/bar")
route.match?(request).should be_nil
end
it "matches" do
route = Route.new("GET", "/foo/:one/path/:two") { "" }
params = route.match("GET", "/foo/uno/path/dos".split("/"))
params.should eq({"one" => "uno", "two" => "dos"})
request = HTTP::Request.new("GET", "/foo/uno/path/dos")
match = route.match?(request)
match.should eq true
end
end
end

View file

@ -20,21 +20,10 @@ class Kemal::Handler < HTTP::Handler
def exec_request(request)
components = request.path.not_nil!.split "/"
@routes.each do |route|
params = route.match(request.method, components)
if params
if query = request.query
HTTP::Params.parse(query) do |key, value|
params[key] ||= value
end
end
if body = request.body
HTTP::Params.parse(request.body.not_nil!) do |key, value|
params[key] ||= value
end
end
context = Context.new(request, params)
match = route.match?(request)
if match
params = Kemal::Params.new(route, request).parse
context = Context.new(request, params.not_nil!)
begin
body = route.handler.call(context).to_s
content_type = context.response?.try(&.content_type) || "text/plain"

View file

@ -1,5 +1,6 @@
class Kemal::Logger
LOG_LEVELS = %w(info debug error warn)
def initialize(@stream)
end

37
src/kemal/param_parser.cr Normal file
View file

@ -0,0 +1,37 @@
class Kemal::Params
def initialize(@route, @request)
@route_components = route.components
@request_components = request.path.not_nil!.split "/"
@params = {} of String => String
end
def parse
parse_components
parse_request
end
def parse_request
if query = @request.query
HTTP::Params.parse(query) do |key, value|
@params[key] ||= value
end
end
if body = @request.body
HTTP::Params.parse(body.not_nil!) do |key, value|
@params[key] ||= value
end
end
@params
end
def parse_components
@route_components.zip(@request_components) do |route_component, req_component|
if route_component.starts_with? ':'
@params[route_component[1..-1]] = req_component
else
return nil unless route_component == req_component
end
end
end
end

View file

@ -1,26 +1,15 @@
class Kemal::Route
getter handler
getter components
def initialize(@method, path, &@handler : Kemal::Context -> _)
@components = path.split "/"
end
def match(method, components)
return nil unless method == @method
def match?(request)
components = request.path.not_nil!.split "/"
return nil unless request.method == @method
return nil unless components.size == @components.size
params = nil
@components.zip(components) do |route_component, req_component|
if route_component.starts_with? ':'
params ||= {} of String => String
params[route_component[1..-1]] = req_component
else
return nil unless route_component == req_component
end
end
params ||= {} of String => String
params
true
end
end