Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support returning {:ok, payload} from adapter.inform/3 #1193

Merged
merged 3 commits into from
Nov 23, 2023

Conversation

wojtekmach
Copy link
Contributor

@wojtekmach wojtekmach commented Nov 22, 2023

There is a minor Bandit bug where it looks like it does not support inform but it definitely does. Turns out using Plug.Conn.inform/3 worked but inform!/3 did not. The bug in Bandit was wrong return value which went unchecked in inform/3 but got incorrectly interpreted in inform!/3.

This is not a breaking change for inform!/3 as we were already raising but it could be considered a breaking change for inform/3 but in this particular case it seemed warranted to me.

cc @mtrudel

@mtrudel
Copy link
Contributor

mtrudel commented Nov 22, 2023

It'd actually be real nice if we could instead add a match on {:ok, adapter} and return that back to the caller. As it is this makes it impossible to track state (namely metrics) past an inform call. WDYT?

@wojtekmach
Copy link
Contributor Author

@mtrudel to be a bit more precise, do you have something like this in mind?

  def inform(%Conn{} = conn, status, headers \\ []) do
    status_code = Plug.Conn.Status.code(status)
    adapter_inform(conn, status_code, headers)
-   conn
  end

  # simplified for brevity
  defp adapter_inform(%Conn{adapter: {adapter, payload}}, status, headers) do
-   :ok = adapter.inform(payload, status, headers)
+   {:ok, payload} = adapter.inform(payload, status, headers)
+   put_in(conn.adapter, {adapter, payload})
  end

With almost zero knowledge about this side of Plug, this looks sensible to me. 😅

@mtrudel
Copy link
Contributor

mtrudel commented Nov 22, 2023

Conceptually, yeah. Though in an additive sense (with a case statement) so as to be backwards compatible. Like here (and without the change to the private function further down)

@wojtekmach wojtekmach changed the title Check adapter return value in Plug.Conn.inform/3 Support returning {:ok, payload} from adapter.inform/3 Nov 23, 2023
@wojtekmach
Copy link
Contributor Author

I believe this is ready. I renamed the PR to "Support returning {:ok, payload} from adapter.inform/3".

Comment on lines +1333 to +1334
{:error, :not_supported} ->
conn
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add a catch-all clause for backwards compatibility, let me know. If so perhaps with a warning?

Suggested change
{:error, :not_supported} ->
conn
{:error, :not_supported} ->
conn
_other ->
conn

there's no need for a catch-all clause in inform!/3 as it already was rasing.

@josevalim josevalim merged commit ec9f45b into elixir-plug:main Nov 23, 2023
2 checks passed
@josevalim
Copy link
Member

💚 💙 💜 💛 ❤️

@wojtekmach wojtekmach deleted the wm-strict-inform branch November 23, 2023 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants