logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

uploaded_media.ex (2984B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.Plugs.UploadedMedia do
  5. @moduledoc """
  6. """
  7. import Plug.Conn
  8. import Pleroma.Web.Gettext
  9. require Logger
  10. alias Pleroma.Web.MediaProxy
  11. @behaviour Plug
  12. # no slashes
  13. @path "media"
  14. @default_cache_control_header "public, max-age=1209600"
  15. def init(_opts) do
  16. static_plug_opts =
  17. [
  18. headers: %{"cache-control" => @default_cache_control_header},
  19. cache_control_for_etags: @default_cache_control_header
  20. ]
  21. |> Keyword.put(:from, "__unconfigured_media_plug")
  22. |> Keyword.put(:at, "/__unconfigured_media_plug")
  23. |> Plug.Static.init()
  24. %{static_plug_opts: static_plug_opts}
  25. end
  26. def call(%{request_path: <<"/", @path, "/", file::binary>>} = conn, opts) do
  27. conn =
  28. case fetch_query_params(conn) do
  29. %{query_params: %{"name" => name}} = conn ->
  30. name = String.replace(name, ~s["], ~s[\\"])
  31. put_resp_header(conn, "content-disposition", ~s[inline; filename="#{name}"])
  32. conn ->
  33. conn
  34. end
  35. |> merge_resp_headers([{"content-security-policy", "sandbox"}])
  36. config = Pleroma.Config.get(Pleroma.Upload)
  37. with uploader <- Keyword.fetch!(config, :uploader),
  38. proxy_remote = Keyword.get(config, :proxy_remote, false),
  39. {:ok, get_method} <- uploader.get_file(file),
  40. false <- media_is_banned(conn, get_method) do
  41. get_media(conn, get_method, proxy_remote, opts)
  42. else
  43. _ ->
  44. conn
  45. |> send_resp(:internal_server_error, dgettext("errors", "Failed"))
  46. |> halt()
  47. end
  48. end
  49. def call(conn, _opts), do: conn
  50. defp media_is_banned(%{request_path: path} = _conn, {:static_dir, _}) do
  51. MediaProxy.in_banned_urls(Pleroma.Upload.base_url() <> path)
  52. end
  53. defp media_is_banned(_, {:url, url}), do: MediaProxy.in_banned_urls(url)
  54. defp media_is_banned(_, _), do: false
  55. defp get_media(conn, {:static_dir, directory}, _, opts) do
  56. static_opts =
  57. Map.get(opts, :static_plug_opts)
  58. |> Map.put(:at, [@path])
  59. |> Map.put(:from, directory)
  60. conn = Plug.Static.call(conn, static_opts)
  61. if conn.halted do
  62. conn
  63. else
  64. conn
  65. |> send_resp(:not_found, dgettext("errors", "Not found"))
  66. |> halt()
  67. end
  68. end
  69. defp get_media(conn, {:url, url}, true, _) do
  70. proxy_opts = [
  71. http: [
  72. follow_redirect: true,
  73. pool: :upload
  74. ]
  75. ]
  76. conn
  77. |> Pleroma.ReverseProxy.call(url, proxy_opts)
  78. end
  79. defp get_media(conn, {:url, url}, _, _) do
  80. conn
  81. |> Phoenix.Controller.redirect(external: url)
  82. |> halt()
  83. end
  84. defp get_media(conn, unknown, _, _) do
  85. Logger.error("#{__MODULE__}: Unknown get strategy: #{inspect(unknown)}")
  86. conn
  87. |> send_resp(:internal_server_error, dgettext("errors", "Internal Error"))
  88. |> halt()
  89. end
  90. end