total rebase
[anni] / lib / pleroma / web / rich_media / helpers.ex
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
5 defmodule Pleroma.Web.RichMedia.Helpers do
6   alias Pleroma.Config
7
8   def rich_media_get(url) do
9     headers = [{"user-agent", Pleroma.Application.user_agent() <> "; Bot"}]
10
11     head_check =
12       case Pleroma.HTTP.head(url, headers, http_options()) do
13         # If the HEAD request didn't reach the server for whatever reason,
14         # we assume the GET that comes right after won't either
15         {:error, _} = e ->
16           e
17
18         {:ok, %Tesla.Env{status: 200, headers: headers}} ->
19           with :ok <- check_content_type(headers),
20                :ok <- check_content_length(headers),
21                do: :ok
22
23         _ ->
24           :ok
25       end
26
27     with :ok <- head_check, do: Pleroma.HTTP.get(url, headers, http_options())
28   end
29
30   defp check_content_type(headers) do
31     case List.keyfind(headers, "content-type", 0) do
32       {_, content_type} ->
33         case Plug.Conn.Utils.media_type(content_type) do
34           {:ok, "text", "html", _} -> :ok
35           _ -> {:error, {:content_type, content_type}}
36         end
37
38       _ ->
39         :ok
40     end
41   end
42
43   defp check_content_length(headers) do
44     max_body = Keyword.get(http_options(), :max_body)
45
46     case List.keyfind(headers, "content-length", 0) do
47       {_, maybe_content_length} ->
48         case Integer.parse(maybe_content_length) do
49           {content_length, ""} when content_length <= max_body -> :ok
50           {_, ""} -> {:error, :body_too_large}
51           _ -> :ok
52         end
53
54       _ ->
55         :ok
56     end
57   end
58
59   defp http_options do
60     [
61       pool: :media,
62       max_body: Config.get([:rich_media, :max_body], 5_000_000)
63     ]
64   end
65 end