Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting Started

TezWeb is a blazing-fast Rust HTTP framework built from scratch. No Hyper for HTTP/1.1, no Tower — just raw TCP and pure Rust.

Installation

Add TezWeb to your Cargo.toml:

[dependencies]
tezweb = { git = "https://github.com/akramjhabail/tezweb" }
tokio = { version = "1", features = ["full"] }

Hello World

use tezweb::{TezWeb, Response};

#[tokio::main]
async fn main() {
    TezWeb::new()
        .port(8080)
        .get("/hello", |_req, _params| async move {
            Response::ok().text("Hello from TezWeb! ⚡")
        })
        .run()
        .await
        .unwrap();
}

Run it:

cargo run

Visit http://localhost:8080/hello in your browser.

JSON Response

use tezweb::{TezWeb, Response};
use serde_json::json;

#[tokio::main]
async fn main() {
    TezWeb::new()
        .port(8080)
        .get("/users", |_req, _params| async move {
            Response::ok().json(&json!([
                {"id": 1, "name": "Akram"},
                {"id": 2, "name": "Ali"}
            ]))
        })
        .run()
        .await
        .unwrap();
}

Next Steps

Routing

TezWeb uses a Trie-based router with O(log n) lookup — supports exact matches, URL parameters, and wildcards.

Basic Routes

#![allow(unused)]
fn main() {
TezWeb::new()
    .get("/users", handler)
    .post("/users", handler)
    .put("/users/:id", handler)
    .delete("/users/:id", handler)
}

URL Parameters

Use :name syntax to capture URL segments:

#![allow(unused)]
fn main() {
.get("/users/:id", |_req, params| async move {
    let id = params.get("id").cloned().unwrap_or_default();
    Response::ok().text(format!("User ID: {}", id))
})
}

Multiple params:

#![allow(unused)]
fn main() {
.get("/posts/:post_id/comments/:comment_id", |_req, params| async move {
    let post_id = &params["post_id"];
    let comment_id = &params["comment_id"];
    Response::ok().text(format!("Post {} Comment {}", post_id, comment_id))
})
}

Wildcards

Use * to match any remaining path segments — useful for static files and proxying:

#![allow(unused)]
fn main() {
.get("/static/*", |_req, _params| async move {
    Response::ok().text("Matches /static/anything/here")
})
}

Query Parameters

#![allow(unused)]
fn main() {
.get("/search", |req, _params| async move {
    let query = &req.query;
    Response::ok().text(format!("Query: {}", query))
})
}

How It Works

TezWeb router is a custom Trie (prefix tree). Each segment of the URL path is a node. Exact matches are checked first, then param matches, then wildcard. This gives fast O(log n) lookup even with thousands of routes.

Middleware

Rate Limiting

Limits requests per IP within a time window.

#![allow(unused)]
fn main() {
use tezweb::rate_limit_middleware;

TezWeb::new()
    .middleware(rate_limit_middleware(5, 10))
    .get("/api", handler)
}

Parameters: rate_limit_middleware(max_requests, window_seconds).

Example above: max 5 requests per 10 seconds per IP. The 6th request within the window returns 429 Too Many Requests.

The IP is read from the X-Forwarded-For header. If missing, a "global" key is used as fallback.

Combining Middleware

Middleware runs in the order you add it:

#![allow(unused)]
fn main() {
TezWeb::new()
    .middleware(logger())
    .middleware(cors())
    .middleware(rate_limit_middleware(100, 60))
    .get("/api", handler)
    .run()
    .await
    .unwrap();
}

Custom Middleware

You can write your own middleware function matching the MiddlewareFn signature to add custom behavior like authentication checks, request ID injection, or custom headers.

WebSocket

TezWeb implements RFC 6455 WebSocket with full handshake support.

Basic WebSocket Server

use tezweb::{TezWeb, WsContext};

#[tokio::main]
async fn main() {
    TezWeb::new()
        .port(8080)
        .ws("/chat", |ctx: WsContext| async move {
            ctx.send("Welcome to TezWeb chat!").await;
        })
        .run()
        .await
        .unwrap();
}

How It Works

  1. Client sends an HTTP upgrade request to /chat
  2. TezWeb performs the WebSocket handshake (SHA-1 key exchange per RFC 6455)
  3. Connection upgrades from HTTP to WebSocket protocol
  4. Your handler function runs with access to the WsContext

Testing

Run the example:

cargo run --example websocket_chat

Connect using a WebSocket client (browser console):

const ws = new WebSocket("ws://localhost:8080/chat");
ws.onmessage = (event) => console.log(event.data);

Verified

WebSocket handshake and message handling have been tested end-to-end — handshake succeeds and the handler is reached correctly.

GraphQL

TezWeb integrates with async-graphql for GraphQL support.

Basic Setup

use tezweb::{TezWeb, graphql_handler};
use async_graphql::{Object, Schema, EmptyMutation, EmptySubscription};

struct Query;

#[Object]
impl Query {
    async fn add(&self, a: i32, b: i32) -> i32 {
        a + b
    }
}

#[tokio::main]
async fn main() {
    let schema = Schema::new(Query, EmptyMutation, EmptySubscription);

    TezWeb::new()
        .port(8080)
        .graphql("/graphql", schema)
        .run()
        .await
        .unwrap();
}

Querying

Send a POST request to /graphql:

curl -X POST http://localhost:8080/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ add(a: 5, b: 7) }"}'

Response:

{"data": {"add": 12}}

Running the Example

cargo run --example graphql_test

Verified

GraphQL query execution has been tested end-to-end. The example query { add(a: 5, b: 7) } correctly returns 12.

Reverse Proxy

TezWeb supports reverse proxying with automatic prefix stripping.

Basic Usage

use tezweb::TezWeb;

#[tokio::main]
async fn main() {
    TezWeb::new()
        .port(8080)
        .proxy("/api", "http://localhost:9000")
        .run()
        .await
        .unwrap();
}

How Prefix Stripping Works

A request to /api/users is forwarded to the backend as /users — the /api prefix is stripped automatically.

Incoming RequestForwarded To
/api/usershttp://localhost:9000/users
/api/datahttp://localhost:9000/data
/api/http://localhost:9000/

Multiple Proxy Rules

#![allow(unused)]
fn main() {
TezWeb::new()
    .proxy("/api", "http://localhost:9000")
    .proxy("/auth", "http://localhost:9001")
    .run()
    .await
    .unwrap();
}

Testing

cargo run --example proxy_test

Then in another terminal:

python3 -m http.server 9000
curl http://localhost:8080/api/somefile

Implementation Notes

The proxy opens a raw TCP connection to the target, forwards the HTTP request with the stripped path, and streams the response back to the client. Connection header is set to close for simplicity.

Verified

Prefix stripping was tested end-to-end — /api/somefile correctly forwards to the backend as /somefile.

JWT Authentication

TezWeb provides built-in JWT (JSON Web Token) support using real HMAC-SHA256 cryptography.

Generating a Token

#![allow(unused)]
fn main() {
use tezweb::auth::{generate_token, verify_token};

let token = generate_token("user123", "my-secret-key");
println!("Token: {}", token);
}

Verifying a Token

#![allow(unused)]
fn main() {
match verify_token(&token, "my-secret-key") {
    Ok(claims) => println!("Valid! User: {}", claims),
    Err(e) => println!("Invalid token: {}", e),
}
}

Using With Routes

#![allow(unused)]
fn main() {
TezWeb::new()
    .get("/login", |_req, _params| async move {
        let token = generate_token("user123", "secret-key");
        Response::ok().json(&serde_json::json!({ "token": token }))
    })
    .get("/protected", |req, _params| async move {
        let auth_header = req.headers.get("Authorization");
        match auth_header.and_then(|h| verify_token(h, "secret-key").ok()) {
            Some(_) => Response::ok().text("Access granted"),
            None => Response::new(401).text("Unauthorized"),
        }
    })
    .run()
    .await
    .unwrap();
}

Security

TezWeb’s JWT implementation uses the hmac and sha2 crates for cryptographically secure HMAC-SHA256 signing — not a simple hash function. Tokens are tamper-proof: any modification to the payload invalidates the signature.

Running the Example

cargo run --example jwt_test

Verified

Tested end-to-end: token generation, valid-secret verification, wrong-secret rejection, and tampered-token rejection all pass correctly.

Internals

Yeh poora content paste karo internals.md mein:

# Internals

How TezWeb works under the hood.

## Architecture

TezWeb ├── HTTP/1.1 Parser (hand-rolled, zero-copy) ├── HTTP/2 (TLS + ALPN via Hyper) ├── HTTP/3 / QUIC (Quinn backend) ├── Trie Router (O(log n), params + wildcards) ├── Middleware Chain (CORS, Logger, Rate-limit) ├── Protocol Handlers │ ├── WebSocket (RFC 6455) │ ├── SSE (text/event-stream) │ └── GraphQL (async-graphql) ├── Reverse Proxy (prefix stripping) ├── Static Files (MIME types + directory listing) └── TLS (Rustls — no OpenSSL)


## HTTP/1.1 Parser

TezWeb does not use Hyper for HTTP/1.1. The parser is hand-rolled for zero-copy performance — it reads directly into a buffer pool and avoids unnecessary allocations.

## Trie Router

Routes are stored in a segment-based Trie (prefix tree). Each path segment (`/users`, `:id`, `*`) is a node. Lookup checks exact matches first, then parameter matches, then wildcards — giving O(log n) performance regardless of route count.

## Per-Core Architecture

TezWeb spawns one TCP listener per CPU core using `SO_REUSEPORT`, allowing the OS to load-balance incoming connections across cores without a single shared accept loop becoming a bottleneck.

## Platform-Specific I/O

- **Linux**: uses `monoio` with `io_uring` for kernel-level async I/O
- **macOS**: uses `tokio` with `kqueue`
- **Windows**: uses `tokio` with IOCP

## Buffer Pooling

A thread-local buffer pool reuses allocated buffers across requests instead of allocating fresh memory for every read/write, reducing GC-like pressure.

## TLS

TezWeb uses `rustls` exclusively — no OpenSSL dependency, which simplifies cross-platform builds and removes a common source of security vulnerabilities.

Pehle Ctrl+A (select all) → Delete → phir yeh paste karo → Ctrl+S save.

Benchmarks

Real, measured performance — not theoretical.

Test Setup

  • Machine: MacBook Pro (Linux/macOS)
  • Tool: wrk -t8 -c400 -d10s
  • Build: cargo build --release
  • Endpoint: /health

Results

FrameworkRPSResult
TezWeb40,2481st place
Actix-web (8 workers)17,8092.26x slower

TezWeb Across Modes

ModeRPS
Debug build + Logger middleware17,602
Release build + Logger middleware26,964
Release build (no logger)40,248

Logger middleware adds noticeable overhead — for max throughput, disable it or use sampling in production.

Reproducing the Benchmark

cd tezweb
cargo build --release --example rest_api
./target/release/examples/rest_api &
wrk -t8 -c400 -d10s http://localhost:8080/health

Actix Comparison

cd actix-bench
cargo build --release
./target/release/actix-bench &
wrk -t8 -c400 -d10s http://localhost:8081/

Why TezWeb Is Fast

  1. Hand-rolled HTTP/1.1 parser — no Hyper overhead for HTTP/1.1
  2. Custom Trie router — O(log n) lookup
  3. Per-core TCP listeners with SO_REUSEPORT
  4. Thread-local buffer pooling — reduces allocations
  5. Zero unnecessary middleware by default

Platform Notes

  • Linux: Uses monoio + io_uring — expected to outperform macOS numbers shown here
  • macOS: kqueue via tokio — current benchmark numbers (40,248 RPS)
  • Windows: IOCP via tokio — untested

Deployment

benchmarks.md done! ✅ 58 lines.

Last file baaki hai — deployment.md:

code ~/tezweb/docs/deployment.md

Yeh content paste karo (Ctrl+A, Delete, phir paste):

# Deployment

Guide to deploying TezWeb to production.

## Option 1: Oracle Cloud Free Tier (Recommended)

Oracle Cloud's Always Free tier offers 4 CPU cores and 24GB RAM at no cost — ideal for TezWeb's per-core architecture.

### Steps

1. Sign up at oracle.com/cloud/free
2. Select Mumbai region for best latency from South Asia
3. Create a VM instance (Ampere A1 or AMD shape)
4. SSH into the instance

### Install Rust

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env

Clone and Build

git clone https://github.com/akramjhabail/tezweb.git
cd tezweb
cargo build --release --example rest_api

Run as a systemd Service

Create /etc/systemd/system/tezweb.service:

[Unit]
Description=TezWeb Server
After=network.target

[Service]
ExecStart=/home/ubuntu/tezweb/target/release/examples/rest_api
Restart=always
User=ubuntu

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable tezweb
sudo systemctl start tezweb

Open Firewall Port

sudo iptables -I INPUT -p tcp --dport 8080 -j ACCEPT

Also open the port in the Oracle Cloud Security List for your VM’s subnet.

Option 2: DigitalOcean / VPS

Same steps as above apply to any Linux VPS (DigitalOcean, Hetzner, Vultr). Choose a region close to your users for lowest latency.

Option 3: Cloudflare Tunnel (Quick Demo)

For temporary public access without a dedicated server:

brew install cloudflared
cloudflared tunnel --url http://localhost:8080

This gives a temporary public URL — not suitable for permanent production use.

Why Not Cloudflare Workers?

Cloudflare Workers run on a serverless WASM model and do not support raw TCP socket servers. TezWeb requires a real Linux/macOS/Windows server with full TCP/IP access, so a VPS or cloud VM is required instead.

Performance on Linux

TezWeb performs best on Linux due to io_uring support via the monoio runtime. Expect significantly higher throughput than the macOS benchmark numbers (40,248 RPS) shown in benchmarks.md.