67 lines
1.9 KiB
Rust
Raw Normal View History

2026-01-24 22:59:20 +00:00
use crate::api::ApiHandler;
use crate::config::Config;
use anyhow::Result;
use hyper_util::rt::TokioIo;
use hyper_util::server::conn::auto::Builder as AutoBuilder;
use std::net::SocketAddr;
use std::sync::Arc;
use tokio::net::TcpListener;
use hyper::service::service_fn;
use tracing::{error, info};
pub struct Server {
config: Config,
api_handler: Arc<ApiHandler>,
}
impl Server {
pub async fn new(config: Config) -> Result<Self> {
let api_handler = Arc::new(ApiHandler::new(config.clone()).await?);
Ok(Self {
config,
api_handler,
})
}
pub async fn serve(&self, addr: SocketAddr) -> Result<()> {
let listener = TcpListener::bind(addr).await?;
loop {
let (stream, peer_addr) = match listener.accept().await {
Ok(conn) => conn,
Err(e) => {
error!("Failed to accept connection: {}", e);
continue;
}
};
let io = TokioIo::new(stream);
let handler = self.api_handler.clone();
tokio::spawn(async move {
let service = service_fn(move |req| {
let handler = handler.clone();
async move {
handler.handle_request(req).await
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e)))
2026-01-24 22:59:20 +00:00
}
});
let mut builder = AutoBuilder::new(
2026-01-24 22:59:20 +00:00
hyper_util::rt::TokioExecutor::new()
);
// Use HTTP/1.1 only for now
builder = builder.http1_only();
2026-01-24 22:59:20 +00:00
if let Err(e) = builder
.serve_connection(io, service)
.await
{
error!("Error serving connection from {}: {}", peer_addr, e);
}
});
}
}
}