diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex index c230cea46..ca9f5368d 100644 --- a/lib/pleroma/http.ex +++ b/lib/pleroma/http.ex @@ -79,8 +79,14 @@ defmodule Pleroma.HTTP do adapter, adapter_opts ) + |> drop_partial_body() end + # Hackney 4.9 returns the bytes read before the peer closed. No caller wants + # them, and callers that cache errors would keep them. + defp drop_partial_body({:error, {:closed, body}}) when is_binary(body), do: {:error, :closed} + defp drop_partial_body(result), do: result + @spec request(Client.t(), keyword()) :: {:ok, Env.t()} | {:error, any()} def request(client, request), do: Tesla.request(client, request) diff --git a/test/pleroma/http_test.exs b/test/pleroma/http_test.exs index e673e6591..436a22447 100644 --- a/test/pleroma/http_test.exs +++ b/test/pleroma/http_test.exs @@ -29,6 +29,10 @@ defmodule Pleroma.HTTPTest do %{method: :post, url: "http://example.com/world"} -> %Tesla.Env{status: 200, body: "world"} + # Hackney 4.9 hands back the bytes it read before the peer closed. + %{method: :get, url: "http://example.com/truncated"} -> + {:error, {:closed, "partial body"}} + %{method: :get, url: "https://example.com/emoji/Pack%201/koronebless.png?foo=bar+baz"} -> %Tesla.Env{status: 200, body: "emoji data"} @@ -81,6 +85,12 @@ defmodule Pleroma.HTTPTest do end end + describe "get/1 with a truncated body" do + test "drops the partial body from the error" do + assert HTTP.get("http://example.com/truncated") == {:error, :closed} + end + end + describe "get/2 (with headers)" do test "returns successfully result for json content-type" do assert HTTP.get("http://example.com/hello", [{"content-type", "application/json"}]) ==