tako_rs_server/builder/
compio_server.rs1use tako_rs_core::router::Router;
2
3use super::handle::ServerHandle;
4use super::spawn::make_handle;
5use super::spawn::spawn_done_compio;
6#[cfg(feature = "compio-tls")]
7use super::spawn::tls_alpn_for_tcp;
8#[cfg(feature = "compio-tls")]
9use super::tls_cert::TlsCert;
10#[cfg(feature = "compio-tls")]
11use super::tls_cert::build_rustls_server_config;
12use crate::ServerConfig;
13
14#[derive(Debug, Default, Clone)]
16pub struct CompioServerBuilder {
17 config: ServerConfig,
18 #[cfg(feature = "compio-tls")]
21 tls: Option<TlsCert>,
22}
23
24impl CompioServerBuilder {
25 #[must_use]
27 pub fn config(mut self, config: ServerConfig) -> Self {
28 self.config = config;
29 self
30 }
31
32 #[cfg(feature = "compio-tls")]
34 #[must_use]
35 pub fn tls(mut self, cert: TlsCert) -> Self {
36 self.tls = Some(cert);
37 self
38 }
39
40 pub fn build(self) -> CompioServer {
42 CompioServer {
43 config: self.config,
44 #[cfg(feature = "compio-tls")]
45 tls: self.tls,
46 }
47 }
48}
49
50#[derive(Debug, Clone)]
55pub struct CompioServer {
56 config: ServerConfig,
57 #[cfg(feature = "compio-tls")]
61 tls: Option<TlsCert>,
62}
63
64impl CompioServer {
65 #[must_use]
67 pub fn builder() -> CompioServerBuilder {
68 CompioServerBuilder::default()
69 }
70
71 #[inline]
73 pub fn config(&self) -> &ServerConfig {
74 &self.config
75 }
76
77 pub fn spawn_http(&self, listener: compio::net::TcpListener, router: Router) -> ServerHandle {
79 let (handle, shutdown_fut) = make_handle(self.config.drain_timeout);
80 let config = self.config.clone();
81 spawn_done_compio(handle.done.clone(), async move {
82 crate::server_compio::serve_with_shutdown_and_config(listener, router, shutdown_fut, config)
83 .await;
84 });
85 handle
86 }
87
88 #[cfg(feature = "compio-tls")]
90 pub fn spawn_tls(&self, listener: compio::net::TcpListener, router: Router) -> ServerHandle {
91 let tls = self
92 .tls
93 .clone()
94 .expect("CompioServer::spawn_tls requires a TlsCert (use builder().tls(...))");
95 let (handle, shutdown_fut) = make_handle(self.config.drain_timeout);
96 let config = self.config.clone();
97 let alpn = tls_alpn_for_tcp();
98 spawn_done_compio(handle.done.clone(), async move {
99 if let TlsCert::PemPaths {
100 cert_path,
101 key_path,
102 client_auth: None,
103 } = &tls
104 {
105 crate::server_tls_compio::serve_tls_with_shutdown_and_config(
106 listener,
107 router,
108 Some(cert_path.as_str()),
109 Some(key_path.as_str()),
110 shutdown_fut,
111 config,
112 )
113 .await;
114 return;
115 }
116 let rustls_cfg = match build_rustls_server_config(&tls, alpn) {
117 Ok(c) => c,
118 Err(e) => {
119 tracing::error!("CompioServer::spawn_tls: failed to build rustls config: {e}");
120 return;
121 }
122 };
123 crate::server_tls_compio::serve_tls_with_rustls_config_and_shutdown(
124 listener,
125 router,
126 rustls_cfg,
127 shutdown_fut,
128 config,
129 )
130 .await;
131 });
132 handle
133 }
134}