Merge pull request #465 from kemalcr/rework-param-parser

Rework param parser
This commit is contained in:
Serdar Dogruyol 2018-08-06 20:03:12 +03:00 committed by GitHub
commit 64fbe406d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 67 additions and 183 deletions

View file

@ -14,12 +14,7 @@ class HTTP::Server
end
def params
@request.url_params ||= route_lookup.params
@params ||= if @request.param_parser
@request.param_parser.not_nil!
else
Kemal::ParamParser.new(@request)
end
@params ||= Kemal::ParamParser.new(@request, route_lookup.params)
end
def redirect(url : String, status_code : Int32 = 302)
@ -36,7 +31,7 @@ class HTTP::Server
end
def route_lookup
Kemal::RouteHandler::INSTANCE.lookup_route(@request.override_method.as(String), @request.path)
Kemal::RouteHandler::INSTANCE.lookup_route(@request.method.as(String), @request.path)
end
def route_defined?

View file

@ -1,32 +0,0 @@
class HTTP::Request
property override_method
property url_params : Hash(String, String)?
getter param_parser : Kemal::ParamParser?
def override_method
@override_method ||= check_for_method_override!
end
def content_type
@headers["Content-Type"]?
end
# Checks if method contained in _method param is valid one
def self.override_method_valid?(override_method : String)
override_method = override_method.upcase
override_method == "PUT" || override_method == "PATCH" || override_method == "DELETE"
end
# Checks if request params contain _method param to override request incoming method
private def check_for_method_override!
@override_method = @method
if @method == "POST"
@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"]
end
end
@override_method
end
end

View file

@ -1,25 +0,0 @@
module Kemal
# :nodoc:
struct FileUpload
getter tmpfile : Tempfile
getter filename : String?
getter headers : HTTP::Headers
getter creation_time : Time?
getter modification_time : Time?
getter read_time : Time?
getter size : UInt64?
def initialize(upload)
@tmpfile = Tempfile.new(filename)
::File.open(@tmpfile.path, "w") do |file|
IO.copy(upload.body, file)
end
@filename = upload.filename
@headers = upload.headers
@creation_time = upload.creation_time
@modification_time = upload.modification_time
@read_time = upload.read_time
@size = upload.size
end
end
end

View file

@ -14,12 +14,12 @@ module Kemal
def call(context : HTTP::Server::Context)
return call_next(context) unless context.route_defined?
call_block_for_path_type("ALL", context.request.path, :before, context)
call_block_for_path_type(context.request.override_method, context.request.path, :before, context)
call_block_for_path_type(context.request.method, context.request.path, :before, context)
if Kemal.config.error_handlers.has_key?(context.response.status_code)
raise Kemal::Exceptions::CustomException.new(context)
end
call_next(context)
call_block_for_path_type(context.request.override_method, context.request.path, :after, context)
call_block_for_path_type(context.request.method, context.request.path, :after, context)
call_block_for_path_type("ALL", context.request.path, :after, context)
context
end

View file

@ -8,7 +8,7 @@ module Kemal::Exceptions
class RouteNotFound < Exception
def initialize(context : HTTP::Server::Context)
super "Requested path: '#{context.request.override_method}:#{context.request.path}' was not found."
super "Requested path: '#{context.request.method}:#{context.request.path}' was not found."
end
end

View file

@ -9,14 +9,11 @@ module Kemal
PARTS = %w(url query body json)
# :nodoc:
alias AllParamTypes = Nil | String | Int64 | Float64 | Bool | Hash(String, JSON::Any) | Array(JSON::Any)
getter files
def initialize(@request : HTTP::Request)
@url = {} of String => String
def initialize(@request : HTTP::Request, @url : Hash(String, String) = {} of String => String)
@query = HTTP::Params.new({} of String => Array(String))
@body = HTTP::Params.new({} of String => Array(String))
@json = {} of String => AllParamTypes
@files = [] of FileUpload
@url_parsed = false
@query_parsed = false
@body_parsed = false
@ -42,16 +39,12 @@ module Kemal
{% end %}
private def parse_body
content_type = @request.content_type
content_type = @request.headers["Content-Type"]?
return unless content_type
if content_type.try(&.starts_with?(URL_ENCODED_FORM))
@body = parse_part(@request.body)
return
end
if content_type.try(&.starts_with?(MULTIPART_FORM))
parse_file_upload
return
end
end
private def parse_query
@ -59,23 +52,7 @@ module Kemal
end
private def parse_url
if params = @request.url_params
params.each do |key, value|
@url[key] = unescape_url_param(value)
end
end
end
private def parse_file_upload
HTTP::FormData.parse(@request) do |upload|
next unless upload
filename = upload.filename
if !filename.nil?
@files << FileUpload.new(upload: upload)
else
@body.add(upload.name, upload.body.gets_to_end)
end
end
@url.each { |key, value| @url[key] = unescape_url_param(value) }
end
# Parses JSON request body if Content-Type is `application/json`.

View file

@ -11,7 +11,6 @@ module Kemal
def call(context : HTTP::Server::Context)
return call_next(context) unless context.ws_route_defined? && websocket_upgrade_request?(context)
context.request.url_params ||= context.ws_route_lookup.params
content = context.websocket.call(context)
context.response.print(content)
context