Ensure Gun is Gone
[akkoma] / lib / pleroma / web / rich_media / helpers.ex
index 084a664661ac7254d3a035739227934d2446f410..061c1a79530c94e6233967a5dc85d19a6dca9a13 100644 (file)
@@ -10,9 +10,8 @@ defmodule Pleroma.Web.RichMedia.Helpers do
   alias Pleroma.Web.RichMedia.Parser
 
   @options [
-    pool: :media,
     max_body: 2_000_000,
-    recv_timeout: 2_000
+    receive_timeout: 2_000
   ]
 
   @spec validate_page_url(URI.t() | binary()) :: :ok | :error
@@ -57,7 +56,6 @@ defmodule Pleroma.Web.RichMedia.Helpers do
 
   def fetch_data_for_object(object) do
     with true <- Config.get([:rich_media, :enabled]),
-         false <- object.data["sensitive"] || false,
          {:ok, page_url} <-
            HTML.extract_first_external_url_from_object(object),
          :ok <- validate_page_url(page_url),
@@ -70,7 +68,7 @@ defmodule Pleroma.Web.RichMedia.Helpers do
 
   def fetch_data_for_activity(%Activity{data: %{"type" => "Create"}} = activity) do
     with true <- Config.get([:rich_media, :enabled]),
-         %Object{} = object <- Object.normalize(activity) do
+         %Object{} = object <- Object.normalize(activity, fetch: false) do
       fetch_data_for_object(object)
     else
       _ -> %{}
@@ -79,14 +77,53 @@ defmodule Pleroma.Web.RichMedia.Helpers do
 
   def fetch_data_for_activity(_), do: %{}
 
-  def perform(:fetch, %Activity{} = activity) do
-    fetch_data_for_activity(activity)
-    :ok
-  end
-
   def rich_media_get(url) do
     headers = [{"user-agent", Pleroma.Application.user_agent() <> "; Bot"}]
 
-    Pleroma.HTTP.get(url, headers, adapter: @options)
+    head_check =
+      case Pleroma.HTTP.head(url, headers, @options) do
+        # If the HEAD request didn't reach the server for whatever reason,
+        # we assume the GET that comes right after won't either
+        {:error, _} = e ->
+          e
+
+        {:ok, %Tesla.Env{status: 200, headers: headers}} ->
+          with :ok <- check_content_type(headers),
+               :ok <- check_content_length(headers),
+               do: :ok
+
+        _ ->
+          :ok
+      end
+
+    with :ok <- head_check, do: Pleroma.HTTP.get(url, headers, @options)
+  end
+
+  defp check_content_type(headers) do
+    case List.keyfind(headers, "content-type", 0) do
+      {_, content_type} ->
+        case Plug.Conn.Utils.media_type(content_type) do
+          {:ok, "text", "html", _} -> :ok
+          _ -> {:error, {:content_type, content_type}}
+        end
+
+      _ ->
+        :ok
+    end
+  end
+
+  @max_body @options[:max_body]
+  defp check_content_length(headers) do
+    case List.keyfind(headers, "content-length", 0) do
+      {_, maybe_content_length} ->
+        case Integer.parse(maybe_content_length) do
+          {content_length, ""} when content_length <= @max_body -> :ok
+          {_, ""} -> {:error, :body_too_large}
+          _ -> :ok
+        end
+
+      _ ->
+        :ok
+    end
   end
 end