Current section
Files
Jump to
Current section
Files
lib/conduit/plug/decode.ex
defmodule Conduit.Plug.Decode do
use Conduit.Plug.Builder
@moduledoc """
Decodes the message body based on the content encoding.
It uses in order of preference:
1. The content encoding specified for the plug.
2. The content encoding specified on the message.
3. The default content encoding `identity`.
The location of the content encoding can be changed from `content_encoding`
to a header with the `:header` option. This is useful for having multiple
encodings, like a transfer encoding.
This plug should be used in an incoming pipeline. Generally before
a `Conduit.Plug.Parse` plug.
## Examples
plug Conduit.Plug.Decode
plug Conduit.Plug.Decode, content_encoding: "gzip"
plug Conduit.Plug.Decode, header: "transfer_encoding"
iex> import Conduit.Message
iex> message =
iex> %Conduit.Message{}
iex> |> put_body("{}")
iex> |> Conduit.Plug.Decode.run
iex> message.body
"{}"
iex> message.content_encoding
"identity"
iex> import Conduit.Message
iex> message =
iex> %Conduit.Message{}
iex> |> put_body("{}")
iex> |> Conduit.Plug.Decode.run(header: "transfer_encoding")
iex> message.body
"{}"
iex> get_header(message, "transfer_encoding")
"identity"
"""
alias Conduit.Encoding
@doc """
Formats the message body based on the content encoding.
"""
@default_content_encoding "identity"
def call(message, next, opts) do
content_encoding =
Keyword.get(opts, :content_encoding) || Map.get(message, :content_encoding) ||
@default_content_encoding
message
|> put_content_encoding_at(Keyword.get(opts, :header), content_encoding)
|> Encoding.decode(content_encoding, opts)
|> next.()
end
defp put_content_encoding_at(message, nil, content_encoding) do
put_content_encoding(message, content_encoding)
end
defp put_content_encoding_at(message, header, content_encoding) do
put_header(message, header, content_encoding)
end
end