zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

handler.ex (2174B)


      1 defmodule Plug.Cowboy.Handler do
      2   @moduledoc false
      3   @connection Plug.Cowboy.Conn
      4   @already_sent {:plug_conn, :sent}
      5 
      6   def init(req, {plug, opts}) do
      7     conn = @connection.conn(req)
      8 
      9     try do
     10       conn
     11       |> plug.call(opts)
     12       |> maybe_send(plug)
     13       |> case do
     14         %Plug.Conn{adapter: {@connection, %{upgrade: {:websocket, websocket_args}} = req}} = conn ->
     15           {handler, state, cowboy_opts} = websocket_args
     16           {__MODULE__, copy_resp_headers(conn, req), {handler, state}, cowboy_opts}
     17 
     18         %Plug.Conn{adapter: {@connection, req}} ->
     19           {:ok, req, {plug, opts}}
     20       end
     21     catch
     22       kind, reason ->
     23         exit_on_error(kind, reason, __STACKTRACE__, {plug, :call, [conn, opts]})
     24     after
     25       receive do
     26         @already_sent -> :ok
     27       after
     28         0 -> :ok
     29       end
     30     end
     31   end
     32 
     33   def upgrade(req, env, __MODULE__, {handler, state}, opts) do
     34     :cowboy_websocket.upgrade(req, env, handler.module_info(:module), state, opts)
     35   end
     36 
     37   defp copy_resp_headers(%Plug.Conn{} = conn, req) do
     38     Enum.reduce(conn.resp_headers, req, fn {key, val}, acc ->
     39       :cowboy_req.set_resp_header(key, val, acc)
     40     end)
     41   end
     42 
     43   defp exit_on_error(
     44          :error,
     45          %Plug.Conn.WrapperError{kind: kind, reason: reason, stack: stack},
     46          _stack,
     47          call
     48        ) do
     49     exit_on_error(kind, reason, stack, call)
     50   end
     51 
     52   defp exit_on_error(:error, value, stack, call) do
     53     exception = Exception.normalize(:error, value, stack)
     54     :erlang.raise(:exit, {{exception, stack}, call}, [])
     55   end
     56 
     57   defp exit_on_error(:throw, value, stack, call) do
     58     :erlang.raise(:exit, {{{:nocatch, value}, stack}, call}, [])
     59   end
     60 
     61   defp exit_on_error(:exit, value, _stack, call) do
     62     :erlang.raise(:exit, {value, call}, [])
     63   end
     64 
     65   defp maybe_send(%Plug.Conn{state: :unset}, _plug), do: raise(Plug.Conn.NotSentError)
     66   defp maybe_send(%Plug.Conn{state: :set} = conn, _plug), do: Plug.Conn.send_resp(conn)
     67   defp maybe_send(%Plug.Conn{} = conn, _plug), do: conn
     68 
     69   defp maybe_send(other, plug) do
     70     raise "Cowboy2 adapter expected #{inspect(plug)} to return Plug.Conn but got: " <>
     71             inspect(other)
     72   end
     73 end