use crate::network::{NetworkConfig, NetworkError};
use std::collections::BTreeMap;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use std::net::TcpListener;
pub type Http2Handler = fn(&str, &[u8]) -> Result<Vec<u8>, NetworkError>;
#[derive(Debug, Clone)]
pub struct Http2Route {
pub path: String,
pub handler: Http2Handler,
}
#[derive(Debug, Clone)]
pub struct Http2ServerStats {
pub total_requests: u64,
pub active_streams: usize,
pub total_connections: usize,
}
pub struct Http2Server {
config: NetworkConfig,
enabled: bool,
routes: HashMap<String, Http2Handler>,
stats: std::sync::Arc<std::sync::Mutex<Http2ServerStats>>,
}
impl Http2Server {
pub fn new(config: NetworkConfig) -> Result<Self, NetworkError> {
Ok(Self {
enabled: config.enable_http2,
config,
routes: HashMap::new(),
stats: std::sync::Arc::new(Mutex::new(Http2ServerStats {
total_requests: 0,
active_streams: 0,
total_connections: 0,
})),
})
}
pub fn add_route(&mut self, path: &str, handler: Http2Handler) -> Result<(), NetworkError> {
self.routes.insert(path.to_string(), handler);
Ok(())
}
pub fn is_enabled(&self) -> bool {
self.enabled
}
pub fn start(&mut self, addr: &str) -> Result<TcpListener, NetworkError> {
if !self.enabled {
return Err(NetworkError::Connection("HTTP/2 is not enabled".to_string()));
}
let listener: _ = TcpListener::bind(addr)
.map_err(|e| NetworkError::Connection(e.to_string()))?;
{
let mut stats = self.stats.lock().unwrap();
stats.total_connections += 1;
}
Ok(listener)
}
pub fn handle_request(&self, path: &str, body: &[u8]) -> Result<Vec<u8>, NetworkError> {
let mut stats = self.stats.lock().unwrap();
stats.total_requests += 1;
if let Some(handler) = self.routes.get(path) {
handler(path, body)
} else {
Ok(b"HTTP/2 404 Not Found".to_vec())
}
}
pub fn get_stats(&self) -> Http2ServerStats {
self.stats.lock().unwrap().clone()
}
}
impl Default for Http2Server {
fn default() -> Self {
Http2Server::new(NetworkConfig::default()).unwrap()
}
}