Fix multipart upload and back params.files (#499)
This commit is contained in:
parent
207f38251a
commit
7358994e91
2 changed files with 51 additions and 0 deletions
24
src/kemal/file_upload.cr
Normal file
24
src/kemal/file_upload.cr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module Kemal
|
||||||
|
struct FileUpload
|
||||||
|
getter tempfile : File
|
||||||
|
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)
|
||||||
|
@tempfile = File.tempfile
|
||||||
|
::File.open(@tempfile.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
|
|
@ -9,15 +9,18 @@ module Kemal
|
||||||
PARTS = %w(url query body json)
|
PARTS = %w(url query body json)
|
||||||
# :nodoc:
|
# :nodoc:
|
||||||
alias AllParamTypes = Nil | String | Int64 | Float64 | Bool | Hash(String, JSON::Any) | Array(JSON::Any)
|
alias AllParamTypes = Nil | String | Int64 | Float64 | Bool | Hash(String, JSON::Any) | Array(JSON::Any)
|
||||||
|
getter files
|
||||||
|
|
||||||
def initialize(@request : HTTP::Request, @url : Hash(String, String) = {} of String => String)
|
def initialize(@request : HTTP::Request, @url : Hash(String, String) = {} of String => String)
|
||||||
@query = HTTP::Params.new({} of String => Array(String))
|
@query = HTTP::Params.new({} of String => Array(String))
|
||||||
@body = HTTP::Params.new({} of String => Array(String))
|
@body = HTTP::Params.new({} of String => Array(String))
|
||||||
@json = {} of String => AllParamTypes
|
@json = {} of String => AllParamTypes
|
||||||
|
@files = {} of String => FileUpload
|
||||||
@url_parsed = false
|
@url_parsed = false
|
||||||
@query_parsed = false
|
@query_parsed = false
|
||||||
@body_parsed = false
|
@body_parsed = false
|
||||||
@json_parsed = false
|
@json_parsed = false
|
||||||
|
@files_parsed = false
|
||||||
end
|
end
|
||||||
|
|
||||||
private def unescape_url_param(value : String)
|
private def unescape_url_param(value : String)
|
||||||
|
@ -40,11 +43,17 @@ module Kemal
|
||||||
|
|
||||||
private def parse_body
|
private def parse_body
|
||||||
content_type = @request.headers["Content-Type"]?
|
content_type = @request.headers["Content-Type"]?
|
||||||
|
|
||||||
return unless content_type
|
return unless content_type
|
||||||
|
|
||||||
if content_type.try(&.starts_with?(URL_ENCODED_FORM))
|
if content_type.try(&.starts_with?(URL_ENCODED_FORM))
|
||||||
@body = parse_part(@request.body)
|
@body = parse_part(@request.body)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if content_type.try(&.starts_with?(MULTIPART_FORM))
|
||||||
|
parse_files
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private def parse_query
|
private def parse_query
|
||||||
|
@ -55,6 +64,24 @@ module Kemal
|
||||||
@url.each { |key, value| @url[key] = unescape_url_param(value) }
|
@url.each { |key, value| @url[key] = unescape_url_param(value) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private def parse_files
|
||||||
|
return if @files_parsed
|
||||||
|
|
||||||
|
HTTP::FormData.parse(@request) do |upload|
|
||||||
|
next unless upload
|
||||||
|
|
||||||
|
filename = upload.filename
|
||||||
|
|
||||||
|
if !filename.nil?
|
||||||
|
@files[upload.name] = FileUpload.new(upload)
|
||||||
|
else
|
||||||
|
@body.add(upload.name, upload.body.gets_to_end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@files_parsed = true
|
||||||
|
end
|
||||||
|
|
||||||
# Parses JSON request body if Content-Type is `application/json`.
|
# Parses JSON request body if Content-Type is `application/json`.
|
||||||
#
|
#
|
||||||
# - If request body is a JSON `Hash` then all the params are parsed and added into `params`.
|
# - If request body is a JSON `Hash` then all the params are parsed and added into `params`.
|
||||||
|
|
Loading…
Reference in a new issue