diff --git a/lib/pleroma/web/plugs/trailing_format_plug.ex b/lib/pleroma/web/plugs/trailing_format_plug.ex index 652ee45876..8b14500afa 100644 --- a/lib/pleroma/web/plugs/trailing_format_plug.ex +++ b/lib/pleroma/web/plugs/trailing_format_plug.ex @@ -2,6 +2,59 @@ # Copyright © 2017-2024 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only +defmodule TrailingFormatPlug do + @behaviour Plug + + def init(options), do: options + + def call(conn, opts \\ []) + + def call(%{path_info: []} = conn, _opts), do: conn + + def call(conn, opts) do + path = conn.path_info |> List.last() |> String.split(".") |> Enum.reverse() + + supported_formats = Keyword.get(opts, :supported_formats, nil) + + case path do + [_] -> + conn + + [format | fragments] -> + if supported_formats == nil || format in supported_formats do + new_path = fragments |> Enum.reverse() |> Enum.join(".") + path_fragments = List.replace_at(conn.path_info, -1, new_path) + + params = + Plug.Conn.fetch_query_params(conn).params + |> update_params(new_path, format) + |> Map.put("_format", format) + + %{ + conn + | path_info: path_fragments, + query_params: params, + params: params + } + else + conn + end + end + end + + defp update_params(params, new_path, format) do + wildcard = Enum.find(params, fn {_, v} -> v == "#{new_path}.#{format}" end) + + case wildcard do + {key, _} -> + Map.put(params, key, new_path) + + _ -> + params + end + end +end + defmodule Pleroma.Web.Plugs.TrailingFormatPlug do @moduledoc """ This plug is adapted from [`TrailingFormatPlug`](https://github.com/mschae/trailing_format_plug/blob/master/lib/trailing_format_plug.ex). diff --git a/mix.lock b/mix.lock index c051b42042..e4e9ccb62d 100644 --- a/mix.lock +++ b/mix.lock @@ -149,7 +149,6 @@ "thousand_island": {:hex, :thousand_island, "1.3.2", "bc27f9afba6e1a676dd36507d42e429935a142cf5ee69b8e3f90bff1383943cd", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0e085b93012cd1057b378fce40cbfbf381ff6d957a382bfdd5eca1a98eec2535"}, "timex": {:hex, :timex, "3.7.7", "3ed093cae596a410759104d878ad7b38e78b7c2151c6190340835515d4a46b8a", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "0ec4b09f25fe311321f9fc04144a7e3affe48eb29481d7a5583849b6c4dfa0a7"}, "toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"}, - "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"}, "tz_world": {:hex, :tz_world, "1.3.2", "15d331ad1ff22735dfcc8c98bfc7b2a9fdc17f1f071e31e21cdafe2d9318a300", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:geo, "~> 1.0 or ~> 2.0 or ~> 3.3", [hex: :geo, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d1a345e07b3378c4c902ad54fbd5d54c8c3dd55dba883b7407fe57bcec45ff2a"}, "tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"}, "ueberauth": {:hex, :ueberauth, "0.10.7", "5a31cbe11e7ce5c7484d745dc9e1f11948e89662f8510d03c616de03df581ebd", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0bccf73e2ffd6337971340832947ba232877aa8122dba4c95be9f729c8987377"},