Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions core/lib/src/rocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,19 @@ impl Rocket<Ignite> {
Paint::default(addr).bold().underline());
})).await
}

async fn _launch_with_listener<L>(self, listener: L) -> Result<(), Error>
where
L: crate::http::private::Listener + Send,
<L as crate::http::private::Listener>::Connection: Send + Unpin + 'static,
{
let rkt = self.into_orbit();
rkt.fairings.handle_liftoff(&rkt).await;
launch_info!("{}{}",
Paint::emoji("🚀 "),
Paint::default("Rocket has launched (custom listener)").bold());
rkt.http_server(listener).await
}
}

impl Rocket<Orbit> {
Expand Down Expand Up @@ -844,6 +857,27 @@ impl<P: Phase> Rocket<P> {
State::Orbit(_) => Ok(())
}
}

/// Launch this rocket on a caller-supplied `Listener` instead of the
/// built-in TCP and rustls pair.
///
/// `launch` can only use the transports Rocket ships with, so a
/// caller with its own TLS stack has no way in. This takes any
/// `Listener` and drives the normal ignite-then-serve sequence over
/// it, including liftoff fairings.
pub async fn launch_with_listener<L>(self, listener: L) -> Result<(), Error>
where
L: crate::http::private::Listener + Send,
<L as crate::http::private::Listener>::Connection: Send + Unpin + 'static,
{
match self.0.into_state() {
State::Build(s) => {
Rocket::from(s).ignite().await?._launch_with_listener(listener).await
}
State::Ignite(s) => Rocket::from(s)._launch_with_listener(listener).await,
State::Orbit(_) => Ok(()),
}
}
}

#[doc(hidden)]
Expand Down
6 changes: 4 additions & 2 deletions core/lib/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,10 @@ impl Rocket<Orbit> {
self.http_server(l).await
}

// TODO.async: Solidify the Listener APIs and make this function public
pub(crate) async fn http_server<L>(self, listener: L) -> Result<(), Error>
// Public so a caller supplying its own Listener can reach the accept
// loop; `default_tcp_http_server` remains the built-in path. This is
// the "make this function public" half of the TODO above.
pub async fn http_server<L>(self, listener: L) -> Result<(), Error>
where L: Listener + Send, <L as Listener>::Connection: Send + Unpin + 'static
{
// Determine keep-alives.
Expand Down