diff --git a/lib/majic/plug.ex b/lib/majic/plug.ex index 5d647c9..311d20b 100644 --- a/lib/majic/plug.ex +++ b/lib/majic/plug.ex @@ -42,12 +42,9 @@ if Code.ensure_loaded?(Plug) do true -> raise(Majic.PlugError, "No server/pool/once option defined") end - opts = - opts - |> Keyword.put_new(:fix_extension, true) - |> Keyword.put_new(:append_extension, false) - opts + |> Keyword.put_new(:fix_extension, true) + |> Keyword.put_new(:append_extension, false) end @impl Plug @@ -55,6 +52,15 @@ if Code.ensure_loaded?(Plug) do collected = collect_uploads([], conn.body_params, []) Enum.reduce(collected, conn, fn {param_path, upload}, conn -> + {array_index, param_path} = + case param_path do + [index, :array | path] -> + {index, path} + + path -> + {nil, path} + end + param_path = Enum.reverse(param_path) upload = @@ -63,14 +69,9 @@ if Code.ensure_loaded?(Plug) do {:error, error} -> raise(Majic.PlugError, "Failed to majic: #{inspect(error)}") end - conn = - if get_in(conn.params, param_path) do - %{conn | params: put_in(conn.params, param_path, upload)} - end - - if get_in(conn.body_params, param_path) do - %{conn | body_params: put_in(conn.body_params, param_path, upload)} - end + conn + |> put_in_if_exists(:params, param_path, upload, array_index) + |> put_in_if_exists(:body_params, param_path, upload, array_index) end) end @@ -93,6 +94,12 @@ if Code.ensure_loaded?(Plug) do collect_uploads([k | path], v, acc) end + defp collect_upload(path, {k, v}, acc) when is_list(v) do + Enum.reduce(Enum.with_index(v), acc, fn {item, index}, acc -> + collect_upload([:array, k | path], {index, item}, acc) + end) + end + defp collect_upload(_path, _, acc) do acc end @@ -164,5 +171,24 @@ if Code.ensure_loaded?(Plug) do defp rewrite_or_append_extension(basename, _, ext, _) do basename <> "." <> ext end + + # put value at path in conn. + defp put_in_if_exists(conn, key, path, value, nil) do + if get_in(Map.get(conn, key), path) do + Map.put(conn, key, put_in(Map.get(conn, key), path, value)) + else + conn + end + end + + # change value at index in list at path in conn. + defp put_in_if_exists(conn, key, path, value, index) do + if array = get_in(Map.get(conn, key), path) do + array = List.replace_at(array, index, value) + Map.put(conn, key, put_in(Map.get(conn, key), path, array)) + else + conn + end + end end end diff --git a/test/majic/plug_test.exs b/test/majic/plug_test.exs index 2e9638b..c0187cc 100644 --- a/test/majic/plug_test.exs +++ b/test/majic/plug_test.exs @@ -44,6 +44,16 @@ defmodule Majic.PlugTest do Content-Type: image/jpg\r \r #{String.replace(File.read!("test/fixtures/cat.webp"), "\n", "\n")}\r + ------w58EW1cEpjzydSCq\r + Content-Disposition: form-data; name=\"cats[]\"; filename*=\"utf-8''first-cute-cat.jpg\"\r + Content-Type: image/jpg\r + \r + #{String.replace(File.read!("test/fixtures/cat.webp"), "\n", "\n")}\r + ------w58EW1cEpjzydSCq\r + Content-Disposition: form-data; name=\"cats[]\"; filename*=\"utf-8''second-cute-cat.jpg\"\r + Content-Type: image/jpg\r + \r + #{String.replace(File.read!("test/fixtures/cat.webp"), "\n", "\n")}\r ------w58EW1cEpjzydSCq--\r """ @@ -81,5 +91,7 @@ defmodule Majic.PlugTest do assert get_in(conn.params, ["cat"]).filename == "cute-cat.webp" assert get_in(conn_no_ext.params, ["cat"]).filename == "cute-cat.jpg" assert get_in(conn_append_ext.params, ["cat"]).filename == "cute-cat.jpg.webp" + + assert Enum.all?(conn.params["cats"], fn upload -> upload.content_type == "image/webp" end) end end