Packages
pow_assent
0.2.0
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
0.1.0-rc.2
0.1.0-rc.1
0.1.0-rc.0
0.1.0-alpha.12
0.1.0-alpha.11
0.1.0-alpha.10
0.1.0-alpha.9
0.1.0-alpha.8
0.1.0-alpha.7
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
retired
0.1.0-alpha.1
0.1.0-alpha
Multi-provider support for Pow
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/pow_assent/http_adapter/mint.ex
defmodule PowAssent.HTTPAdapter.Mint do
@moduledoc """
HTTP adapter module for making http requests with Mint.
Mint can be configured by updating the configuration to
`http_adapter: {PowAssent.HTTPAdapter.Mint, [...]}`.
"""
alias PowAssent.{HTTPAdapter, HTTPAdapter.HTTPResponse}
@behaviour HTTPAdapter
@impl HTTPAdapter
def request(method, url, body, headers, mint_opts \\ nil) do
headers = headers ++ [HTTPAdapter.user_agent_header()]
%{scheme: scheme, port: port, host: host, path: path} = URI.parse(url)
scheme
|> open_mint_conn(host, port, mint_opts)
|> mint_request(method, path, headers, body)
|> format_response()
end
defp open_mint_conn(scheme, host, port, nil), do: open_mint_conn(scheme, host, port, [])
defp open_mint_conn("http", host, port, opts), do: open_mint_conn(:http, host, port, opts)
defp open_mint_conn("https", host, port, opts), do: open_mint_conn(:https, host, port, opts)
defp open_mint_conn(scheme, host, port, opts) when is_atom(scheme), do: Mint.HTTP.connect(scheme, host, port, opts)
defp mint_request(resp, :get, path, headers, body), do: mint_request(resp, "GET", path, headers, body)
defp mint_request(resp, :post, path, headers, body), do: mint_request(resp, "POST", path, headers, body)
defp mint_request(resp, method, nil, headers, body), do: mint_request(resp, method, "/", headers, body)
defp mint_request({:ok, conn}, method, path, headers, body) do
conn
|> Mint.HTTP.request(method, path, headers, body)
|> await_response()
end
defp mint_request({:error, error}, _method, _path, _headers, _body), do: {:error, error}
defp await_response({:ok, conn, request_ref}), do: await_response(conn, request_ref)
defp await_response(conn, request_ref, timeout \\ 5_000) do
receive do
message -> mint_stream(conn, request_ref, message)
after timeout ->
{:error, :timeout}
end
end
defp mint_stream(conn, _request_ref, message) do
case Mint.HTTP.stream(conn, message) do
{:ok, _conn, responses} -> {:ok, responses}
:unknown -> {:error, :unknown}
end
end
defp format_response({:ok, responses}) do
[{:status, _, status}, {:headers, _, headers} | responses] = responses
body = merge_body(responses)
{:ok, %HTTPResponse{status: status, headers: headers, body: body}}
end
defp format_response({:error, response}), do: {:error, response}
defp merge_body([{:data, _request, new_body} | rest], body), do: merge_body(rest, body <> new_body)
defp merge_body(_rest, body), do: body
defp merge_body([{:data, _request, _body} | _rest] = responses), do: merge_body(responses, "")
end