41 lines
1.2 KiB
Elixir
41 lines
1.2 KiB
Elixir
defmodule ComponentsElixirWeb.FileController do
|
|
use ComponentsElixirWeb, :controller
|
|
|
|
def show(conn, %{"filename" => filename}) do
|
|
# Security: only allow alphanumeric, dashes, underscores, and dots
|
|
if String.match?(filename, ~r/^[a-zA-Z0-9_\-\.]+$/) do
|
|
uploads_dir = Application.get_env(:components_elixir, :uploads_dir)
|
|
file_path = Path.join([uploads_dir, "images", filename])
|
|
|
|
if File.exists?(file_path) do
|
|
# Get the file's MIME type
|
|
mime_type = get_mime_type(filename)
|
|
|
|
conn
|
|
|> put_resp_content_type(mime_type)
|
|
|> put_resp_header("cache-control", "public, max-age=86400") # Cache for 1 day
|
|
|> send_file(200, file_path)
|
|
else
|
|
conn
|
|
|> put_status(:not_found)
|
|
|> text("File not found")
|
|
end
|
|
else
|
|
conn
|
|
|> put_status(:bad_request)
|
|
|> text("Invalid filename")
|
|
end
|
|
end
|
|
|
|
defp get_mime_type(filename) do
|
|
case Path.extname(filename) |> String.downcase() do
|
|
".jpg" -> "image/jpeg"
|
|
".jpeg" -> "image/jpeg"
|
|
".png" -> "image/png"
|
|
".gif" -> "image/gif"
|
|
".webp" -> "image/webp"
|
|
_ -> "application/octet-stream"
|
|
end
|
|
end
|
|
end
|