From 7b7f1fd6b480dc1937b666a437570f07d7b8f687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 1 Oct 2023 20:31:02 +0200 Subject: [PATCH] Revert "Add `Plug.Conn.register_before_chunk/2` (#1154)" This reverts commit 8bff7c193aa8517e2d4c14a15df4a98dfa6c2ce7. --- lib/plug/conn.ex | 43 --------------------------------- test/plug/conn_test.exs | 53 ----------------------------------------- 2 files changed, 96 deletions(-) diff --git a/lib/plug/conn.ex b/lib/plug/conn.ex index 1a0bcd53..54997b0a 100644 --- a/lib/plug/conn.ex +++ b/lib/plug/conn.ex @@ -551,8 +551,6 @@ defmodule Plug.Conn do """ @spec chunk(t, body) :: {:ok, t} | {:error, term} | no_return def chunk(%Conn{adapter: {adapter, payload}, state: :chunked} = conn, chunk) do - conn = run_before_chunk(conn, chunk) - if iodata_empty?(chunk) do {:ok, conn} else @@ -1808,36 +1806,6 @@ defmodule Plug.Conn do update_in(conn.private[:before_send], &[callback | &1 || []]) end - @doc ~S""" - Registers a callback to be invoked before a chunk is sent by `chunk/2`. - - Callbacks are invoked in the reverse order they are registered, that is, callbacks which - are registered first are invoked last. - - ## Examples - - This example logs the size of the chunk about to be sent: - - register_before_chunk(conn, fn _conn, chunk -> - Logger.info("Sending #{IO.iodata_length(chunk)} bytes") - conn - end) - - """ - @doc since: "1.15.0" - @spec register_before_chunk(t, (t, body -> t)) :: t - def register_before_chunk(conn, callback) - - def register_before_chunk(%Conn{state: state}, _callback) - when state not in @unsent do - raise AlreadySentError - end - - def register_before_chunk(%Conn{} = conn, callback) - when is_function(callback, 2) do - update_in(conn.private[:before_chunk], &[callback | &1 || []]) - end - @doc """ Halts the `Plug` pipeline by preventing further plugs downstream from being invoked. See the docs for `Plug.Builder` for more information on halting a @@ -1874,17 +1842,6 @@ defmodule Plug.Conn do %{conn | resp_headers: merge_headers(conn.resp_headers, conn.resp_cookies)} end - defp run_before_chunk(%Conn{private: private} = conn, chunk) do - initial_state = conn.state - conn = Enum.reduce(private[:before_chunk] || [], conn, & &1.(&2, chunk)) - - if conn.state != initial_state do - raise ArgumentError, "cannot send or change response from run_before_chunk/2 callback" - end - - %{conn | resp_headers: merge_headers(conn.resp_headers, conn.resp_cookies)} - end - defp merge_headers(headers, cookies) do Enum.reduce(cookies, headers, fn {key, opts}, acc -> value = diff --git a/test/plug/conn_test.exs b/test/plug/conn_test.exs index aaad463a..d71b6399 100644 --- a/test/plug/conn_test.exs +++ b/test/plug/conn_test.exs @@ -405,51 +405,6 @@ defmodule Plug.ConnTest do assert get_resp_header(conn, "x-body") == ["CHUNK"] end - test "chunk/2 runs before_chunk callbacks" do - pid = self() - - conn(:get, "/foo") - |> register_before_chunk(fn conn, chunk -> - send(pid, {:before_chunk, 1, chunk}) - conn - end) - |> register_before_chunk(fn conn, chunk -> - send(pid, {:before_chunk, 2, chunk}) - conn - end) - |> send_chunked(200) - |> chunk("CHUNK") - - # We need to match with n1 and n2 because if we match directly on 1 and 2 then - # selective receive will match on the messages even if they're out of order. - assert_receive {:before_chunk, n1, "CHUNK"} - assert_receive {:before_chunk, n2, "CHUNK"} - assert n1 == 2 - assert n2 == 1 - end - - test "chunk/2 uses the updated conn from before_chunk callbacks" do - pid = self() - - conn = - conn(:get, "/foo") - |> assign(:test_counter, 0) - |> register_before_chunk(fn conn, _chunk -> - {count, conn} = get_and_update_in(conn.assigns[:test_counter], &{&1, &1 + 1}) - send(pid, {:before_chunk, count}) - conn - end) - |> send_chunked(200) - - assert {:ok, conn} = chunk(conn, "CHUNK") - assert {:ok, conn} = chunk(conn, "CHUNK") - assert {:ok, _conn} = chunk(conn, "CHUNK") - - assert_received {:before_chunk, 0} - assert_received {:before_chunk, 1} - assert_received {:before_chunk, 2} - end - test "inform/3 performs an informational request" do conn = conn(:get, "/foo") |> inform(103, [{"link", "; rel=preload; as=style"}]) assert {103, [{"link", "; rel=preload; as=style"}]} in sent_informs(conn) @@ -1454,14 +1409,6 @@ defmodule Plug.ConnTest do end end - test "register_before_chunk/2 raises when a response has already been sent" do - conn = send_resp(conn(:get, "/"), 200, "ok") - - assert_raise Plug.Conn.AlreadySentError, fn -> - register_before_chunk(conn, fn _ -> nil end) - end - end - test "does not delegate to connections' adapter's chunk/2 when called with an empty chunk" do defmodule RaisesOnEmptyChunkAdapter do defdelegate send_chunked(state, status, headers), to: Plug.Adapters.Test.Conn