From bd69f8be1ca98c084ad329dbbdf0b3ad7ecd398d Mon Sep 17 00:00:00 2001 From: matthewmcgarvey Date: Thu, 27 Jan 2022 00:12:02 -0600 Subject: [PATCH] Pass in if form is multipart It's possible to have a multipart form and not have or supply a file field. Avram bombed because it looks for a file and then raises an error because the form was not multipart encoded --- src/webless/request_builder.cr | 4 ++-- src/webless/request_builder/form_handler.cr | 15 +++++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/webless/request_builder.cr b/src/webless/request_builder.cr index 51fd788..cc197e5 100644 --- a/src/webless/request_builder.cr +++ b/src/webless/request_builder.cr @@ -52,8 +52,8 @@ class Webless::RequestBuilder clone.tap(&.params[key] = value) end - def form(form : Hash(String, _) | NamedTuple) : RequestBuilder - result = FormHandler.handle(form) + def form(form : Hash(String, _) | NamedTuple, multipart : Bool = false) : RequestBuilder + result = FormHandler.handle(form, multipart) body(result[:body]).content_type(result[:content_type]) end diff --git a/src/webless/request_builder/form_handler.cr b/src/webless/request_builder/form_handler.cr index bccfd36..66aebc9 100644 --- a/src/webless/request_builder/form_handler.cr +++ b/src/webless/request_builder/form_handler.cr @@ -1,8 +1,8 @@ class Webless::RequestBuilder::FormHandler alias FormType = Symbol | String | Int32 | Int64 | Float64 | Bool | File | Array(FormType) | Hash(String, FormType) - def self.handle(form : Hash(String, _) | NamedTuple) : NamedTuple(body: String, content_type: String) - new(cast(form).as(Hash(String, FormType))).handle + def self.handle(form : Hash(String, _) | NamedTuple, multipart : Bool) : NamedTuple(body: String, content_type: String) + new(cast(form).as(Hash(String, FormType)), multipart).handle end private def self.cast(raw : Array) : FormType @@ -28,12 +28,13 @@ class Webless::RequestBuilder::FormHandler end @form : Hash(String, FormType) + @multipart : Bool - def initialize(@form) + def initialize(@form, @multipart) end def handle : NamedTuple(body: String, content_type: String) - if multipart? + if @multipart io = IO::Memory.new builder = HTTP::FormData::Builder.new(io) @form.each { |k, v| apply_multipart(builder, k, v) } @@ -46,12 +47,6 @@ class Webless::RequestBuilder::FormHandler end end - private def multipart? : Bool - @form.any? do |_, v| - v.is_a?(File) || (v.is_a?(Array) && v.any?(File)) - end - end - private def apply_multipart(builder : HTTP::FormData::Builder, k : String, v : FormType) if v.is_a?(File) builder.file(k, v.as(IO), HTTP::FormData::FileMetadata.new(filename: File.basename(v.path)))