Expand description
Monoio-based HTTP/1.1 and HTTP/2 server for Harrow.
This crate provides a high-performance HTTP server using io_uring. It supports HTTP/1.1 with keep-alive and chunked transfer encoding, and HTTP/2 with multiplexed streams.
§Features
- io_uring-based I/O: Zero-copy where possible, minimal syscalls
- Cancellation Safety: Proper handling of io_uring operation cancellation
- Buffer Pooling: Reusable buffers to reduce allocator pressure
- HTTP/2 Support: Multiplexed streams with flow control
§Architecture
┌─────────────────────────────────────────────┐
│ Server (lib.rs) │
└─────────────────────┬───────────────────────┘
│ TcpStream
▼
┌─────────────────────────────────────────────┐
│ Connection Handler │
│ (connection.rs) │
└─────────────────────┬───────────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌─────────────────┐ ┌─────────────────────┐
│ H1 Handler │ │ H2 Handler │
│(h1/dispatcher.rs)│ │ (h2.rs) │
└─────────────────┘ └─────────────────────┘§Example
fn main() {
// High-level thread-per-core bootstrap.
harrow_server_monoio::run(
|| App::new().get("/hello", hello),
"127.0.0.1:3000".parse().unwrap(),
)
.unwrap();
}For advanced cases where you already own a monoio runtime, use the async
serve / serve_with_shutdown / serve_with_config entrypoints instead.
§Cancellation Safety
This crate uses io_uring for async I/O. Unlike epoll-based runtimes, io_uring submits actual kernel operations. Dropping a Rust future does NOT automatically cancel the in-flight kernel operation.
This can lead to use-after-free (UAF) vulnerabilities:
- A read operation is submitted with a user buffer
- The future is dropped (e.g., due to timeout)
- The kernel writes to the buffer after it’s been freed/reused
§Mitigation
All I/O operations with timeout paths use CancelableAsyncReadRent and
explicitly cancel kernel operations before returning:
let canceller = Canceller::new();
let handle = canceller.handle();
monoio::select! {
result = stream.cancelable_read(buf, handle) => result,
_ = timeout => {
canceller.cancel(); // Explicit kernel cancellation
// Await the operation to reclaim buffer
let (_, buf) = read_fut.await;
release_buffer(buf);
return Err(Timeout);
}
}See cancel.rs for the implementation details.
Modules§
- kernel_
check - Kernel version and io_uring availability checks. Kernel version check for io_uring support.
Structs§
- Server
Config - Configuration for the monoio server.
- Server
Handle - Handle returned by the high-level monoio bootstrap APIs.
Functions§
- run
- Start the application using Harrow’s thread-per-core monoio bootstrap.
- run_
with_ config - Start the application using Harrow’s thread-per-core monoio bootstrap and block until shutdown.
- serve
- Serve the application on the given address using HTTP/1.1.
- serve_
with_ config - Serve with a graceful shutdown signal and custom configuration.
- serve_
with_ shutdown - Serve with a graceful shutdown signal.
- start
- Start the application using Harrow’s thread-per-core monoio bootstrap and return a handle for shutdown / test control.
- start_
with_ config - Start the application using Harrow’s thread-per-core monoio bootstrap and return a handle for shutdown / test control.