Skip to content

Implement a more comprehensive way to get connection information #1269

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

Merged
merged 4 commits into from
May 24, 2025

Conversation

mtrudel
Copy link
Contributor

@mtrudel mtrudel commented May 13, 2025

Scope of changes:

  • Add optional c:Plug.Conn.Adapter.get_sock_data/1 and c:Plug.Conn.Adapter.get_ssl_data/1 callbacks
  • Add Plug.Conn.get_sock_data/1 and Plug.Conn.get_ssl_data/1

@mtrudel
Copy link
Contributor Author

mtrudel commented May 13, 2025

Hrm. Looking into the work required to implement this in Cowboy, it's not insignificant. Cowboy easily provides all of the existing info in peer_data, but basically nothing else (I suspect that this is probably why the existing Plug.Conn.Adapter contract looks the way it does). It'd be a whole set of kinda subtle PRs all the way up to Ranch to get this information sourced, for what amounts to a pretty niche use case. Not entirely sure this is a good use of effort, TBH.

WDYT?

@ns-blee
Copy link

ns-blee commented May 19, 2025

Out of curiosity here... It is not possible to do an adapter check, return nil if Cowboy, and the value if Bandit? Or is the expectation that it will remain agnostic? If so, is there not some way to expose the methods and allow the user to do the adapter check, if needed, though implied? Without access I will be forced to use a proxy and handle TLS termination there so I can inject the values in the stream...

Copy link
Member

@josevalim josevalim left a comment

Choose a reason for hiding this comment

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

LGTM! Just two tiny comments.

@mtrudel
Copy link
Contributor Author

mtrudel commented May 23, 2025

Out of curiosity here... It is not possible to do an adapter check, return nil if Cowboy, and the value if Bandit?

I think the better option here might be to make get_connection_data/1 optional on the Adapter behaviour and keep the Plug.Conn plumbing for get_peer_data/1 as-is (at least until someone gets the relevant work done upstream in Cowboy). I can write up the Plug.Conn.get_connection_data/1 function to return {:error, :not_supported}, similar to how we used to do push promises before we deprecated them.

@josevalim
Copy link
Member

I think the better option here might be to make get_connection_data/1 optional on the Adapter behaviour and keep the Plug.Conn plumbing for get_peer_data/1 as-is (at least until someone gets the relevant work done upstream in Cowboy).

We could also make the other keys in connection_data optional. Both options are fine by me!

@mtrudel mtrudel force-pushed the add_connection_info branch from d02c753 to 9d2a226 Compare May 23, 2025 21:23
@mtrudel
Copy link
Contributor Author

mtrudel commented May 23, 2025

Trying a different tack here with separate get_peer_data/1. get_sock_data/1 and get_ssl_data/1 callbacks that I think is a whole lot simpler (and doesn't require and upstream changes in Plug.Cowboy at all).

lib/plug/conn.ex Outdated
Comment on lines 649 to 665
raise "get_sock_data not supported by #{inspect(adapter)}." <>
"You should either delete the call to `get_sock_data/1` or switch to an " <>
"adapter that does support this call such as Bandit."
end
end

@doc """
Returns SSL data for the connection if present. If the connection is not SSL, returns nil
"""
@spec get_ssl_data(t) :: Plug.Conn.Adapter.ssl_data()
def get_ssl_data(%Conn{adapter: {adapter, payload}}) do
if function_exported?(adapter, :get_ssl_data, 1) do
adapter.get_ssl_data(payload)
else
raise "get_ssl_data not supported by #{inspect(adapter)}." <>
"You should either delete the call to `get_ssl_data/1` or switch to an " <>
"adapter that does support this call such as Bandit."
Copy link
Member

Choose a reason for hiding this comment

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

Mostly to keep ti adapter agnostic :)

Suggested change
raise "get_sock_data not supported by #{inspect(adapter)}." <>
"You should either delete the call to `get_sock_data/1` or switch to an " <>
"adapter that does support this call such as Bandit."
end
end
@doc """
Returns SSL data for the connection if present. If the connection is not SSL, returns nil
"""
@spec get_ssl_data(t) :: Plug.Conn.Adapter.ssl_data()
def get_ssl_data(%Conn{adapter: {adapter, payload}}) do
if function_exported?(adapter, :get_ssl_data, 1) do
adapter.get_ssl_data(payload)
else
raise "get_ssl_data not supported by #{inspect(adapter)}." <>
"You should either delete the call to `get_ssl_data/1` or switch to an " <>
"adapter that does support this call such as Bandit."
raise "get_sock_data not supported by #{inspect(adapter)}"
end
end
@doc """
Returns SSL data for the connection if present. If the connection is not SSL, returns nil
"""
@spec get_ssl_data(t) :: Plug.Conn.Adapter.ssl_data()
def get_ssl_data(%Conn{adapter: {adapter, payload}}) do
if function_exported?(adapter, :get_ssl_data, 1) do
adapter.get_ssl_data(payload)
else
raise "get_ssl_data not supported by #{inspect(adapter)}"

Copy link
Member

@josevalim josevalim left a comment

Choose a reason for hiding this comment

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

Minor nits and we can ship this!!!

mtrudel and others added 2 commits May 24, 2025 10:58
@mtrudel mtrudel marked this pull request as ready for review May 24, 2025 14:59
@mtrudel
Copy link
Contributor Author

mtrudel commented May 24, 2025

Ready for review - since the new callbacks are optional this can go out anytime and underlying support can come out on its own schedule (I'll be getting Bandit's support done in the next few days, bad weather permitting)

@josevalim josevalim merged commit 8abdd30 into elixir-plug:main May 24, 2025
2 checks passed
@josevalim
Copy link
Member

💚 💙 💜 💛 ❤️

@mtrudel
Copy link
Contributor Author

mtrudel commented May 24, 2025

Aw shoot sorry I missed those changes - GitHub stacked all of your suggestions such that I had to do them manually.

@josevalim
Copy link
Member

josevalim commented May 24, 2025 via email

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