summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfeld <feld@feld.me>2024-06-05 12:18:56 +0000
committerfeld <feld@feld.me>2024-06-05 12:18:56 +0000
commitbf8b251dc16b5730f384daf19a0c6ce02391c92e (patch)
treec00dcc72106dab2df8fba2f979819b30514472d6
parentacde8d0e0c5ca954b71ec9425f9a0904113938c9 (diff)
parent858d528cc1b551e23850a4b65eb43e44a2a18cf4 (diff)
downloadpleroma-bf8b251dc16b5730f384daf19a0c6ce02391c92e.tar.gz
pleroma-bf8b251dc16b5730f384daf19a0c6ce02391c92e.zip
Merge branch 'cowboy-streaming' into 'develop'
Allow Cowboy to stream the response instead of chunk it See merge request pleroma/pleroma!4138
-rw-r--r--changelog.d/cowboy-stream-chunked.fix1
-rw-r--r--lib/pleroma/reverse_proxy.ex16
2 files changed, 16 insertions, 1 deletions
diff --git a/changelog.d/cowboy-stream-chunked.fix b/changelog.d/cowboy-stream-chunked.fix
new file mode 100644
index 000000000..07211bf18
--- /dev/null
+++ b/changelog.d/cowboy-stream-chunked.fix
@@ -0,0 +1 @@
+Restore Cowboy's ability to stream MediaProxy responses without Chunked encoding.
diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex
index 4d13e51fc..8aec4ae58 100644
--- a/lib/pleroma/reverse_proxy.ex
+++ b/lib/pleroma/reverse_proxy.ex
@@ -8,7 +8,7 @@ defmodule Pleroma.ReverseProxy do
~w(if-unmodified-since if-none-match) ++ @range_headers
@resp_cache_headers ~w(etag date last-modified)
@keep_resp_headers @resp_cache_headers ++
- ~w(content-type content-disposition content-encoding) ++
+ ~w(content-length content-type content-disposition content-encoding) ++
~w(content-range accept-ranges vary)
@default_cache_control_header "public, max-age=1209600"
@valid_resp_codes [200, 206, 304]
@@ -180,6 +180,7 @@ defmodule Pleroma.ReverseProxy do
result =
conn
|> put_resp_headers(build_resp_headers(headers, opts))
+ |> streaming_compat
|> send_chunked(status)
|> chunk_reply(client, opts)
@@ -417,4 +418,17 @@ defmodule Pleroma.ReverseProxy do
@cachex.put(:failed_proxy_url_cache, url, true, ttl: ttl)
end
+
+ # When Cowboy handles a chunked response with a content-length header it streams
+ # over HTTP 1.1 instead of chunking. Bandit cannot stream over HTTP 1.1 so the header
+ # must be stripped or it breaks RFC compliance for Transfer Encoding: Chunked. RFC9112ยง6.2
+ #
+ # HTTP2 is always streamed for all adapters.
+ defp streaming_compat(conn) do
+ with Phoenix.Endpoint.Cowboy2Adapter <- Pleroma.Web.Endpoint.config(:adapter) do
+ conn
+ else
+ _ -> delete_resp_header(conn, "content-length")
+ end
+ end
end