use tako_rs_core::router::Router;
use super::handle::ServerHandle;
use super::spawn::make_handle;
use super::spawn::spawn_done_compio;
#[cfg(feature = "compio-tls")]
use super::spawn::tls_alpn_for_tcp;
#[cfg(feature = "compio-tls")]
use super::tls_cert::TlsCert;
#[cfg(feature = "compio-tls")]
use super::tls_cert::build_rustls_server_config;
use crate::ServerConfig;
#[derive(Debug, Default, Clone)]
pub struct CompioServerBuilder {
config: ServerConfig,
#[cfg(feature = "compio-tls")]
tls: Option<TlsCert>,
}
impl CompioServerBuilder {
#[must_use]
pub fn config(mut self, config: ServerConfig) -> Self {
self.config = config;
self
}
#[cfg(feature = "compio-tls")]
#[must_use]
pub fn tls(mut self, cert: TlsCert) -> Self {
self.tls = Some(cert);
self
}
pub fn build(self) -> CompioServer {
CompioServer {
config: self.config,
#[cfg(feature = "compio-tls")]
tls: self.tls,
}
}
}
#[derive(Debug, Clone)]
pub struct CompioServer {
config: ServerConfig,
#[cfg(feature = "compio-tls")]
tls: Option<TlsCert>,
}
impl CompioServer {
#[must_use]
pub fn builder() -> CompioServerBuilder {
CompioServerBuilder::default()
}
#[inline]
pub fn config(&self) -> &ServerConfig {
&self.config
}
pub fn spawn_http(&self, listener: compio::net::TcpListener, router: Router) -> ServerHandle {
self
.try_spawn_http(listener, router)
.unwrap_or_else(|error| super::spawn::failed_handle(error, self.config.drain_timeout))
}
pub fn try_spawn_http(
&self,
listener: compio::net::TcpListener,
router: Router,
) -> Result<ServerHandle, tako_rs_core::types::BoxError> {
#[cfg(feature = "plugins")]
router.setup_plugins_once()?;
let (handle, signal) = make_handle(self.config.drain_timeout, Some(listener.local_addr()?));
spawn_done_compio(
&handle,
crate::server_compio::run(listener, router, Some(signal), self.config.clone()),
);
Ok(handle)
}
#[cfg(feature = "compio-tls")]
pub fn spawn_tls(&self, listener: compio::net::TcpListener, router: Router) -> ServerHandle {
self
.try_spawn_tls(listener, router)
.unwrap_or_else(|error| super::spawn::failed_handle(error, self.config.drain_timeout))
}
#[cfg(feature = "compio-tls")]
pub fn try_spawn_tls(
&self,
listener: compio::net::TcpListener,
router: Router,
) -> Result<ServerHandle, tako_rs_core::types::BoxError> {
let tls = self
.tls
.as_ref()
.ok_or("TLS certificate configuration is required")?;
let tls = build_rustls_server_config(tls, tls_alpn_for_tcp())?;
#[cfg(feature = "plugins")]
router.setup_plugins_once()?;
let (handle, signal) = make_handle(self.config.drain_timeout, Some(listener.local_addr()?));
spawn_done_compio(
&handle,
crate::server_tls_compio::run_with_config(
listener,
router,
tls,
Some(signal),
self.config.clone(),
),
);
Ok(handle)
}
}