defmodule GriffinSSG.Web.Plug do @moduledoc """ Defines a simple HTTP server with LiveReload. Spawned from the `grf.server` task. PlugLiveReload doesn't work within the context of a Plug.Builder, so we can't use Plug.Static to serve the files. Instead, we use Plug.Router and need to implement the file serving logic, which is... unfortunate. """ use Plug.Router use Plug.ErrorHandler plug(PlugLiveReload) plug(:match) plug(:dispatch) match "*path" do expanded_path = [output_dir() | path] |> Path.join() |> Path.expand() if File.exists?(expanded_path) and File.dir?(expanded_path) do send_file(conn, Path.join(expanded_path, "index.html")) else send_file(conn, expanded_path) end end defp send_file(conn, path) do case File.read(path) do {:ok, file} -> conn |> put_resp_content_type(MIME.from_path(path)) |> send_resp(200, file) {:error, :enoent} -> send_resp(conn, 404, "not found") end end @impl Plug.ErrorHandler def handle_errors(conn, _) do send_resp(conn, conn.status, "internal server error") end defp output_dir do Application.get_env(:griffin, :output, "_site") end end