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

Add axum example #54

Merged
merged 2 commits into from
Mar 12, 2025
Merged

Add axum example #54

merged 2 commits into from
Mar 12, 2025

Conversation

SabrinaJewson
Copy link
Contributor

This example bridges TlsListener with axum::serve.

One can also bypass axum::serve and use the Router with Hyper's serve_connection API directly. The main advantages of using axum::serve are that

  • graceful shutdown is made easy with axum's .with_graceful_shutdown API, and
  • the Hyper server is configured by axum itself, allowing options specific to axum to be set (for example, axum currently enables the CONNECT protocol in order to support HTTP/2 websockets).

There are a couple slight papercuts I encountered when writing this example. In particular:

  • TlsListener provides no way to access the underlying listener, meaning .local_addr() has to be implemented by caching the address instead of calling a hypothetical .inner.listener().local_addr(). This seems fairly easy to fix.
  • Because tls_listener::AsyncAccept is poll-based while axum’s Listener trait is async-based, it is not possible to easily bridge axum's existing error-handling logic with this crate; hence, I opted to simply copy-paste the code. Maybe it would be nice if axum exposed handle_connection_error in its public API.

@SabrinaJewson SabrinaJewson changed the title Axum Add axum example Mar 7, 2025
@tmccombs tmccombs merged commit fd3793a into tmccombs:main Mar 12, 2025
13 checks passed
@tmccombs
Copy link
Owner

Thanks for adding this!

TlsListener provides no way to access the underlying listener, meaning .local_addr() has to be implemented by caching the address instead of calling a hypothetical .inner.listener().local_addr(). This seems fairly easy to fix.

Yep. Done in #55

Because tls_listener::AsyncAccept is poll-based while axum’s Listener trait is async-based, it is not possible to easily bridge axum's existing error-handling logic with this crate

Well, that's a little annoying.

I don't think it would be too difficult to make an adapter from something that returns Futures (like axum's Listener trait) to AsyncAccept, that just stores and polls the next future.

@SabrinaJewson
Copy link
Contributor Author

SabrinaJewson commented Mar 12, 2025

I don't think it would be too difficult to make an adapter from something that returns Futures (like axum's Listener trait) to AsyncAccept, that just stores and polls the next future.

The probem is that such a type would have to be self-referential, since the future returned by axum’s accept borrows from self. Your best bet would be using a boxed stream with async_stream, or spawning the Listener in a task and receiving the results via an mpsc::channel. I started on the latter solution, but I thought it probably wasn’t worth the effort over copying and pasting.

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.

2 participants