fix(http): drop the partial body from truncated-read errors

Hackney 4.9 returns {:error, {:closed, partial}}. RelMe caches errors,
so it would keep up to max_body bytes per URL.
This commit is contained in:
Lain Soykaf 2026-10-26 22:02:18 +04:00
commit 48ec8518a3
No known key found for this signature in database
2 changed files with 16 additions and 0 deletions

View file

@ -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)

View file

@ -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"}]) ==