init
This commit is contained in:
60
lib/forum/public_site_router.ex
Normal file
60
lib/forum/public_site_router.ex
Normal file
@@ -0,0 +1,60 @@
|
||||
defmodule Forum.PublicSiteRouter do
|
||||
@moduledoc """
|
||||
Serves one network's public website on its own port.
|
||||
"""
|
||||
import Plug.Conn
|
||||
|
||||
def init(opts), do: opts
|
||||
|
||||
def call(conn, opts) do
|
||||
network = Keyword.fetch!(opts, :network)
|
||||
started_at = System.monotonic_time(:microsecond)
|
||||
|
||||
response =
|
||||
with {:ok, pid} <- Forum.PublicSiteSupervisor.get_or_start(network) do
|
||||
Forum.PublicSite.serve(pid, %{
|
||||
method: conn.method,
|
||||
path: conn.request_path,
|
||||
query_string: conn.query_string,
|
||||
headers: conn.req_headers
|
||||
})
|
||||
else
|
||||
{:error, reason} ->
|
||||
%{
|
||||
status: 500,
|
||||
content_type: "text/plain",
|
||||
body: "Unable to start public site: #{inspect(reason)}"
|
||||
}
|
||||
end
|
||||
|
||||
duration_us = System.monotonic_time(:microsecond) - started_at
|
||||
|
||||
Forum.LogStore.add(%{
|
||||
"source_ip" => remote_ip(conn),
|
||||
"host" => conn.host || "",
|
||||
"network" => network,
|
||||
"method" => conn.method,
|
||||
"path" => conn.request_path,
|
||||
"query_string" => conn.query_string,
|
||||
"status" => response.status,
|
||||
"duration_ms" => Float.round(duration_us / 1_000, 2)
|
||||
})
|
||||
|
||||
conn
|
||||
|> put_resp_content_type(response.content_type)
|
||||
|> send_resp(response.status, response.body)
|
||||
end
|
||||
|
||||
defp remote_ip(conn) do
|
||||
case Plug.Conn.get_req_header(conn, "x-real-ip") do
|
||||
[ip | _] -> ip
|
||||
[] -> fallback_ip(conn)
|
||||
end
|
||||
end
|
||||
|
||||
defp fallback_ip(%{remote_ip: remote_ip}) when is_tuple(remote_ip) do
|
||||
remote_ip |> :inet.ntoa() |> to_string()
|
||||
end
|
||||
|
||||
defp fallback_ip(_), do: ""
|
||||
end
|
||||
Reference in New Issue
Block a user