use crate::Server;
use quinn::{Endpoint, ServerConfig as QuinnServerConfig};
use std::net::SocketAddr;
use std::sync::Arc;
use tracing::info;
pub struct H3Server {
#[allow(dead_code)]
server: Arc<Server>,
endpoint: Option<Endpoint>,
}
impl H3Server {
pub fn new(server: Arc<Server>) -> Self {
Self {
server,
endpoint: None,
}
}
pub async fn listen(&mut self, addr: SocketAddr) -> Result<(), Box<dyn std::error::Error>> {
let server_config = configure_server()?;
let endpoint = Endpoint::server(server_config, addr)?;
info!("HTTP/3 server listening on {}", addr);
self.endpoint = Some(endpoint.clone());
while let Some(_incoming) = endpoint.accept().await {
}
Ok(())
}
pub fn shutdown(&mut self) {
if let Some(endpoint) = &self.endpoint {
endpoint.close(0u32.into(), b"server shutdown");
}
}
}
fn configure_server() -> Result<QuinnServerConfig, Box<dyn std::error::Error>> {
let rcgen::CertifiedKey { cert, signing_key } =
rcgen::generate_simple_self_signed(vec!["localhost".into()])?;
let cert_der = rustls::pki_types::CertificateDer::from(cert.der().to_vec());
let priv_key = rustls::pki_types::PrivateKeyDer::try_from(signing_key.serialize_der())?;
let cert_chain = vec![cert_der];
let mut server_config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(cert_chain, priv_key)?;
server_config.alpn_protocols = vec![b"h3".to_vec()];
let server_config = QuinnServerConfig::with_crypto(Arc::new(
quinn::crypto::rustls::QuicServerConfig::try_from(server_config)?,
));
Ok(server_config)
}
#[cfg(test)]
mod tests {
#[test]
fn test_h3_server_creation() {
}
}