Packages

Mojito client but with castore updated, forked from https://github.com/surgeventures/mojito

Current section

Files

Jump to
mojito_fresha lib mojito utils.ex
Raw

lib/mojito/utils.ex

defmodule Mojito.Utils do
@moduledoc false
alias Mojito.Error
@doc ~S"""
Ensures that the return value errors are of the form
`{:error, %Mojito.Error{}}`. Values `:ok` and `{:ok, val}` are
considered successful; other values are treated as errors.
"""
@spec wrap_return_value(any) :: :ok | {:ok, any} | {:error, Mojito.error()}
def wrap_return_value(rv) do
case rv do
:ok -> rv
{:ok, _} -> rv
{:error, %Error{}} -> rv
{:error, {:error, e}} -> {:error, %Error{reason: e}}
{:error, e} -> {:error, %Error{reason: e}}
{:error, _mint_conn, error} -> {:error, %Error{reason: error}}
other -> {:error, %Error{reason: :unknown, message: other}}
end
end
@doc ~S"""
Returns the protocol, hostname, and port (express or implied) from a
web URL.
iex> Mojito.Utils.decompose_url("http://example.com:8888/test")
{:ok, "http", "example.com", 8888}
iex> Mojito.Utils.decompose_url("https://user:pass@example.com")
{:ok, "https", "example.com", 443}
"""
@spec decompose_url(String.t()) ::
{:ok, String.t(), String.t(), non_neg_integer} | {:error, any}
def decompose_url(url) do
try do
uri = URI.parse(url)
cond do
!uri.scheme || !uri.host || !uri.port ->
{:error, %Error{message: "invalid URL: #{url}"}}
:else ->
{:ok, uri.scheme, uri.host, uri.port}
end
rescue
e -> {:error, %Error{message: "invalid URL", reason: e}}
end
end
@doc ~S"""
Returns a relative URL including query parts, excluding the fragment, and any
necessary auth headers (i.e., for HTTP Basic auth).
iex> Mojito.Utils.get_relative_url_and_auth_headers("https://user:pass@example.com/this/is/awesome?foo=bar&baz")
{:ok, "/this/is/awesome?foo=bar&baz", [{"authorization", "Basic dXNlcjpwYXNz"}]}
iex> Mojito.Utils.get_relative_url_and_auth_headers("https://example.com/something.html#section42")
{:ok, "/something.html", []}
"""
@spec get_relative_url_and_auth_headers(String.t()) ::
{:ok, String.t(), Mojito.headers()} | {:error, any}
def get_relative_url_and_auth_headers(url) do
try do
uri = URI.parse(url)
headers =
case uri.userinfo do
nil -> []
userinfo -> [{"authorization", "Basic #{Base.encode64(userinfo)}"}]
end
joined_url =
[
if(uri.path, do: "#{uri.path}", else: ""),
if(uri.query, do: "?#{uri.query}", else: "")
]
|> Enum.join("")
relative_url =
if String.starts_with?(joined_url, "/") do
joined_url
else
"/" <> joined_url
end
{:ok, relative_url, headers}
rescue
e -> {:error, %Error{message: "invalid URL", reason: e}}
end
end
@doc ~S"""
Returns the correct Erlang TCP transport module for the given protocol.
"""
@spec protocol_to_transport(String.t()) :: {:ok, atom} | {:error, any}
def protocol_to_transport("https"), do: {:ok, :ssl}
def protocol_to_transport("http"), do: {:ok, :gen_tcp}
def protocol_to_transport(proto),
do: {:error, "unknown protocol #{inspect(proto)}"}
end