From 5f321b0b5b10d0a3324b588b8f9af01878ecac04 Mon Sep 17 00:00:00 2001 From: Phantasm Date: Thu, 5 Mar 2026 12:49:20 +0100 Subject: [PATCH] Favicon Plug: Halt Plug pipeline when favicon not found --- lib/pleroma/web/plugs/favicon_plug.ex | 12 ++++++-- test/pleroma/web/plugs/favicon_plug_test.exs | 30 ++++++++------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/pleroma/web/plugs/favicon_plug.ex b/lib/pleroma/web/plugs/favicon_plug.ex index d50a03d83..1f8b891a1 100644 --- a/lib/pleroma/web/plugs/favicon_plug.ex +++ b/lib/pleroma/web/plugs/favicon_plug.ex @@ -11,7 +11,9 @@ defmodule Pleroma.Web.Plugs.FaviconPlug do Serves default or custom favicon.png with cacheable cache-control. """ - import Plug.Conn, only: [put_resp_header: 3] + import Plug.Conn, only: [put_resp_header: 3, send_resp: 3, halt: 1] + + require Logger def init(opts) do opts @@ -25,7 +27,12 @@ defmodule Pleroma.Web.Plugs.FaviconPlug do call_static(conn, opts, dir) :error -> - conn # Let the request keep going to a 404 + # Favicon should always be available and this should never occur. + # If it does, halt the pipeline before having unintended side-effects. + Logger.error("No favicon.png found! Is the default favicon deleted?") + conn + |> send_resp(404, "Not found") + |> halt() end end @@ -54,7 +61,6 @@ defmodule Pleroma.Web.Plugs.FaviconPlug do |> Map.put(:content_types, false) conn = set_content_type(conn) - Plug.Static.call(conn, opts) end diff --git a/test/pleroma/web/plugs/favicon_plug_test.exs b/test/pleroma/web/plugs/favicon_plug_test.exs index 87d955ccc..62926e041 100644 --- a/test/pleroma/web/plugs/favicon_plug_test.exs +++ b/test/pleroma/web/plugs/favicon_plug_test.exs @@ -5,20 +5,21 @@ defmodule Pleroma.Web.Plugs.FaviconPlugTest do use Pleroma.Web.ConnCase - # import Mox - - # alias Pleroma.UnstubbedConfigMock, as: ConfigMock - @dir "test/tmp/favicon_static" + setup do + Pleroma.Backports.mkdir_p!(@dir) + + on_exit(fn -> File.rm_rf!(@dir) end) + end + describe "default favicon" do test "returns favicon", %{conn: conn} do conn = get(conn, "/favicon.png") - etag = get_resp_header(conn, "etag") + body_size = byte_size(conn.resp_body) - # etag changes when serving a different file assert conn.status == 200 - assert etag == ["\"72487CE\""] + assert body_size == 1583 assert response_content_type(conn, :png) end @@ -33,28 +34,21 @@ defmodule Pleroma.Web.Plugs.FaviconPlugTest do describe "custom favicon" do setup do - Pleroma.Backports.mkdir_p!(@dir) favicon_path = Path.join(@dir, "favicon.png") + donor_image = "test/fixtures/image.png" - # Favicon plug should always return image/png - donor_image = "test/fixtures/image.gif" - image_stat = File.stat!(donor_image) - - # Preserve stat since that's what etag is based on File.cp!(donor_image, favicon_path) - File.write_stat!(favicon_path, image_stat) - clear_config([:instance, :static_dir], @dir) - on_exit( fn -> File.rm_rf!(@dir) end) + on_exit(fn -> File.rm!(favicon_path) end) end test "returns favicon", %{conn: conn} do conn = get(conn, "/favicon.png") - etag = get_resp_header(conn, "etag") + body_size = byte_size(conn.resp_body) assert conn.status == 200 - assert etag == ["\"215A3A4\""] + assert body_size == 104426 assert response_content_type(conn, :png) end