micro_http/
lib.rs

1//! An asynchronous micro HTTP server implementation
2//!
3//! This crate provides a lightweight, efficient, and modular HTTP/1.1 server implementation
4//! built on top of tokio. It focuses on providing a clean API while maintaining high performance
5//! through careful memory management and asynchronous processing.
6//!
7//! # Features
8//!
9//! - Full HTTP/1.1 protocol support
10//! - Asynchronous I/O using tokio
11//! - Streaming request and response bodies
12//! - Chunked transfer encoding
13//! - Keep-alive connections
14//! - Expect-continue mechanism
15//! - Efficient memory usage through zero-copy parsing
16//! - Clean error handling
17//!
18//!
19//! # Example
20//!
21//! ```no_run
22//! use http::{Request, Response, StatusCode};
23//! use http_body_util::BodyExt;
24//! use std::error::Error;
25//! use std::sync::Arc;
26//! use tokio::net::TcpListener;
27//! use tracing::{error, info, warn, Level};
28//! use tracing_subscriber::FmtSubscriber;
29//! use micro_http::connection::HttpConnection;
30//! use micro_http::handler::make_handler;
31//! use micro_http::protocol::body::ReqBody;
32//!
33//! #[tokio::main]
34//! async fn main() {
35//!     // Initialize logging
36//!     let subscriber = FmtSubscriber::builder()
37//!         .with_max_level(Level::INFO)
38//!         .finish();
39//!     tracing::subscriber::set_global_default(subscriber)
40//!         .expect("setting default subscriber failed");
41//!     
42//!     info!(port = 8080, "start listening");
43//!     let tcp_listener = match TcpListener::bind("127.0.0.1:8080").await {
44//!         Ok(tcp_listener) => tcp_listener,
45//!         Err(e) => {
46//!             error!(cause = %e, "bind server error");
47//!             return;
48//!         }
49//!     };
50//!     
51//!     let handler = Arc::new(make_handler(hello_world));
52//!     
53//!     loop {
54//!         let (tcp_stream, _remote_addr) = match tcp_listener.accept().await {
55//!             Ok(stream_and_addr) => stream_and_addr,
56//!             Err(e) => {
57//!                 warn!(cause = %e, "failed to accept");
58//!                 continue;
59//!             }
60//!         };
61//!         
62//!         let handler = handler.clone();
63//!         
64//!         tokio::spawn(async move {
65//!             let (reader, writer) = tcp_stream.into_split();
66//!             let connection = HttpConnection::new(reader, writer);
67//!             match connection.process(handler).await {
68//!                 Ok(_) => {
69//!                     info!("finished process, connection shutdown");
70//!                 }
71//!                 Err(e) => {
72//!                     error!("service has error, cause {}, connection shutdown", e);
73//!                 }
74//!             }
75//!         });
76//!     }
77//! }
78//!
79//! async fn hello_world(request: Request<ReqBody>) -> Result<Response<String>, Box<dyn Error + Send + Sync>> {
80//!     let path = request.uri().path().to_string();
81//!     info!("request path {}", path);
82//!     
83//!     let (_header, body) = request.into_parts();
84//!     
85//!     let body_bytes = body.collect().await?.to_bytes();
86//!     info!(body = std::str::from_utf8(&body_bytes[..]).unwrap(), "receiving request body");
87//!     
88//!     let response_body = "Hello World!\r\n";
89//!     let response = Response::builder()
90//!         .status(StatusCode::OK)
91//!         .header(http::header::CONTENT_LENGTH, response_body.len())
92//!         .body(response_body.to_string())
93//!         .unwrap();
94//!     
95//!     Ok(response)
96//! }
97//! ```
98//!
99//!
100//! # Architecture
101//!
102//! The crate is organized into several key modules:
103//!
104//! - [`connection`]: Core connection handling and lifecycle management
105//! - [`protocol`]: Protocol types and abstractions
106//! - [`codec`]: Protocol encoding/decoding implementation
107//! - [`handler`]: Request handler traits and utilities
108//!
109//!
110//!
111//! # Core Components
112//!
113//! ## Connection Handling
114//!
115//! The [`connection::HttpConnection`] type is the main entry point for processing HTTP connections.
116//! It manages the full lifecycle of connections including:
117//!
118//! - Request parsing
119//! - Body streaming
120//! - Response generation
121//! - Keep-alive handling
122//!
123//! ## Request Processing
124//!
125//! Requests are processed through handler functions that implement the [`handler::Handler`] trait.
126//! The crate provides utilities for creating handlers from async functions through
127//! [`handler::make_handler`].
128//!
129//! ## Body Streaming
130//!
131//! Request and response bodies are handled through streaming interfaces that implement
132//! the `http_body::Body` trait. This enables efficient processing of large payloads
133//! without buffering entire bodies in memory.
134//!
135//! ## Error Handling
136//!
137//! The crate uses custom error types that implement `std::error::Error`:
138//!
139//! - [`protocol::HttpError`]: Top-level error type
140//! - [`protocol::ParseError`]: Request parsing errors
141//! - [`protocol::SendError`]: Response sending errors
142//!
143//! # Performance Considerations
144//!
145//! The implementation focuses on performance through:
146//!
147//! - Zero-copy parsing where possible
148//! - Efficient buffer management
149//! - Streaming processing of bodies
150//! - Concurrent request/response handling
151//! - Connection keep-alive
152//!
153//! # Limitations
154//!
155//! - HTTP/1.1 only (currently HTTP/2 or HTTP/3 is not supported)
156//! - No TLS support (use a reverse proxy for HTTPS)
157//! - Maximum header size: 8KB
158//! - Maximum number of headers: 64
159//!
160//! # Safety
161//!
162//! The crate uses unsafe code in a few well-documented places for performance
163//! optimization, particularly in header parsing. All unsafe usage is carefully
164//! reviewed and tested.
165
166pub mod codec;
167pub mod connection;
168pub mod handler;
169pub mod protocol;
170
171mod utils;
172pub(crate) use utils::ensure;