Packages
ankh
0.8.11
0.17.0
0.16.0
0.15.0
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.0
0.12.1
0.12.0
0.11.0
0.10.0
0.9.0
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.1
0.3.0
0.1.1
0.1.0
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Pure Elixir HTTP/2 implementation
Current section
Files
Jump to
Current section
Files
lib/ankh/http/response.ex
defmodule Ankh.HTTP.Response do
@moduledoc """
Ankh HTTP Response
"""
alias Ankh.HTTP
@typedoc "Response status"
@type status :: non_neg_integer()
@type t() :: %__MODULE__{
status: status(),
body: HTTP.body(),
headers: HTTP.headers(),
trailers: HTTP.headers(),
body_fetched: boolean(),
complete: boolean()
}
defstruct status: 200,
body: [],
headers: [],
trailers: [],
body_fetched: false,
complete: false
@spec new(keyword) :: t()
def new(attrs \\ []), do: struct(__MODULE__, attrs)
@spec put_header(t(), HTTP.header_name(), HTTP.header_value()) :: t()
def put_header(%{headers: headers} = response, name, value),
do: %{response | headers: [{String.downcase(name), value} | headers]}
@spec put_headers(t(), HTTP.headers()) :: t()
def put_headers(response, headers),
do:
Enum.reduce(headers, response, fn {header, value}, acc -> put_header(acc, header, value) end)
@spec put_trailer(t(), HTTP.header_name(), HTTP.header_value()) :: t()
def put_trailer(%{trailers: trailers} = response, name, value),
do: %{response | trailers: [{String.downcase(name), value} | trailers]}
@spec put_trailers(t(), HTTP.headers()) :: t()
def put_trailers(response, trailers) do
Enum.reduce(trailers, response, fn {header, value}, acc ->
put_trailer(acc, header, value)
end)
end
@spec set_status(t(), status()) :: t()
def set_status(response, status), do: %{response | status: status}
@spec set_body(t(), iodata()) :: t()
def set_body(response, body), do: %{response | body: body}
@spec fetch_header_values(t(), HTTP.header_name()) :: [HTTP.header_value()]
def fetch_header_values(%{headers: headers}, name), do: fetch_values(headers, name)
@spec fetch_trailer_values(t(), HTTP.header_name()) :: [HTTP.header_value()]
def fetch_trailer_values(%{trailers: trailers}, name), do: fetch_values(trailers, name)
defp fetch_values(headers, name) do
headers
|> Enum.reduce([], fn
{^name, value}, acc ->
[value | acc]
_, acc ->
acc
end)
|> Enum.reverse()
end
@spec fetch_body(t()) :: t()
def fetch_body(%__MODULE__{body_fetched: false, body: body} = response) do
body =
body
|> Enum.reverse()
|> IO.iodata_to_binary()
%{response | body_fetched: true, body: body}
end
def fetch_body(%__MODULE__{body_fetched: true} = response), do: response
end