mirror of
				https://gitea.invidious.io/iv-org/shard-kemal.git
				synced 2024-08-15 00:53:36 +00:00 
			
		
		
		
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue