# WebIO π¦
> **A minimalist, high-performance web framework for Rust built with a zero-dependency philosophy.**
<div style="text-align: center;">
<a href="https://github.com/dr-montasir/webio"><img src="https://img.shields.io/badge/github-dr%20montasir%20/%20webio-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="24" style="margin-top: 10px;" alt="github" /></a> <a href="https://crates.io/crates/webio"><img src="https://img.shields.io/crates/v/webio.svg?style=for-the-badge&color=fc8d62&logo=rust" height="24" style="margin-top: 10px;" alt="crates.io"></a> <a href="https://docs.rs/webio"><img src="https://img.shields.io/badge/docs.rs-webio-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="24" style="margin-top: 10px;" alt="docs.rs"></a> <a href="https://choosealicense.com/licenses/mit"><img src="https://img.shields.io/badge/license-mit-4a98f7.svg?style=for-the-badge&labelColor=555555" height="24" style="margin-top: 10px;" alt="license"></a>
</div>
---
## π§ͺ Research Status: Experimental
**WebIO** is currently in an active **research and development phase**.
- **API Stability:** Expect breaking changes as we refine the core engine.
- **Goal:** To provide a high-integrity core engine for **Data Science**, **Computing Science**, and frameworks like **Fluxor**.
- **Production Warning:** Use with caution until the stable `1.0.0` released.
## π― Core Philosophy
WebIO provides a fully functional web engine with **zero external dependencies**. By strictly utilizing the Rust std library, it ensures an ultra-light footprint, rapid compilation, and total memory predictability.
**zero external dependencies**.
- **No** `tokio`, `async-std` or `hyper`.
- **No** `serde` or heavy middleware bloat.
- **No** `unsafe` code in the executor.
- **Just pure, high-performance Rust**.
## π οΈ Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
webio = "0.5.0-alpha"
```
## π What's New in v0.5.0-alpha
The `v0.5.0-alpha` release represents a major architectural shift from a single-threaded async model to a **High-Performance Multi-threaded Hybrid Engine** inspired by the Go concurrency model.
## π§΅ Go-Inspired Multi-threading
WebIO now mimics the Go strategy by spawning a unique **OS Thread** for every incoming connection. This ensures **Pre-emptive Multitasking**: a heavy mathematical calculation on one thread will never "freeze" the server for other usersβa common pitfall in traditional async runtimes like Tokio.
## β‘ Safe-Turbo block_on Executor
We have replaced the legacy runtime with a specialized **Safe-Turbo Bridge**. It utilizes a **150,000-cycle spin-loop** to catch I/O ready states in nanoseconds. This bypasses OS scheduler jitter, maintaining sub-millisecond tail latency (~200Β΅s) while remaining 100% safe.
## π‘οΈ RAM Safety & Big Data Streaming
- **10MB Safety Valve**: A pre-emptive RAM guard protects the heap by rejecting massive payloads before they are ingested.
- **Zero-RAM Ingestion**: Handlers now have direct access to the `TcpStream`, allowing multi-gigabyte files (CSVs, Videos, Datasets) to be moved directly to disk in 64KB chunks with O(1) **memory complexity**.
## π°οΈ Real-Time WebSockets & Global Broadcast
Full **RFC 6455** compliance is now built-in. WebIO handles the cryptographic handshake (SHA-1/Base64) and binary framing manually. The new **Global Client Registry** allows any thread to broadcast messages to all connected users simultaneously.
## π§ Smart Asset Caching
Introduced an **`RwLock`** **RAM Cache** for static assets. Small files (<500KB) are served at RAM speeds (~50Β΅s), while larger files are intelligently served via the OS Page Cache to prevent memory exhaustion.
## π Dynamic Nagle Control
New builder-pattern support for `set_nagle(bool)`. Toggle between **Low Latency** (TCP_NODELAY) for real-time APIs or **High Throughput** for massive data synchronization.
## 𧬠Concurrency Comparison
| Feature | Traditional Async (Tokio) | WebIO v0.5.0 (OS Threads) |
| ---------------- | -------------------------- | --------------------------- |
| **Heavy Math** | β Blocks the Event Loop | β
Isolated per CPU Core |
| **Tail Latency** | β οΈ Variable (Task Stealing) | β
Ultra-Low (Spin-Wait) |
| **Memory** | β οΈ Managed by Runtime | β
Deterministic (Ownership) |
| **Dependencies** | β Hundreds | β
**Zero (std only)** |
## π Big Data POST Examples
In WebIO, standard `POST` data is limited to **10MB** for RAM safety. For datasets exceeding this (e.g., 10GB CSVs or Videos), handlers must use the raw `stream` for **Zero-RAM Ingestion**.
```rust,no_run
use webio::*;
use std::io::{Write, Read, BufWriter};
use std::fs::File;
const INDEX_HTML: &str = r##"<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WebIO | High-Performance Rust</title>
<link rel="icon" href="/images/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="/css/styles.css" />
</head>
<body>
<main>
<h1>π Welcome to WebIO</h1>
<p>A zero-dependency, ultra-low-latency web framework.</p>
<section class="gallery">
<img src="/images/logo.svg" alt="WebIO Logo" width="150" />
</section>
</main>
<script src="/js/script.js"></script>
</body>
</html>"##;
// --- Implementation Examples ---
/// Demonstrates basic GET routing.
async fn hello_get_handler(_req: Req, _params: Params) -> Reply {
Reply::new(StatusCode::Ok)
.header("Content-Type", "text/html; charset=UTF-8")
.body(INDEX_HTML)
}
/// Demonstrates dynamic path parameters using `<name>`.
/// Extracted via the `Params` collection.
async fn user_handler(_req: Req, params: Params) -> Reply {
let name = params.0.get("name").cloned().unwrap_or("Guest".to_string());
Reply::new(StatusCode::Ok).
header("Content-Type", "text/html; charset=UTF-8")
.body(format!("<h1>Hello π, {}!</h1>", name))
}
/// A specialized handler for numeric IDs or other dynamic segments.
async fn id_handler(_req: Req, params: Params) -> Reply {
let id = params.0.get("id").cloned().unwrap_or("0".to_string());
Reply::new(StatusCode::Ok)
.header("Content-Type", "text/html; charset=UTF-8")
.body(format!("<h1>π ID: {}</h1>", id))
}
/// Demonstrates handling POST data directly from the `Req` struct.
async fn create_user_handler(req: Req, _params: Params) -> Reply {
// Access the POST body directly
Reply::new(StatusCode::Ok)
.header("Content-Type", "text/html; charset=UTF-8")
.body(format!("<h1>π User Created with Data: {}</h1>", req.body))
}
/// A typical API endpoint returning JSON content.
async fn status_handler(_req: Req, _params: Params) -> Reply {
Reply::new(StatusCode::Ok)
.header("Content-Type", "application/json")
.body("{\"status\": \"online\"}")
}
/// A protected resource example. Access is controlled by the middleware defined in `main`.
async fn secret_handler(_req: Req, _params: Params) -> Reply {
Reply::new(StatusCode::Ok)
.header("Content-Type", "text/html; charset=UTF-8")
.body("<h1>π Access Granted: Welcome Boss! π</h1>")
}
/// A custom 404 handler that serves a styled HTML page.
/// Automatically selected by WebIO when a browser (Accept: text/html) hits a missing route.
async fn my_custom_html_404(_req: Req, _params: Params) -> Reply {
Reply::new(StatusCode::NotFound)
.header("Content-Type", "text/html; charset=UTF-8")
.body("<h1 style='color:red;'>πΈ 404 - That page doesn't exist on WebIo!</h1>")
}
/// A custom 404 handler that serves a JSON error.
/// Automatically selected for API clients or tools like `curl`.
async fn my_custom_json_404(_req: Req, _params: Params) -> Reply {
Reply::new(StatusCode::NotFound)
.header("Content-Type", "application/json")
.body("{\"error\": \"not_found\", \"code\": 404, \"source\": \"WebIo API\"}")
}
async fn handle_big_csv(mut req: Req, _params: Params) -> Reply {
let mut file = std::fs::File::create("huge_dataset.csv").unwrap();
// Use a small 64KB buffer to move 10GB of data
let mut buffer = [0; 65536];
while let Ok(n) = req.stream.read(&mut buffer) {
if n == 0 { break; }
file.write_all(&buffer[..n]).unwrap();
}
Reply::new(StatusCode::Ok).body("Upload Complete")
}
async fn handle_video_upload(mut req: Req, _params: Params) -> Reply {
// 1. Create the destination file
let file_path = "uploads/video_data.mp4";
let file = match File::create(file_path) {
Ok(f) => f,
Err(_) => return Reply::new(StatusCode::InternalError).body("Could not create file"),
};
let mut writer = BufWriter::new(file);
let mut buffer = [0; 65536]; // 64KB Chunk (High Throughput)
let mut total_bytes = 0;
// 2. Stream directly from the RAW socket (req.stream)
// This bypasses the 10MB RAM limit entirely!
while let Ok(n) = req.stream.read(&mut buffer) {
if n == 0 { break; } // Socket closed or upload finished
if let Err(_) = writer.write_all(&buffer[..n]) {
return Reply::new(StatusCode::InternalError).body("Disk Write Error");
}
total_bytes += n as u64;
}
let _ = writer.flush();
Reply::new(StatusCode::Ok)
.header("Content-Type", "application/json")
.body(format!(r#"{{"status": "success", "bytes_saved": {}}}"#, total_bytes))
}
async fn chat_handler(req: Req, _params: Params) -> Reply {
// 1. Upgrade to WebSocket
if let Some(mut ws) = req.upgrade_websocket() {
// 2. Register the connection in our Global Registry
if let Ok(mut clients) = CLIENTS.lock() {
if let Ok(clone) = ws.try_clone() {
clients.push(clone);
}
}
// 3. Enter the persistent Loop (Isolated on this OS Thread)
loop {
// Read binary frames from the browser
match WSFrame::read(&mut ws) {
Ok(frame) => {
let msg = String::from_utf8_lossy(&frame.payload);
// Broadcast to ALL other threads
broadcast(&format!("User {}: {}", msg, req.path));
}
Err(_) => break, // Disconnect
}
}
}
// 4. Return empty (Stream is closed or hijacked)
Reply::new(StatusCode::Ok).body("")
}
fn main() {
let mut app = WebIo::new();
app.log_reply_enabled = true;
app.use_static("assets");
app.on_404(my_custom_html_404);
app.on_404(my_custom_json_404);
// --- Routes ---
app.route(GET, "/", hello_get_handler);
app.route(GET, "/status", status_handler);
app.route(GET, "/user/create", create_user_handler);
app.route(GET, "/secret-handler", secret_handler);
app.route(GET, "/user/<name>", user_handler);
app.route(GET, "/req/<id>", id_handler);
// WebSockets & Big Data (Persistent/Heavy)
app.route(GET, "/chat", chat_handler);
app.route(POST, "/csv", handle_big_csv);
app.route(POST, "/video-upload", handle_video_upload);
// --- Start ---
// Start the Multi-Threaded TCP Listener
// // set false or true
app.set_nagle(true)
.run("0.0.0.0", "8080");
// // set false or true
// app = app.set_nagle(false);
// app.run("0.0.0.0", "8080");
// Default value nagle is on/true
// app.run("0.0.0.0", "8080");
}
```