symbiont_ex/deps/bandit/lib/bandit/socket_helpers.ex

75 lines
2.4 KiB
Elixir

defmodule Bandit.SocketHelpers do
@moduledoc false
def iodata_empty?(""), do: true
def iodata_empty?([]), do: true
def iodata_empty?([head | tail]), do: iodata_empty?(head) and iodata_empty?(tail)
def iodata_empty?(_), do: false
@spec conn_data(ThousandIsland.Socket.t()) :: Bandit.Pipeline.conn_data()
def conn_data(socket) do
secure? = ThousandIsland.Socket.secure?(socket)
{peer_address, _port} =
case ThousandIsland.Socket.peername(socket) do
{:ok, peername} -> map_address(peername)
{:error, reason} -> transport_error!("Unable to obtain conn_data", reason)
end
{secure?, peer_address}
end
@spec peer_data(ThousandIsland.Socket.t()) :: Plug.Conn.Adapter.peer_data()
def peer_data(socket) do
with {:ok, peername} <- ThousandIsland.Socket.peername(socket),
{address, port} <- map_address(peername),
{:ok, ssl_cert} <- peercert(socket) do
%{address: address, port: port, ssl_cert: ssl_cert}
else
{:error, reason} -> transport_error!("Unable to obtain peer_data", reason)
end
end
@spec sock_data(ThousandIsland.Socket.t()) :: Plug.Conn.Adapter.sock_data()
def sock_data(socket) do
with {:ok, sockname} <- ThousandIsland.Socket.sockname(socket),
{address, port} <- map_address(sockname) do
%{address: address, port: port}
else
{:error, reason} -> transport_error!("Unable to obtain sock_data", reason)
end
end
@spec ssl_data(ThousandIsland.Socket.t()) :: Plug.Conn.Adapter.ssl_data()
def ssl_data(socket) do
case ThousandIsland.Socket.connection_information(socket) do
{:ok, connection_information} -> connection_information
{:error, :not_secure} -> nil
{:error, reason} -> transport_error!("Unable to obtain ssl_data", reason)
end
end
defp map_address(address) do
case address do
{:local, path} -> {{:local, path}, 0}
{:unspec, <<>>} -> {:unspec, 0}
{:undefined, term} -> {{:undefined, term}, 0}
{ip, port} -> {ip, port}
end
end
defp peercert(socket) do
case ThousandIsland.Socket.peercert(socket) do
{:ok, cert} -> {:ok, cert}
{:error, :no_peercert} -> {:ok, nil}
{:error, :not_secure} -> {:ok, nil}
{:error, reason} -> {:error, reason}
end
end
@spec transport_error!(term(), term()) :: no_return()
defp transport_error!(message, error) do
raise Bandit.TransportError, message: message, error: error
end
end