micro_web/
server.rs

1//! Server module for handling HTTP requests and managing web server lifecycle.
2//!
3//! This module provides the core server functionality including:
4//! - Server builder pattern for configuration
5//! - HTTP request routing and handling
6//! - Connection management and error handling
7//! - Default request handling
8//!
9//! # Examples
10//!
11//! ```no_run
12//! use micro_web::{Server, router::{Router, get}};
13//!
14//! async fn hello_world() -> &'static str {
15//!     "Hello, World!"
16//! }
17//!
18//! #[tokio::main]
19//! async fn main() {
20//!     let router = Router::builder()
21//!         .route("/", get(hello_world))
22//!         .build();
23//!         
24//!     Server::builder()
25//!         .router(router)
26//!         .bind("127.0.0.1:3000")
27//!         .build()
28//!         .unwrap()
29//!         .start()
30//!         .await;
31//! }
32//! ```
33
34use crate::handler::RequestHandler;
35use crate::router::Router;
36use crate::{OptionReqBody, RequestContext, ResponseBody, handler_fn, FnTrait};
37use http::{Request, Response, StatusCode};
38use micro_http::connection::HttpConnection;
39use micro_http::handler::Handler;
40use micro_http::protocol::RequestHeader;
41use micro_http::protocol::body::ReqBody;
42use std::error::Error;
43use std::net::{SocketAddr, ToSocketAddrs};
44use std::sync::Arc;
45use thiserror::Error;
46use tokio::net::TcpListener;
47use tracing::{Level, error, info, warn};
48use tracing_subscriber::FmtSubscriber;
49use crate::extract::FromRequest;
50use crate::responder::Responder;
51
52/// Builder for configuring and constructing a [`Server`] instance.
53///
54/// The builder provides a fluent API for setting server options including:
55/// - Binding address
56/// - Request router
57/// - Default request handler
58#[derive(Debug)]
59pub struct ServerBuilder {
60    router: Option<Router>,
61    default_handler: Option<Box<dyn RequestHandler>>,
62    address: Option<Vec<SocketAddr>>,
63}
64
65impl ServerBuilder {
66    fn new() -> Self {
67        Self { router: None, default_handler: None, address: None }
68    }
69
70    pub fn bind<A: ToSocketAddrs>(mut self, address: A) -> Self {
71        self.address = Some(address.to_socket_addrs().unwrap().collect::<Vec<_>>());
72        self
73    }
74
75    pub fn router(mut self, router: Router) -> Self {
76        self.router = Some(router);
77        self
78    }
79
80    pub fn default_handler<F, Args>(mut self, f: F) -> Self
81    where
82    for<'r> F: FnTrait<Args> + 'r,
83    for<'r> Args: FromRequest + 'r,
84    for<'r> F: FnTrait<Args::Output<'r>>,
85    for<'r> <F as FnTrait<Args::Output<'r>>>::Output: Responder,
86    {
87        let handler = handler_fn(f);
88        self.default_handler = Some(Box::new(handler));
89        self
90    }
91
92    pub fn build(self) -> Result<Server, ServerBuildError> {
93        let new_builder = if self.default_handler.is_none() { self.default_handler(default_handler) } else { self };
94        let router = new_builder.router.ok_or(ServerBuildError::MissingRouter)?;
95        let address = new_builder.address.ok_or(ServerBuildError::MissingAddress)?;
96
97        // unwrap is safe here because we set it in the new_builder
98        Ok(Server { router, default_handler: new_builder.default_handler.unwrap(), address })
99    }
100}
101
102async fn default_handler() -> (StatusCode, &'static str) {
103    (StatusCode::NOT_FOUND, "404 Not Found")
104}
105
106/// Core server implementation that processes HTTP requests.
107///
108/// The server is responsible for:
109/// - Listening for incoming connections
110/// - Routing requests to appropriate handlers
111/// - Managing connection lifecycle
112/// - Error handling and logging
113///
114#[derive(Debug)]
115pub struct Server {
116    router: Router,
117    default_handler: Box<dyn RequestHandler>,
118    address: Vec<SocketAddr>,
119}
120
121/// Errors that can occur during server construction.
122#[derive(Error, Debug)]
123pub enum ServerBuildError {
124    /// Router was not configured
125    #[error("router must be set")]
126    MissingRouter,
127
128    /// Bind address was not configured
129    #[error("address must be set")]
130    MissingAddress,
131}
132
133impl Server {
134    pub fn builder() -> ServerBuilder {
135        ServerBuilder::new()
136    }
137
138    pub async fn start(self) {
139        let subscriber = FmtSubscriber::builder().with_max_level(Level::WARN).finish();
140        tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
141
142        info!("start listening at {:?}", self.address);
143        let tcp_listener = match TcpListener::bind(self.address.as_slice()).await {
144            Ok(tcp_listener) => tcp_listener,
145            Err(e) => {
146                error!(cause = %e, "bind server error");
147                return;
148            }
149        };
150
151        let handler = Arc::new(self);
152        loop {
153            let (tcp_stream, _remote_addr) = tokio::select! {
154                _ = tokio::signal::ctrl_c() => { break; },
155                result = tcp_listener.accept() => {
156                    match result {
157                        Ok(stream_and_addr) => stream_and_addr,
158                        Err(e) => {
159                            warn!(cause = %e, "failed to accept");
160                            continue;
161                        }
162                    }
163                }
164            };
165
166            let handler = handler.clone();
167
168            tokio::spawn(async move {
169                tcp_stream.set_nodelay(true).unwrap();
170                let (reader, writer) = tcp_stream.into_split();
171                let connection = HttpConnection::new(reader, writer);
172                match connection.process(handler).await {
173                    Ok(_) => {
174                        info!("finished process, connection shutdown");
175                    }
176                    Err(e) => {
177                        error!("service has error, cause {}, connection shutdown", e);
178                    }
179                }
180            });
181        }
182    }
183}
184
185impl Handler for Server {
186    type RespBody = ResponseBody;
187    type Error = Box<dyn Error + Send + Sync>;
188
189    async fn call(&self, req: Request<ReqBody>) -> Result<Response<Self::RespBody>, Self::Error> {
190        let (parts, body) = req.into_parts();
191        let header = RequestHeader::from(parts);
192        // TODO: insignificant memory allocate
193        let req_body = OptionReqBody::from(body);
194
195        let path = header.uri().path();
196        let route_result = self.router.at(path);
197
198        let mut request_context = RequestContext::new(&header, route_result.params());
199
200        let handler = route_result
201            .router_items()
202            .iter()
203            .filter(|item| item.filter().matches(&request_context))
204            .map(|item| item.handler())
205            .take(1)
206            .next()
207            .unwrap_or(self.default_handler.as_ref());
208
209        let response = handler.invoke(&mut request_context, req_body).await;
210        Ok(response)
211    }
212}