Plug.Parsers behaviour
A plug for parsing the request body.
This module also specifies a behaviour that all the parsers to be used with Plug should adopt.
This plug also fetches query params in the connection through Plug.Conn.fetch_query_params/2
.
Once a connection goes through this plug, it will have :body_params
set to the map of params parsed by one of the parsers listed in :parsers
and :params
set to the result of merging the :body_params
and :query_params
.
This plug will raise Plug.Parsers.UnsupportedMediaTypeError
by default if the request cannot be parsed by any of the given types and the MIME type has not been explicitly accepted with the :pass
option.
Plug.Parsers.RequestTooLargeError
will be raised if the request goes over the given limit.
Parsers may raise a Plug.Parsers.ParseError
if the request has a malformed body.
This plug only parses the body if the request method is one of the following:
POST
PUT
PATCH
DELETE
For requests with a different request method, this plug will only fetch the query params.
Options
:parsers
- a list of modules or atoms of built-in parsers to be invoked for parsing. These modules need to implement the behaviour outlined in this module.-
:pass
- an optional list of MIME type strings that are allowed to pass through. Any mime not handled by a parser and not explicitly listed in:pass
willraise UnsupportedMediaTypeError
. For example:-
["*/*"]
- never raises -
["text/html", "application/*"]
- doesn't raise for those values -
[]
- always raises (default)
-
:query_string_length
- the maximum allowed size for query strings:validate_utf8
- boolean that tells whether or not we want to validate that parsed binaries are utf8 strings.:body_reader
- an optional replacement (or wrapper) forPlug.Conn.read_body/2
to provide a function that gives access to the raw body before it is parsed and discarded. It is in the standard format of{Module, :function, [args]}
(MFA) and defaults to{Plug.Conn, :read_body, []}
. Note that this option is not used byPlug.Parsers.MULTIPART
which relies instead on other functions defined inPlug.Conn
.
Examples
plug Plug.Parsers, parsers: [:urlencoded, :multipart] plug Plug.Parsers, parsers: [:urlencoded, :json], pass: ["text/*"], json_decoder: Jason
Each parser also accepts options to be given directly to it by using tuples. For example, to support file uploads it is common to pass the :length
, :read_length
and :read_timeout
option to the multipart parser:
plug Plug.Parsers, parsers: [ :url_encoded, {:multipart, length: 20_000_000} # Increase to 20MB max upload ]
Built-in parsers
Plug ships with the following parsers:
-
Plug.Parsers.URLENCODED
- parsesapplication/x-www-form-urlencoded
requests (can be used as:urlencoded
as well in the:parsers
option) -
Plug.Parsers.MULTIPART
- parsesmultipart/form-data
andmultipart/mixed
requests (can be used as:multipart
as well in the:parsers
option) -
Plug.Parsers.JSON
- parsesapplication/json
requests with the given:json_decoder
(can be used as:json
as well in the:parsers
option)
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 in order to avoid loading the whole file into memory. For such, the :plug
application needs to be started in order for file uploads to work. More details on how the uploaded file is handled can be found in the documentation for Plug.Upload
.
When a file is uploaded, the request parameter that identifies that file will be a Plug.Upload
struct with information about the uploaded file (e.g. filename and content type) and about where the file is stored.
The temporary directory where files are streamed to can be customized by setting the PLUG_TMPDIR
environment variable on the host system. If PLUG_TMPDIR
isn't set, Plug will look at some environment variables which usually hold the value of the system's temporary directory (like TMPDIR
or TMP
). If no value is found in any of those variables, /tmp
is used as a default.
Custom body reader
Sometimes you may want to customize how a parser reads the body from the connection. For example, you may want to cache the body to perform verification later, such as HTTP Signature Verification. This can be achieved with a custom body reader that would read the body and store it in the connection, such as:
defmodule CacheBodyReader do def read_body(conn, opts) do {:ok, body, conn} = Plug.Conn.read_body(conn, opts) conn = update_in(conn.assigns[:raw_body], &[body | (&1 || [])]) {:ok, body, conn} end end
which could then be set as:
plug Plug.Parsers, parsers: [:urlencoded, :json], pass: ["text/*"], body_reader: {CacheBodyReader, :read_body, []}, json_decoder: Jason
Summary
Functions
- call(conn, options)
Callback implementation for
Plug.call/2
.- init(opts)
Callback implementation for
Plug.init/1
.
Callbacks
- parse(conn, type, subtype, params, opts)
Attempts to parse the connection's request body given the content-type type, subtype, and its parameters.
Functions
call(conn, options)
Callback implementation for Plug.call/2
.
init(opts)
Callback implementation for Plug.init/1
.
Callbacks
init(opts)
Specs
init(opts :: Keyword.t()) :: Plug.opts()
parse(conn, type, subtype, params, opts)
Specs
parse( conn :: Plug.Conn.t(), type :: binary(), subtype :: binary(), params :: Plug.Conn.Utils.params(), opts :: Plug.opts() ) :: {:ok, Plug.Conn.params(), Plug.Conn.t()} | {:error, :too_large, Plug.Conn.t()} | {:next, Plug.Conn.t()}
Attempts to parse the connection's request body given the content-type type, subtype, and its parameters.
The arguments are:
- the
Plug.Conn
connection -
type
, the content-type type (e.g.,"x-sample"
for the"x-sample/json"
content-type) -
subtype
, the content-type subtype (e.g.,"json"
for the"x-sample/json"
content-type) -
params
, the content-type parameters (e.g.,%{"foo" => "bar"}
for the"text/plain; foo=bar"
content-type)
This function should return:
-
{:ok, body_params, conn}
if the parser is able to handle the given content-type;body_params
should be a map -
{:next, conn}
if the next parser should be invoked -
{:error, :too_large, conn}
if the request goes over the given limit
© 2013 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/plug/Plug.Parsers.html