Packages
ankh
0.8.10
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/request.ex
defmodule Ankh.HTTP.Request do
@moduledoc """
Ankh HTTP Request
"""
alias Ankh.HTTP
alias Ankh.HTTP.Query
@typedoc "HTTP request options"
@type options :: Keyword.t()
@typedoc "Request method"
@type method :: :CONNECT | :DELETE | :GET | :HEAD | :OPTIONS | :PATCH | :POST | :PUT | :TRACE
@typedoc "Request path"
@type path :: String.t()
@typedoc "HTTP Request"
@type t() :: %__MODULE__{
method: method(),
path: path(),
headers: HTTP.headers(),
trailers: HTTP.headers(),
body: HTTP.body(),
options: options()
}
defstruct method: :GET,
path: "/",
headers: [],
trailers: [],
body: [],
options: []
@spec new(keyword) :: t()
def new(attrs \\ []), do: struct(__MODULE__, attrs)
@spec to_uri(t()) :: URI.t()
def to_uri(%{path: path}), do: URI.parse(path)
@spec from_uri(URI.t()) :: t()
def from_uri(uri), do: put_uri(new(), uri)
@spec put_uri(t(), URI.t()) :: t()
def put_uri(request, %URI{path: nil, query: nil}), do: request
def put_uri(request, %URI{path: path, query: nil}), do: set_path(request, path)
def put_uri(request, %URI{path: nil, query: query}), do: set_query(request, query)
def put_uri(request, %URI{path: path, query: query}) do
query = Query.decode(query)
request
|> set_path(path)
|> set_query(query)
end
@spec put_header(t(), HTTP.header_name(), HTTP.header_value()) :: t()
def put_header(%{headers: headers} = request, header, value),
do: %{request | headers: [{String.downcase(header), value} | headers]}
@spec put_headers(t(), HTTP.headers()) :: t()
def put_headers(request, headers),
do:
Enum.reduce(headers, request, 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} = request, header, value),
do: %{request | trailers: [{String.downcase(header), value} | trailers]}
@spec put_trailers(t(), HTTP.headers()) :: t()
def put_trailers(request, trailers) do
Enum.reduce(trailers, request, fn {header, value}, acc ->
put_trailer(acc, header, value)
end)
end
@spec put_options(t(), options()) :: t()
def put_options(%{options: options} = request, new_options),
do: %{request | options: Keyword.merge(options, new_options)}
@spec set_body(t(), iodata()) :: t()
def set_body(request, body), do: %{request | body: body}
@spec set_method(t(), method()) :: t()
def set_method(request, method), do: %{request | method: method}
@spec set_path(t(), path()) :: t()
def set_path(request, path), do: %{request | path: path}
@spec put_path(t(), path()) :: t()
def put_path(request, path) do
%URI{query: query} = to_uri(request)
new_path =
case query do
nil -> path
query -> path <> "?" <> query
end
%{request | path: new_path}
end
@spec set_query(t(), Query.t()) :: t()
def set_query(request, query) do
%URI{path: path} = to_uri(request)
new_path =
case query do
nil ->
path
query ->
query = Query.encode(query)
path <> "?" <> query
end
%{request | path: new_path}
end
@spec put_query(t(), Query.t()) :: t()
def put_query(request, query) do
%URI{query: old_query} = to_uri(request)
query =
case old_query do
nil ->
query
old_query ->
old_query
|> Query.decode()
|> Map.merge(query)
end
set_query(request, query)
end
end