diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/object/fetcher.ex | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index c85a8b09f..41587c116 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -19,6 +19,8 @@ defmodule Pleroma.Object.Fetcher do require Logger require Pleroma.Constants + @mix_env Mix.env() + @spec reinject_object(struct(), map()) :: {:ok, Object.t()} | {:error, any()} defp reinject_object(%Object{data: %{}} = object, new_data) do Logger.debug("Reinjecting object #{new_data["id"]}") @@ -172,6 +174,19 @@ defmodule Pleroma.Object.Fetcher do def fetch_and_contain_remote_object_from_id(_id), do: {:error, "id must be a string"} + defp check_crossdomain_redirect(final_host, original_url) + + # Handle the common case in tests where responses don't include URLs + if @mix_env == :test do + defp check_crossdomain_redirect(nil, _) do + {:cross_domain_redirect, false} + end + end + + defp check_crossdomain_redirect(final_host, original_url) do + {:cross_domain_redirect, final_host != URI.parse(original_url).host} + end + defp get_object(id) do date = Pleroma.Signature.signed_date() @@ -181,19 +196,29 @@ defmodule Pleroma.Object.Fetcher do |> sign_fetch(id, date) case HTTP.get(id, headers) do + {:ok, %{body: body, status: code, headers: headers, url: final_url}} + when code in 200..299 -> + remote_host = if final_url, do: URI.parse(final_url).host, else: nil + + with {:cross_domain_redirect, false} <- check_crossdomain_redirect(remote_host, id), + {_, content_type} <- List.keyfind(headers, "content-type", 0), + {:ok, _media_type} <- verify_content_type(content_type) do + {:ok, body} + else + {:cross_domain_redirect, true} -> + {:error, {:cross_domain_redirect, true}} + + error -> + error + end + + # Handle the case where URL is not in the response (older HTTP library versions) {:ok, %{body: body, status: code, headers: headers}} when code in 200..299 -> case List.keyfind(headers, "content-type", 0) do {_, content_type} -> - case Plug.Conn.Utils.media_type(content_type) do - {:ok, "application", "activity+json", _} -> - {:ok, body} - - {:ok, "application", "ld+json", - %{"profile" => "https://www.w3.org/ns/activitystreams"}} -> - {:ok, body} - - _ -> - {:error, {:content_type, content_type}} + case verify_content_type(content_type) do + {:ok, _} -> {:ok, body} + error -> error end _ -> @@ -216,4 +241,17 @@ defmodule Pleroma.Object.Fetcher do defp safe_json_decode(nil), do: {:ok, nil} defp safe_json_decode(json), do: Jason.decode(json) + + defp verify_content_type(content_type) do + case Plug.Conn.Utils.media_type(content_type) do + {:ok, "application", "activity+json", _} -> + {:ok, :activity_json} + + {:ok, "application", "ld+json", %{"profile" => "https://www.w3.org/ns/activitystreams"}} -> + {:ok, :ld_json} + + _ -> + {:error, {:content_type, content_type}} + end + end end |