Packages
Plug to get constant response time for requests. Simple protection against side channel attacks.
Current section
Files
Jump to
Current section
Files
lib/request_time_plug.ex
defmodule RequestTimePlug do
import Plug.Conn
def init(default), do: default
@spec call(Plug.Conn.t(), keyword) :: Plug.Conn.t()
def call(%Plug.Conn{} = conn, opts) do
resp_time = Keyword.get(opts, :response_time, 0)
conn
|> assign(:start_time, now())
|> Plug.Conn.register_before_send(&before_send(&1, resp_time))
end
@spec before_send(Plug.Conn.t(), integer()) :: Plug.Conn.t()
defp before_send(%{assigns: %{start_time: start_time}} = conn, resp_time)
when is_integer(start_time) do
execution_time = now() - start_time
delay_time = resp_time - execution_time
if delay_time > 0 do
Process.sleep(delay_time)
end
conn
end
defp before_send(conn, _), do: conn
@spec now() :: integer()
defp now(), do: :os.system_time(:millisecond)
end