Current section
Files
Jump to
Current section
Files
lib/server_web/plugs/directory_check_plug.ex
defmodule ExServerWeb.DirectoryCheckPlug do
@moduledoc """
This plug checks to see if the current request is
for a file or for a direcotry. If it is for a file,
the the file is served and the conn is halted. If
the request is for a directory, then the conn is
moved along and the catch all LiveView module
handles it.
"""
require Logger
import Phoenix.Controller, only: [redirect: 2, protect_from_forgery: 1]
import Plug.Conn, only: [halt: 1, send_file: 3, put_resp_content_type: 2]
alias Plug.Conn
@behaviour Plug
@impl true
def init(_opts) do
[]
end
@impl true
def call(%Conn{params: %{"path" => desired_path}} = conn, _opts) do
desired_path =
case desired_path do
[] -> "/"
path -> Path.join(path)
end
requested_filesystem_object =
File.cwd!()
|> Path.join(desired_path)
cond do
File.dir?(requested_filesystem_object) ->
Logger.info("Requested directory: #{inspect(requested_filesystem_object)}")
protect_from_forgery(conn)
File.exists?(requested_filesystem_object) ->
Logger.info("Requested file: #{inspect(requested_filesystem_object)}")
content_type = MIME.from_path(requested_filesystem_object)
conn
|> put_resp_content_type(content_type)
|> send_file(200, requested_filesystem_object)
|> halt()
true ->
Logger.warning("Invalid file system request: #{inspect(requested_filesystem_object)}")
conn
|> protect_from_forgery()
|> redirect_to_cwd()
end
end
def call(conn, _opts) do
redirect_to_cwd(conn)
end
defp redirect_to_cwd(conn) do
conn
|> redirect(to: "/")
|> halt()
end
end