elixir-plug / plug

Compose web applications with functions
https://hex.pm/packages/plug
Other
2.88k stars 587 forks source link

Plug.Conn.Query - decode_init, each,done unknown #1167

Closed ndrean closed 1 year ago

ndrean commented 1 year ago

I am trying to write a parser for multiparts to be able to include several files and any other input passed via a FormData.

I took the example (see below).

I have the warnings "undefined".

warning: Plug.Conn.Query.decode_done/2 is undefined or private. Did you mean:

      * decode/1
      * decode/2
      * decode/3
      * decode/4

  lib/libraries/plug_parsers_my_multipart.ex:39: Plug.Parsers.MY_MULTIPART.multipart_to_params/2

warning: Plug.Conn.Query.decode_each/2 is undefined or private. Did you mean:

      * decode/1
      * decode/2
      * decode/3
      * decode/4
      * decode_pair/2

lib/libraries/plug_parsers_my_multipart.ex:36: Plug.Parsers.MY_MULTIPART.multipart_to_params/2

warning: Plug.Conn.Query.decode_init/0 is undefined or private. Did you mean:

      * decode/1
      * decode/2
      * decode/3
      * decode/4
      * decode_pair/2

  lib/libraries/plug_parsers_my_multipart.ex:35: Plug.Parsers.MY_MULTIPART.multipart_to_params/2
#plug_parsers_py_mulitpart.ex
defmodule Plug.Parsers.MY_MULTIPART do
  @multipart Plug.Parsers.MULTIPART

  def init(opts) do
    opts
  end

  def parse(conn, "multipart", subtype, headers, opts) do
    length = System.fetch_env!("UPLOAD_LIMIT") |> String.to_integer()
    opts = @multipart.init([length: length] ++ opts)
    @multipart.parse(conn, "multipart", subtype, headers, opts)
  end

  def parse(conn, _type, _subtype, _headers, _opts) do
    {:next, conn}
  end

  def multipart_to_params(parts, conn) do
    acc =
      for {name, _headers, body} <- Enum.reverse(parts),
          i <- 0..length(Enum.reverse(parts)),
          name != nil,
          reduce: Plug.Conn.Query.decode_init() do
        acc -> Plug.Conn.Query.decode_each({"name[#{to_string(i)}]", body}, acc)
      end

    {:ok, Plug.Conn.Query.decode_done(acc, []), conn}
  end
end

with

#endpoint
plug Plug.Parsers,
    parsers: [:urlencoded, :my_multipart, :json],
    pass: ["image/*"],
    json_decoder: Phoenix.json_library()
josevalim commented 1 year ago

What is your Plug version?

ndrean commented 1 year ago

mix.lock says "plug": {:hex, :plug, "1.14.2"

josevalim commented 1 year ago

Can you start the terminal and run the following:

~/OSS/plug[main]$ iex -S mix
Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]

Interactive Elixir (1.16.0-dev) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :code.which(Plug.Conn.Query)
~c"/Users/jose/OSS/plug/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Query.beam"
ndrean commented 1 year ago

Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Interactive Elixir (1.15.6) - press Ctrl+C to exit (type h() ENTER for help)

~c"/Users/nevendrean/code/elixir/up_img/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Query.beam"

josevalim commented 1 year ago

My bad. Apparently we published a more recent version of the docs without releasing the feature. You can use Plug main. I will see if I can do a new release soon.

josevalim commented 1 year ago

Released!

ndrean commented 1 year ago

Yep, everything works and I even solved my issue. Cool