capnweb_server/
h3_server.rs1use crate::Server;
2use quinn::{Endpoint, ServerConfig as QuinnServerConfig};
3use std::net::SocketAddr;
4use std::sync::Arc;
5use tracing::info;
6
7pub struct H3Server {
9 #[allow(dead_code)]
10 server: Arc<Server>,
11 endpoint: Option<Endpoint>,
12}
13
14impl H3Server {
15 pub fn new(server: Arc<Server>) -> Self {
17 Self {
18 server,
19 endpoint: None,
20 }
21 }
22
23 pub async fn listen(&mut self, addr: SocketAddr) -> Result<(), Box<dyn std::error::Error>> {
25 let server_config = configure_server()?;
27
28 let endpoint = Endpoint::server(server_config, addr)?;
30 info!("HTTP/3 server listening on {}", addr);
31
32 self.endpoint = Some(endpoint.clone());
33
34 while let Some(_incoming) = endpoint.accept().await {
37 }
39
40 Ok(())
41 }
42
43 pub fn shutdown(&mut self) {
45 if let Some(endpoint) = &self.endpoint {
46 endpoint.close(0u32.into(), b"server shutdown");
47 }
48 }
49}
50
51fn configure_server() -> Result<QuinnServerConfig, Box<dyn std::error::Error>> {
53 let rcgen::CertifiedKey { cert, signing_key } =
54 rcgen::generate_simple_self_signed(vec!["localhost".into()])?;
55 let cert_der = rustls::pki_types::CertificateDer::from(cert.der().to_vec());
56 let priv_key = rustls::pki_types::PrivateKeyDer::try_from(signing_key.serialize_der())?;
57
58 let cert_chain = vec![cert_der];
59
60 let mut server_config = rustls::ServerConfig::builder()
61 .with_no_client_auth()
62 .with_single_cert(cert_chain, priv_key)?;
63
64 server_config.alpn_protocols = vec![b"h3".to_vec()];
65
66 let server_config = QuinnServerConfig::with_crypto(Arc::new(
67 quinn::crypto::rustls::QuicServerConfig::try_from(server_config)?,
68 ));
69
70 Ok(server_config)
71}
72
73#[cfg(test)]
74mod tests {
75 #[test]
76 fn test_h3_server_creation() {
77 }
80}