Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85629942
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/changelog.d/fix-preferred-frontend.fix b/changelog.d/fix-preferred-frontend.fix
new file mode 100644
index 000000000..07bf4d0c6
--- /dev/null
+++ b/changelog.d/fix-preferred-frontend.fix
@@ -0,0 +1 @@
+Fix preferred frontend not working due to InstanceStatic plug prematurely returning HTTP 404
diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex
index 07b33f866..4582fd0fd 100644
--- a/lib/pleroma/web/endpoint.ex
+++ b/lib/pleroma/web/endpoint.ex
@@ -1,206 +1,214 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Endpoint do
use Phoenix.Endpoint, otp_app: :pleroma
require Pleroma.Constants
alias Pleroma.Config
plug(Pleroma.Web.MastodonAPI.WebsocketPlug,
path: "/api/v1/streaming",
websocket: [
path: "/",
compress: false,
connect_info: [:sec_websocket_headers],
error_handler: {Pleroma.Web.MastodonAPI.WebsocketHandler, :handle_error, []},
fullsweep_after: 20
]
)
socket("/socket", Pleroma.Web.UserSocket,
websocket: [
path: "/websocket",
serializer: [
{Phoenix.Socket.V1.JSONSerializer, "~> 1.0.0"},
{Phoenix.Socket.V2.JSONSerializer, "~> 2.0.0"}
],
timeout: 60_000,
transport_log: false,
compress: false,
fullsweep_after: 20
],
longpoll: false
)
socket("/live", Phoenix.LiveView.Socket)
plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint])
plug(Pleroma.Web.Plugs.LoggerMetadataPath)
plug(Pleroma.Web.Plugs.SetLocalePlug)
plug(CORSPlug)
plug(Pleroma.Web.Plugs.HTTPSecurityPlug)
plug(Pleroma.Web.Plugs.UploadedMedia)
@static_cache_control "public, max-age=1209600, immutable"
@static_cache_disabled "public, no-cache"
# cache for a day
@favicon_cache_control "public, max=age=86400, immutable"
# InstanceStatic needs to be before Plug.Static to be able to override shipped-static files
# If you're adding new paths to `only:` you'll need to configure them in InstanceStatic as well
# Cache-control headers are duplicated in case we turn off etags in the future
plug(
Pleroma.Web.Plugs.InstanceStatic,
at: "/",
from: :pleroma,
only: ["emoji", "images"],
gzip: true,
cache_control_for_etags: @static_cache_control,
headers: %{
"cache-control" => @static_cache_control
}
)
plug(Pleroma.Web.Plugs.FaviconPlug,
at: "/",
only: ["favicon.png"],
cache_control_for_etags: @favicon_cache_control,
headers: %{
"cache-control" => @favicon_cache_control
}
)
plug(Pleroma.Web.Plugs.InstanceStatic,
at: "/",
gzip: true,
cache_control_for_etags: @static_cache_disabled,
headers: %{
"cache-control" => @static_cache_disabled
}
)
plug(Pleroma.Web.Plugs.FrontendStatic,
at: "/",
frontend_type: :primary,
only: ["index.html"],
gzip: true,
cache_control_for_etags: @static_cache_disabled,
headers: %{
"cache-control" => @static_cache_disabled
}
)
plug(Pleroma.Web.Plugs.FrontendStatic,
at: "/",
frontend_type: :primary,
gzip: true,
cache_control_for_etags: @static_cache_control,
headers: %{
"cache-control" => @static_cache_control
}
)
plug(Plug.Static.IndexHtml, at: "/pleroma/admin/")
plug(Pleroma.Web.Plugs.FrontendStatic,
at: "/pleroma/admin",
frontend_type: :admin,
gzip: true,
cache_control_for_etags: @static_cache_disabled,
headers: %{
"cache-control" => @static_cache_disabled
}
)
# Serve at "/" the static files from "priv/static" directory.
#
# You should set gzip to true if you are running phoenix.digest
# when deploying your static files in production.
plug(
Plug.Static,
at: "/",
from: :pleroma,
only: Pleroma.Constants.static_only_files(),
# credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
gzip: true,
cache_control_for_etags: @static_cache_disabled,
headers: %{
"cache-control" => @static_cache_disabled
}
)
plug(Plug.Static,
at: "/pleroma/admin/",
from: {:pleroma, "priv/static/adminfe/"}
)
+ plug(Pleroma.Web.Plugs.StaticNotFoundPlug,
+ at: "/",
+ cache_control_for_etags: @static_cache_disabled,
+ headers: %{
+ "cache-control" => @static_cache_disabled
+ }
+ )
+
# Code reloading can be explicitly enabled under the
# :code_reloader configuration of your endpoint.
if code_reloading? do
plug(Phoenix.CodeReloader)
end
plug(Pleroma.Web.Plugs.TrailingFormatPlug)
plug(Plug.RequestId)
plug(Plug.Logger, log: :debug)
plug(Plug.Parsers,
parsers: [:urlencoded, Pleroma.Web.Multipart, :json],
pass: ["*/*"],
json_decoder: Jason,
# Note: this is compile-time only, won't work for database-config
length: Config.get([:instance, :upload_limit]),
body_reader: {Pleroma.Web.Plugs.DigestPlug, :read_body, []}
)
plug(Plug.MethodOverride)
plug(Plug.Head)
secure_cookies = Config.get([__MODULE__, :secure_cookie_flag])
cookie_name =
if secure_cookies,
do: "__Host-pleroma_key",
else: "pleroma_key"
extra =
Enum.join(Config.get([__MODULE__, :extra_cookie_attrs]), ";")
# The session will be stored in the cookie and signed,
# this means its contents can be read but not tampered with.
# Set :encryption_salt if you would also like to encrypt it.
plug(
Plug.Session,
store: :cookie,
key: cookie_name,
signing_salt: Config.get([__MODULE__, :signing_salt], "CqaoopA2"),
http_only: true,
secure: secure_cookies,
extra: extra
)
plug(Pleroma.Web.Plugs.RemoteIp)
plug(Pleroma.Web.Router)
@doc """
Dynamically loads configuration from the system environment
on startup.
It receives the endpoint configuration from the config files
and must return the updated configuration.
"""
def load_from_system_env(config) do
port = System.get_env("PORT") || raise "expected the PORT environment variable to be set"
{:ok, Keyword.put(config, :http, [:inet6, port: port])}
end
def websocket_url do
String.replace_leading(url(), "http", "ws")
end
end
diff --git a/lib/pleroma/web/plugs/instance_static.ex b/lib/pleroma/web/plugs/instance_static.ex
index 948188287..d2a674d39 100644
--- a/lib/pleroma/web/plugs/instance_static.ex
+++ b/lib/pleroma/web/plugs/instance_static.ex
@@ -1,102 +1,75 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.InstanceStatic do
require Pleroma.Constants
- import Plug.Conn, only: [put_resp_header: 3, put_status: 2, send_resp: 3, halt: 1]
+ import Plug.Conn, only: [put_resp_header: 3]
@moduledoc """
This is a shim to call `Plug.Static` but with runtime `from` configuration.
Mountpoints are defined directly in the module to avoid calling the configuration for every request including non-static ones.
"""
@behaviour Plug
def file_path(path, frontend_type \\ :primary) do
instance_path =
Path.join(Pleroma.Config.get([:instance, :static_dir], "instance/static/"), path)
frontend_path = Pleroma.Web.Plugs.FrontendStatic.file_path(path, frontend_type)
(File.exists?(instance_path) && instance_path) ||
(frontend_path && File.exists?(frontend_path) && frontend_path) ||
Path.join(Application.app_dir(:pleroma, "priv/static/"), path)
end
def init(opts) do
opts
|> Keyword.put(:from, "__unconfigured_instance_static_plug")
|> Plug.Static.init()
end
for only <- Pleroma.Constants.static_only_files() do
def call(%{request_path: "/" <> unquote(only) <> _} = conn, opts) do
call_static(
conn,
opts,
Pleroma.Config.get([:instance, :static_dir], "instance/static")
)
end
end
def call(conn, _) do
conn
end
defp call_static(conn, opts, from) do
# Prevent content-type spoofing by setting content_types: false
opts =
opts
|> Map.put(:from, from)
|> Map.put(:content_types, false)
- conn =
- conn
- |> set_content_type(conn.request_path)
- |> Plug.Static.call(opts)
-
- if conn.halted do
- conn
- else
- path = String.trim_leading(conn.request_path, "/")
-
- if not File.exists?(file_path(path)) do
- conn
- |> put_status(:not_found)
- |> send_404()
- |> halt()
- else
- conn
- end
- end
- end
+ conn = set_content_type(conn, conn.request_path)
- defp send_404(conn) do
- if String.ends_with?(String.downcase(conn.request_path), ".json") do
- conn
- |> put_resp_header("content-type", "application/json")
- |> send_resp(404, Jason.encode!(%{error: "not found"}))
- else
- conn
- |> put_resp_header("content-type", "text/plain")
- |> send_resp(404, "Not found")
- end
+ # Call Plug.Static with our sanitized content-type
+ Plug.Static.call(conn, opts)
end
defp set_content_type(conn, "/emoji/" <> filepath) do
real_mime = MIME.from_path(filepath)
clean_mime =
Pleroma.Web.Plugs.Utils.get_safe_mime_type(%{allowed_mime_types: ["image"]}, real_mime)
put_resp_header(conn, "content-type", clean_mime)
end
defp set_content_type(conn, filepath) do
real_mime = MIME.from_path(filepath)
put_resp_header(conn, "content-type", real_mime)
end
end
# I think this needs to be uncleaned except for emoji.
diff --git a/lib/pleroma/web/plugs/static_not_found_plug.ex b/lib/pleroma/web/plugs/static_not_found_plug.ex
new file mode 100644
index 000000000..e2e7a622c
--- /dev/null
+++ b/lib/pleroma/web/plugs/static_not_found_plug.ex
@@ -0,0 +1,38 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2026 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.StaticNotFoundPlug do
+ @moduledoc """
+ A small plug that enforces returning 404 on static files when they don't exist.
+ """
+ @behaviour Plug
+
+ require Pleroma.Constants
+ import Plug.Conn, only: [put_resp_header: 3, send_resp: 3, halt: 1]
+
+ def init(opts), do: opts
+
+ for only <- Pleroma.Constants.static_only_files() do
+ def call(%{request_path: "/" <> unquote(only) <> _} = conn, _opts) do
+ send_404(conn)
+ end
+ end
+
+ def call(conn, _) do
+ conn
+ end
+
+ defp send_404(conn) do
+ if String.ends_with?(String.downcase(conn.request_path), ".json") do
+ conn
+ |> put_resp_header("content-type", "application/json")
+ |> send_resp(404, Jason.encode!(%{error: "not found"}))
+ else
+ conn
+ |> put_resp_header("content-type", "text/plain")
+ |> send_resp(404, "Not found")
+ end
+ |> halt()
+ end
+end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Aug 9, 7:41 AM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1724335
Default Alt Text
(10 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment