Packages

A self-hosted, real-time dashboard for running bloccs networks — topology, live per-node metrics, and coverage, mounted into your Phoenix app.

Current section

Files

Jump to
bloccs_web lib bloccs web assets.ex
Raw

lib/bloccs/web/assets.ex

defmodule Bloccs.Web.Assets do
@moduledoc """
Serves the dashboard's own precompiled `app.css` / `app.js` from
`priv/static/assets`, so the host needs no `Plug.Static` configuration and the
bundles can't collide with the host's own assets.
`forward`ed by `bloccs_dashboard/2` at `<path>/assets`, so the filename arrives
as the remaining `path_info` segment. A long `cache-control` is safe because
the filenames are content-stable per release.
"""
@behaviour Plug
@types %{"app.css" => "text/css", "app.js" => "application/javascript"}
@impl true
def init(opts), do: opts
@impl true
def call(%Plug.Conn{path_info: path_info} = conn, _opts) do
serve(conn, List.last(path_info))
end
defp serve(conn, file) when is_binary(file) do
case Map.fetch(@types, Path.basename(file)) do
{:ok, content_type} ->
path = Path.join(:code.priv_dir(:bloccs_web), "static/assets/#{Path.basename(file)}")
if File.regular?(path) do
conn
|> Plug.Conn.put_resp_header("content-type", content_type)
|> Plug.Conn.put_resp_header("cache-control", "public, max-age=31536000")
|> Plug.Conn.send_file(200, path)
|> Plug.Conn.halt()
else
not_found(conn)
end
:error ->
not_found(conn)
end
end
defp serve(conn, _), do: not_found(conn)
defp not_found(conn) do
conn
|> Plug.Conn.send_resp(404, "not found")
|> Plug.Conn.halt()
end
end