Packages
plug
0.4.2
1.20.3
1.20.2
1.20.1
retired
1.20.0
retired
1.19.5
1.19.4
1.19.3
1.19.2
1.19.1
1.19.0
1.18.5
1.18.4
1.18.3
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.6
1.16.5
1.16.4
1.16.3
1.16.2
1.16.1
1.16.0
1.15.6
1.15.5
1.15.4
1.15.3
1.15.2
1.15.1
1.15.0
1.14.2
1.14.1
1.14.0
1.13.6
1.13.5
1.13.4
1.13.3
1.13.2
1.13.1
retired
1.13.0
retired
1.12.1
1.12.0
1.11.1
1.11.0
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.0
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.14.0
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
Compose web applications with functions
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/plug/parsers.ex
defmodule Plug.Parsers do
message = "the request is too large. If you are willing to process " <>
"larger requests, please give a :limit to Plug.Parsers"
defexception RequestTooLargeError, [:message] do
@moduledoc """
Error raised when the request is too large
"""
defimpl Plug.Exception do
def status(_exception) do
413
end
end
end
defexception UnsupportedMediaTypeError, [:message] do
@moduledoc """
Error raised when the request body cannot be parsed
"""
defimpl Plug.Exception do
def status(_exception) do
415
end
end
end
@moduledoc """
A plug for parsing the request body
## Options
* `:parsers` - a set of modules to be invoked for parsing.
These modules need to implement the behaviour
outlined in this module.
* `:limit` - the request size limit we accept to parse.
Defaults to 8,000,000 bytes.
## Examples
plug Plug.Parsers, parsers: [:urlencoded, :multipart]
## Built-in parsers
Plug ships with the following parsers:
* `Plug.Parsers.URLENCODED` - parses "application/x-www-form-urlencoded" requests
* `Plug.Parsers.MULTIPART` - parses "multipart/form-data" and "multipart/mixed" requests
This plug will raise `Plug.Parsers.UnsupportedMediaTypeError` if
the request cannot be parsed by any of the given types and raise
`Plug.Parsers.RequestTooLargeError` if the request goes over the
given limit.
## File handling
If a file is uploaded via any of the parsers, Plug will
stream the uploaded contents to a file in a temporary directory,
avoiding loading the whole file into memory. For such, it is
required that the `:plug` application is started.
In those cases, the parameter will return a `Plug.Upload`
struct with information about the file and its content type.
You can customize the temporary directory by setting the `PLUG_TMPDIR`
environment variable in your system.
"""
alias Plug.Conn
use Behaviour
@doc """
Attempt to parse the connection request body given the type,
subtype and headers. Returns `{:ok, conn}` if the parser can
handle the given content type, `{:halt, conn}` otherwise.
"""
defcallback parse(Conn.t, type :: binary, subtype :: binary,
headers :: Keyword.t, opts :: Keyword.t) ::
{:ok, Conn.params, Conn.t} |
{:too_large, Conn.t} |
{:skip, Conn.t}
@behaviour Plug
def init(opts) do
parsers = Keyword.get(opts, :parsers) || raise_missing_parsers
opts
|> Keyword.put(:parsers, convert_parsers(parsers))
|> Keyword.put_new(:limit, 8_000_000)
end
defp raise_missing_parsers do
raise ArgumentError, message: "Plug.Parsers expects a set of parsers to be given in :parsers"
end
defp convert_parsers(parsers) do
for parser <- parsers do
case atom_to_binary(parser) do
"Elixir." <> _ -> parser
reference -> Module.concat(Plug.Parsers, String.upcase(reference))
end
end
end
def call(%Conn{req_headers: req_headers} = conn, opts) do
conn = Plug.Conn.fetch_params(conn)
case List.keyfind(req_headers, "content-type", 0) do
{"content-type", ct} ->
case Plug.Conn.Utils.content_type(ct) do
{:ok, type, subtype, headers} ->
reduce(conn, Keyword.fetch!(opts, :parsers), type, subtype, headers, opts)
:error ->
conn
end
nil ->
conn
end
end
defp reduce(conn, [h|t], type, subtype, headers, opts) do
case h.parse(conn, type, subtype, headers, opts) do
{:ok, post, %Conn{params: get} = conn} ->
%{conn | params: Map.merge(get, post)}
{:next, conn} ->
reduce(conn, t, type, subtype, headers, opts)
{:too_large, _conn} ->
raise Plug.Parsers.RequestTooLargeError
end
end
defp reduce(_conn, [], type, subtype, _headers, _opts) do
raise UnsupportedMediaTypeError,
message: "unsupported media type #{type}/#{subtype}"
end
end