mirror of
https://gitea.invidious.io/iv-org/shard-kemal.git
synced 2024-08-15 00:53:36 +00:00
Merge pull request #465 from kemalcr/rework-param-parser
Rework param parser
This commit is contained in:
commit
64fbe406d5
13 changed files with 67 additions and 183 deletions
|
@ -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?
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue