//! 独立 Axum 路由;用官方 Hyper 入口统一连接、报文和超时上限。 use axum::{ Router, body::Bytes, extract::DefaultBodyLimit, http::header, routing::{get, post}, }; use hyper_util::{ rt::{TokioIo, TokioTimer}, service::TowerToHyperService, }; use std::{sync::Arc, time::Duration}; use tokio::{net::TcpListener, sync::Semaphore}; async fn serve(capacity: usize) -> Result<(), Box> { let router = Router::new() .route( "/json", get(async |_: Bytes| { ( [(header::CONTENT_TYPE, "application/json")], "{\"ok\":true}", ) }), ) .route( "/echo", post(async |body: Bytes| ([(header::CONTENT_TYPE, "application/octet-stream")], body)), ) .layer(DefaultBodyLimit::max(65536)); let listener = TcpListener::bind("127.0.0.1:0").await?; let slots = Arc::new(Semaphore::new(capacity)); println!("READY|{}", listener.local_addr()?.port()); loop { let permit = slots.clone().acquire_owned().await?; let (stream, _) = listener.accept().await?; stream.set_nodelay(true)?; let service = TowerToHyperService::new(router.clone()); tokio::spawn(async move { let _permit = permit; let mut builder = hyper::server::conn::http1::Builder::new(); builder .timer(TokioTimer::new()) .header_read_timeout(Duration::from_secs(5)) .max_buf_size(8192); if let Err(error) = builder .serve_connection(TokioIo::new(stream), service) .await { if !error.is_incomplete_message() && !error.is_closed() { eprintln!("connection: {error}"); } } }); } } fn main() -> Result<(), Box> { let capacity = std::env::args().nth(1).unwrap().parse()?; tokio::runtime::Builder::new_multi_thread() .worker_threads(2) .enable_all() .build()? .block_on(serve(capacity)) }