method_override.ex (1185B)
1 defmodule Plug.MethodOverride do 2 @moduledoc """ 3 This plug overrides the request's `POST` method with the method defined in 4 the `_method` request parameter. 5 6 The `POST` method can be overridden only by these HTTP methods: 7 8 * `PUT` 9 * `PATCH` 10 * `DELETE` 11 12 This plug expects the body parameters to be already parsed and 13 fetched. Those can be fetched with `Plug.Parsers`. 14 15 This plug doesn't accept any options. 16 17 ## Examples 18 19 Plug.MethodOverride.call(conn, []) 20 """ 21 22 @behaviour Plug 23 24 @allowed_methods ~w(DELETE PUT PATCH) 25 26 @impl true 27 def init([]), do: [] 28 29 @impl true 30 def call(%Plug.Conn{method: "POST", body_params: body_params} = conn, []), 31 do: override_method(conn, body_params) 32 33 def call(%Plug.Conn{} = conn, []), do: conn 34 35 defp override_method(conn, %Plug.Conn.Unfetched{}) do 36 # Just skip it because maybe it is a content-type that 37 # we could not parse as parameters (for example, text/gps) 38 conn 39 end 40 41 defp override_method(conn, body_params) do 42 method = String.upcase(body_params["_method"] || "", :ascii) 43 44 if method in @allowed_methods do 45 %{conn | method: method} 46 else 47 conn 48 end 49 end 50 end