symbiont_ex/deps/bandit/lib/bandit/delegating_handler.ex

79 lines
2.4 KiB
Elixir

defmodule Bandit.DelegatingHandler do
@moduledoc false
# Delegates all implementation of the ThousandIsland.Handler behaviour
# to an implementation specified in state. Allows for clean separation
# between protocol implementations & friction free protocol selection &
# upgrades.
use ThousandIsland.Handler
@impl ThousandIsland.Handler
def handle_connection(socket, %{handler_module: handler_module} = state) do
handler_module.handle_connection(socket, state)
|> handle_bandit_continuation(socket)
end
@impl ThousandIsland.Handler
def handle_data(data, socket, %{handler_module: handler_module} = state) do
handler_module.handle_data(data, socket, state)
|> handle_bandit_continuation(socket)
end
@impl ThousandIsland.Handler
def handle_shutdown(socket, %{handler_module: handler_module} = state) do
handler_module.handle_shutdown(socket, state)
end
@impl ThousandIsland.Handler
def handle_close(socket, %{handler_module: handler_module} = state) do
handler_module.handle_close(socket, state)
end
@impl ThousandIsland.Handler
def handle_timeout(socket, %{handler_module: handler_module} = state) do
handler_module.handle_timeout(socket, state)
end
@impl ThousandIsland.Handler
def handle_error(error, socket, %{handler_module: handler_module} = state) do
handler_module.handle_error(error, socket, state)
end
@impl GenServer
def handle_call(msg, from, {_socket, %{handler_module: handler_module}} = state) do
handler_module.handle_call(msg, from, state)
end
@impl GenServer
def handle_cast(msg, {_socket, %{handler_module: handler_module}} = state) do
handler_module.handle_cast(msg, state)
end
@impl GenServer
def handle_info(msg, {_socket, %{handler_module: handler_module}} = state) do
handler_module.handle_info(msg, state)
end
defp handle_bandit_continuation(continuation, socket) do
case continuation do
{:switch, next_handler, state} ->
handle_connection(socket, %{state | handler_module: next_handler})
{:switch, next_handler, data, state} ->
case handle_connection(socket, %{state | handler_module: next_handler}) do
{:continue, state} ->
handle_data(data, socket, state)
{:continue, state, _timeout} ->
handle_data(data, socket, state)
other ->
other
end
other ->
other
end
end
end