Crate ignitia

Crate ignitia 

Source
Expand description

Β§Ignitia - A Blazing Fast Rust Web Framework πŸ”₯

Ignitia is a high-performance, production-ready web framework for Rust that ignites your web development experience with exceptional speed, memory safety, and developer ergonomics. Built on modern async Rust with Tokio and Hyper, Ignitia provides a complete toolkit for building scalable web applications, APIs, and real-time services with full HTTP/1.1, HTTP/2, HTTPS, and WebSocket support.

Β§πŸ”₯ Key Features

Β§Multi-Protocol Excellence

  • HTTP/1.1 & HTTP/2: Full support with automatic protocol negotiation via ALPN
  • HTTPS/TLS: Production-ready TLS with certificate management and modern cipher suites
  • WebSocket: Native WebSocket protocol with connection management and message routing
  • H2C Support: HTTP/2 over cleartext connections for development and internal services

Β§Performance Optimized

  • 65K+ RPS Capable: Optimized for extreme throughput with zero-cost abstractions
  • Sub-millisecond Latency: Fast request processing with efficient routing and middleware
  • Connection Pooling: Advanced connection management and resource optimization
  • Memory Efficient: Smart buffer management and minimal heap allocations

Β§Developer Experience

  • Type-Safe Routing: Compile-time route validation with automatic parameter extraction
  • Rich Extractors: JSON, forms, headers, cookies, query params, and custom extractors
  • Composable Middleware: Flexible middleware pipeline for cross-cutting concerns
  • Comprehensive Error Handling: Structured error types with detailed diagnostics

Β§Production Features

  • Advanced CORS: Regex-based origin matching with fine-grained control
  • Security Headers: Built-in security middleware with configurable policies
  • Rate Limiting: Token bucket algorithm with distributed support
  • Observability: Structured logging, metrics, and request tracing

Β§πŸš€ Quick Start Guide

Add Ignitia to your Cargo.toml with desired features:

[dependencies]
ignitia = { version = "0.2.3", features = ["tls", "websocket"] }
tokio = { version = "1.40", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }

Β§Simple HTTP Server

use ignitia::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    let router = Router::new()
        .get("/", || async {
            Ok(Response::text("Hello, Ignitia! πŸ”₯"))
        })
        .get("/health", || async {
            Ok(Response::json(serde_json::json!({"status": "healthy"}))?)
        })
        .post("/echo", |body: String| async move {
            Ok(Response::text(format!("Echo: {}", body)))
        });

    let addr = "127.0.0.1:8080".parse()?;
    Server::new(router, addr).ignitia().await
}

Β§Advanced HTTP/2 Configuration

use ignitia::{Router, Server, ServerConfig, Http2Config};
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<()> {
    let router = Router::new()
        .get("/", || async { Ok(Response::text("HTTP/2 Ready! πŸš€")) });

    // Configure HTTP/2 with optimizations
    let config = ServerConfig {
        http1_enabled: true,
        http2: Http2Config {
            enabled: true,
            enable_prior_knowledge: true, // H2C support
            max_concurrent_streams: Some(1000),
            initial_connection_window_size: Some(1024 * 1024), // 1MB
            keep_alive_interval: Some(Duration::from_secs(60)),
            adaptive_window: true,
            ..Default::default()
        },
        auto_protocol_detection: true,
        max_request_body_size: 16 * 1024 * 1024, // 16MB
        ..Default::default()
    };

    let addr = "127.0.0.1:8080".parse()?;
    Server::with_config(router, addr, config).ignitia().await
}

Β§πŸ”’ HTTPS and TLS Support

Ignitia provides comprehensive TLS support with modern security standards:

Β§Basic HTTPS Setup

use ignitia::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    let router = Router::new()
        .get("/", || async { Ok(Response::text("Secure Hello! πŸ”’")) });

    let addr = "127.0.0.1:8443".parse()?;
    Server::new(router, addr)
        .enable_https("server.crt", "server.key")?
        .ignitia()
        .await
}

Β§Advanced TLS Configuration

#[cfg(feature = "tls")]
use ignitia::{TlsConfig, TlsVersion};

#[cfg(feature = "tls")]
let tls_config = TlsConfig::new("cert.pem", "key.pem")
    .with_alpn_protocols(vec!["h2", "http/1.1"]) // HTTP/2 priority
    .with_protocol_versions(&[TlsVersion::TlsV12, TlsVersion::TlsV13])
    .with_cipher_suites(&["TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"])
    .enable_client_cert_verification();

#[cfg(feature = "tls")]
Server::new(router, addr)
    .with_tls(tls_config)?
    .ignitia()
    .await

Β§Development with Self-Signed Certificates

#[cfg(all(feature = "tls", feature = "self-signed"))]
Server::new(router, addr)
    .with_self_signed_cert("localhost")? // ⚠️ Development only!
    .ignitia()
    .await

Β§HTTP to HTTPS Redirect

// Automatically redirect all HTTP traffic to HTTPS
tokio::spawn(async move {
    Server::new(redirect_router, "0.0.0.0:80".parse().unwrap())
        .redirect_to_https(443)
        .ignitia()
        .await
});

§🌐 Advanced CORS Configuration

Comprehensive CORS support for secure cross-origin requests:

Β§Production CORS Setup

use ignitia::{CorsMiddleware, Method};

let cors = CorsMiddleware::new()
    .allowed_origins(&["https://myapp.com", "https://admin.myapp.com"])
    .allowed_methods(&[Method::GET, Method::POST, Method::PUT, Method::DELETE])
    .allowed_headers(&["Content-Type", "Authorization", "X-API-Key"])
    .expose_headers(&["X-Total-Count", "X-Rate-Limit-Remaining"])
    .allow_credentials()
    .max_age(86400) // 24 hours
    .build()?;

let router = Router::new()
    .middleware(cors)
    .get("/api/users", || async { Ok(Response::json("users")?) });

Β§Regex-Based Origin Matching

let cors = CorsMiddleware::new()
    .allowed_origin_regex(r"https://.*\.myapp\.com") // All subdomains
    .allowed_origin_regex(r"https://localhost:\d+") // Local development ports
    .build()?;

Β§Convenience Configurations

// Development (permissive)
let dev_cors = CorsMiddleware::permissive();

// Production API
let api_cors = CorsMiddleware::default_api();

// Secure API with specific origins
let secure_cors = CorsMiddleware::secure_api(&[
    "https://app.example.com",
    "https://admin.example.com"
]);

Β§πŸ“‘ HTTP/2 Features and Optimization

Leverage HTTP/2’s advanced features for maximum performance:

Β§HTTP/2 Stream Management

use ignitia::{Http2Config, ServerConfig};
use std::time::Duration;

let http2_config = Http2Config {
    enabled: true,
    enable_prior_knowledge: true, // H2C support
    max_concurrent_streams: Some(1000),
    initial_connection_window_size: Some(1024 * 1024), // 1MB
    initial_stream_window_size: Some(64 * 1024), // 64KB
    max_frame_size: Some(16 * 1024), // 16KB
    keep_alive_interval: Some(Duration::from_secs(60)),
    keep_alive_timeout: Some(Duration::from_secs(20)),
    adaptive_window: true,
    max_header_list_size: Some(16 * 1024),
};

let server_config = ServerConfig {
    http1_enabled: true, // Support both protocols
    http2: http2_config,
    auto_protocol_detection: true,
    ..Default::default()
};

Β§Testing HTTP/2 Connections

curl -v --http2 https://localhost:8443/

curl -v --http2-prior-knowledge http://localhost:8080/

curl -v --http2 -H "Accept: application/json" https://localhost:8443/api/status

Β§πŸ“š Core Concepts and Architecture

Β§Protocol Negotiation Flow

Ignitia automatically selects the optimal protocol:

// 1. TLS connections use ALPN negotiation
// Client advertises: ["h2", "http/1.1"]
// Server selects: "h2" (HTTP/2 preferred)

// 2. Cleartext connections check for HTTP/2 Prior Knowledge
// Client sends: PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
// Server responds with HTTP/2 connection preface

// 3. HTTP/1.1 upgrade mechanism
// Client sends: Upgrade: h2c, Connection: Upgrade, HTTP2-Settings: ...
// Server responds: HTTP/1.1 101 Switching Protocols

Β§Request/Response Lifecycle

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Ignitia Request Pipeline                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. Connection Accept (TCP/TLS)
   β”œβ”€ Protocol Detection (HTTP/1.1, HTTP/2, WebSocket)
   β”œβ”€ TLS Handshake (if HTTPS)
   └─ Connection Pooling

2. Request Parsing
   β”œβ”€ Header Parsing and Validation
   β”œβ”€ Body Streaming (with size limits)
   └─ Protocol-specific Processing

3. Middleware Pipeline (Request Phase)
   β”œβ”€ CORS Preflight Handling
   β”œβ”€ Authentication/Authorization
   β”œβ”€ Rate Limiting
   β”œβ”€ Request ID Generation
   └─ Custom middleware

4. Route Resolution
   β”œβ”€ Path Matching (radix tree)
   β”œβ”€ Parameter Extraction
   β”œβ”€ Handler Selection
   └─ WebSocket Upgrade Detection

5. Handler Execution
   β”œβ”€ Extractor Processing
   β”œβ”€ Business Logic
   └─ Response Generation

6. Middleware Pipeline (Response Phase)
   β”œβ”€ Error Handling
   β”œβ”€ Response Headers (Security, CORS)
   β”œβ”€ Compression
   └─ Logging

7. Response Transmission
   β”œβ”€ Protocol-specific Formatting
   β”œβ”€ Connection Management
   └─ Metrics Collection

Β§Advanced Request Extractors

use ignitia::{Path, Query, Json, Headers, Cookies, Body, Method, Uri};
use serde::Deserialize;

#[derive(Deserialize)]
struct UserQuery {
    page: Option<u32>,
    limit: Option<u32>,
    sort: Option<String>,
    filter: Option<String>,
}

#[derive(Deserialize)]
struct CreateUserRequest {
    name: String,
    email: String,
    role: Option<String>,
}

async fn advanced_handler(
    Path(user_id): Path<u64>,
    Query(query): Query<UserQuery>,
    Json(data): Json<CreateUserRequest>,
    headers: Headers,
    cookies: Cookies,
    body: Body,
    method: Method,
    uri: Uri,
) -> ignitia::Result<Response> {
    // Access HTTP version and protocol information
    let http_version = headers.get("version").unwrap_or("HTTP/1.1");
    let user_agent = headers.get("user-agent").unwrap_or("Unknown");

    // Handle authentication from cookies
    let session_token = cookies.get("session_token");

    Response::json(serde_json::json!({
        "user_id": user_id,
        "query": {
            "page": query.page.unwrap_or(1),
            "limit": query.limit.unwrap_or(10),
            "sort": query.sort.unwrap_or_else(|| "created_at".to_string()),
            "filter": query.filter
        },
        "method": method.as_str(),
        "path": uri.path(),
        "query_string": uri.query(),
        "http_version": http_version,
        "user_agent": user_agent,
        "authenticated": session_token.is_some(),
        "content_length": body.len(),
        "timestamp": chrono::Utc::now().timestamp()
    }))
}

Β§Comprehensive Middleware Pipeline

use ignitia::{
    Router, LoggerMiddleware, CorsMiddleware, AuthMiddleware,
    ErrorHandlerMiddleware, RateLimitingMiddleware, SecurityMiddleware
};

let router = Router::new()
    // Request logging with detailed HTTP information
    .middleware(LoggerMiddleware::new()
        .include_headers(true)
        .include_body_size(true)
        .include_timing(true))

    // Security headers (HSTS, CSP, etc.)
    .middleware(SecurityMiddleware::new()
        .enable_hsts(Duration::from_secs(31536000)) // 1 year
        .content_security_policy("default-src 'self'")
        .frame_options("DENY")
        .content_type_options("nosniff"))

    // Rate limiting with token bucket algorithm
    .middleware(RateLimitingMiddleware::new()
        .requests_per_minute(1000)
        .burst_size(100)
        .enable_headers(true))

    // CORS with production configuration
    .middleware(CorsMiddleware::secure_api(&["https://myapp.com"])
        .allow_credentials()
        .max_age(3600)
        .build()?)

    // Authentication for protected routes
    .middleware(AuthMiddleware::bearer_token("your-secret-key")
        .protect_paths(&["/api/admin", "/api/user/profile"])
        .optional_paths(&["/api/public"]))

    // Global error handling with detailed responses
    .middleware(ErrorHandlerMiddleware::new()
        .with_stack_trace(cfg!(debug_assertions))
        .with_error_id(true)
        .with_logging(true))

    // Application routes
    .get("/", || async { Ok(Response::text("Hello, World!")) })
    .get("/api/health", health_check_handler)
    .post("/api/users", create_user_handler)
    .get("/api/users/:id", get_user_handler)
    .put("/api/users/:id", update_user_handler)
    .delete("/api/users/:id", delete_user_handler);

§🌐 WebSocket Support

Full-featured WebSocket implementation with HTTP/2 compatibility:

Β§Enable WebSocket Feature

[dependencies]
ignitia = { version = "0.2.3", features = ["websocket", "tls"] }

Β§Advanced WebSocket Server

#[cfg(feature = "websocket")]
use ignitia::websocket::{websocket_handler, Message, WebSocketConnection};
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

#[cfg(feature = "websocket")]
type ClientMap = Arc<Mutex<HashMap<String, WebSocketConnection>>>;

#[cfg(feature = "websocket")]
let clients: ClientMap = Arc::new(Mutex::new(HashMap::new()));

#[cfg(feature = "websocket")]
let router = Router::new()
    // Simple echo WebSocket
    .websocket("/ws/echo", websocket_handler(|mut ws: WebSocketConnection| async move {
        while let Some(message) = ws.recv().await {
            match message {
                Message::Text(text) => {
                    ws.send_text(format!("Echo: {}", text)).await?;
                }
                Message::Binary(data) => {
                    ws.send_bytes(data).await?;
                }
                Message::Ping(data) => {
                    ws.send_pong(data).await?;
                }
                Message::Close(_) => break,
                _ => {}
            }
        }
        Ok(())
    }))

    // Chat room WebSocket
    .websocket("/ws/chat", {
        let clients = Arc::clone(&clients);
        websocket_handler(move |ws: WebSocketConnection| {
            let clients = Arc::clone(&clients);
            async move {
                let client_id = uuid::Uuid::new_v4().to_string();
                clients.lock().unwrap().insert(client_id.clone(), ws.clone());

                while let Some(message) = ws.recv().await {
                    if let Message::Text(text) = message {
                        let broadcast = format!("User {}: {}", client_id, text);

                        // Broadcast to all connected clients
                        let mut disconnected = Vec::new();
                        for (id, client_ws) in clients.lock().unwrap().iter() {
                            if let Err(_) = client_ws.send_text(broadcast.clone()).await {
                                disconnected.push(id.clone());
                            }
                        }

                        // Remove disconnected clients
                        let mut clients_lock = clients.lock().unwrap();
                        for id in disconnected {
                            clients_lock.remove(&id);
                        }
                    }
                }

                clients.lock().unwrap().remove(&client_id);
                Ok(())
            }
        })
    })

    // JSON API over WebSocket
    .websocket("/ws/api", websocket_handler(|ws: WebSocketConnection| async move {
        while let Some(message) = ws.recv().await {
            if let Message::Text(text) = message {
                match serde_json::from_str::<serde_json::Value>(&text) {
                    Ok(request) => {
                        let response = process_api_request(request).await?;
                        ws.send_json(&response).await?;
                    }
                    Err(_) => {
                        ws.send_json(&serde_json::json!({
                            "error": "Invalid JSON format"
                        })).await?;
                    }
                }
            }
        }
        Ok(())
    }));

Β§WebSocket with HTTPS

#[cfg(feature = "websocket")]
#[tokio::main]
async fn main() -> Result<()> {
    Server::new(router, "127.0.0.1:8443".parse()?)
        .enable_https("cert.pem", "key.pem")?
        .ignitia()
        .await

    // Client connects via: wss://localhost:8443/ws/echo
}

Β§πŸ—οΈ Framework Architecture

Ignitia’s layered architecture supports multiple protocols and advanced features:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           Application Layer                                 β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚   Routes    β”‚ β”‚ Middleware  β”‚ β”‚    CORS     β”‚ β”‚      WebSocket          β”‚ β”‚
β”‚ β”‚  & Handlers β”‚ β”‚   Pipeline  β”‚ β”‚Configurationβ”‚ β”‚      Handlers           β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                           Ignitia Framework                                β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚   Router    β”‚ β”‚   Server    β”‚ β”‚    TLS      β”‚ β”‚      WebSocket          β”‚ β”‚
β”‚ β”‚             β”‚ β”‚             β”‚ β”‚             β”‚ β”‚       Support           β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚  Route  β”‚ β”‚ β”‚ β”‚HTTP/1.1 β”‚ β”‚ β”‚ β”‚  ALPN   β”‚ β”‚ β”‚ β”‚    Connection       β”‚ β”‚ β”‚
β”‚ β”‚ β”‚Matching β”‚ β”‚ β”‚ β”‚Support  β”‚ β”‚ β”‚ β”‚Protocol β”‚ β”‚ β”‚ β”‚    Management       β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚Negotiat.β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚             β”‚ β”‚             β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚                         β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚Handler  β”‚ β”‚ β”‚ β”‚HTTP/2   β”‚ β”‚ β”‚ β”‚  Cert   β”‚ β”‚ β”‚ β”‚      Message        β”‚ β”‚ β”‚
β”‚ β”‚ β”‚Extract  β”‚ β”‚ β”‚ β”‚Support  β”‚ β”‚ β”‚ β”‚Managementβ”‚ β”‚ β”‚ β”‚     Processing      β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                          Runtime Layer (Tokio)                            β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚    HTTP     β”‚ β”‚     TLS     β”‚ β”‚     TCP     β”‚ β”‚       Async I/O         β”‚ β”‚
β”‚ β”‚   (Hyper)   β”‚ β”‚  (Rustls)   β”‚ β”‚  Listeners  β”‚ β”‚      & Futures          β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Β§πŸ”§ Feature Configuration

Ignitia uses Cargo features for optional functionality:

Β§Available Features

[dependencies]
ignitia = {
    version = "0.2.3",
    features = ["tls", "websocket", "self-signed"]
}

ignitia = { version = "0.2.3", features = ["tls"] }        # HTTPS support only
ignitia = { version = "0.2.3", features = ["websocket"] }  # WebSocket support only
ignitia = "0.2.3"                                          # HTTP only (minimal)

Β§Feature Descriptions

  • tls: Enables HTTPS/TLS support with certificate management and ALPN protocol negotiation
  • websocket: Enables WebSocket protocol support with connection management and message routing
  • self-signed: Enables self-signed certificate generation for development environments
  • default: No additional features (HTTP/1.1 and HTTP/2 over cleartext only)

§🎯 Performance Benchmarks

Ignitia is optimized for exceptional performance:

Β§Throughput (Requests/Second)

  • Simple JSON API: 65,000+ RPS
  • Static file serving: 85,000+ RPS
  • WebSocket connections: 25,000+ concurrent
  • HTTPS with TLS 1.3: 55,000+ RPS

Β§Latency (99th percentile)

  • HTTP/1.1: < 1ms
  • HTTP/2: < 1.2ms
  • HTTPS: < 1.5ms
  • WebSocket message: < 0.8ms

Β§Resource Usage

  • Memory per connection: ~2KB
  • CPU overhead: < 5% at 50K RPS
  • Binary size: ~4MB (with all features)

Β§πŸ§ͺ Testing Your Applications

Comprehensive testing utilities and examples:

#[cfg(test)]
mod tests {
    use super::*;
    use ignitia::{Router, Response, Method};

    #[tokio::test]
    async fn test_basic_routing() {
        let router = Router::new()
            .get("/health", || async {
                Ok(Response::json(serde_json::json!({"status": "ok"}))?)
            });

        // Test route registration
        assert!(router.has_route(&Method::GET, "/health"));
        assert!(!router.has_route(&Method::POST, "/health"));
    }

    #[tokio::test]
    async fn test_cors_middleware() {
        let cors = CorsMiddleware::new()
            .allowed_origins(&["https://example.com"])
            .allowed_methods(&[Method::GET, Method::POST])
            .build().unwrap();

        let router = Router::new()
            .middleware(cors)
            .get("/api/test", || async {
                Ok(Response::text("CORS enabled"))
            });

        // Test CORS preflight
        assert!(router.handles_cors_preflight("/api/test"));
    }

    #[tokio::test]
    async fn test_https_configuration() {
        let config = ServerConfig::default()
            .with_https_redirect(443);

        assert!(config.redirect_http_to_https);
        assert_eq!(config.https_port, Some(443));
    }

    #[cfg(feature = "websocket")]
    #[tokio::test]
    async fn test_websocket_upgrade() {
        use ignitia::websocket::websocket_handler;

        let router = Router::new()
            .websocket("/ws", websocket_handler(|_ws| async { Ok(()) }));

        assert!(router.has_websocket_route("/ws"));
    }
}

Β§πŸ” Production Examples

Β§Complete REST API with Authentication

use ignitia::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct ApiResponse<T> {
    success: bool,
    data: T,
    timestamp: i64,
    version: String,
}

#[derive(Serialize, Deserialize)]
struct User {
    id: u64,
    name: String,
    email: String,
    role: String,
}

async fn get_user_handler(Path(id): Path<u64>) -> Result<Response> {
    // Simulate database lookup
    let user = User {
        id,
        name: "John Doe".to_string(),
        email: "john@example.com".to_string(),
        role: "user".to_string(),
    };

    let response = ApiResponse {
        success: true,
        data: user,
        timestamp: chrono::Utc::now().timestamp(),
        version: "1.0.0".to_string(),
    };

    Response::json(response)
}

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize logging
    tracing_subscriber::init();

    let router = Router::new()
        // Global middleware pipeline
        .middleware(LoggerMiddleware::new())
        .middleware(SecurityMiddleware::strict())
        .middleware(CorsMiddleware::secure_api(&["https://myapp.com"])
            .build()?)
        .middleware(RateLimitingMiddleware::new()
            .requests_per_minute(10000))

        // Public routes
        .get("/", || async { Ok(Response::text("API v1.0")) })
        .get("/health", || async {
            Ok(Response::json(serde_json::json!({
                "status": "healthy",
                "timestamp": chrono::Utc::now().timestamp(),
                "version": env!("CARGO_PKG_VERSION")
            }))?)
        })

        // Protected API routes
        .middleware(AuthMiddleware::bearer_token("your-jwt-secret")
            .protect_paths(&["/api/v1/"]))
        .get("/api/v1/users/:id", get_user_handler)
        .post("/api/v1/users", create_user_handler)
        .put("/api/v1/users/:id", update_user_handler)
        .delete("/api/v1/users/:id", delete_user_handler);

    // Production HTTPS server
    let addr = "0.0.0.0:8443".parse()?;
    Server::new(router, addr)
        .enable_https("production.crt", "production.key")?
        .with_performance_config(PerformanceConfig::max_rps())
        .ignitia()
        .await
}

Β§Real-time Chat Application

#[cfg(feature = "websocket")]
use ignitia::websocket::{websocket_handler, Message, WebSocketConnection};
use std::sync::{Arc, RwLock};
use std::collections::HashMap;
use tokio::sync::broadcast;

#[cfg(feature = "websocket")]
type ChatClients = Arc<RwLock<HashMap<String, WebSocketConnection>>>;

#[cfg(feature = "websocket")]
#[tokio::main]
async fn main() -> Result<()> {
    let (broadcast_tx, _) = broadcast::channel(1000);
    let clients: ChatClients = Arc::new(RwLock::new(HashMap::new()));

    let router = Router::new()
        // Serve chat UI
        .get("/", || async {
            Ok(Response::html(include_str!("../static/chat.html")))
        })

        // WebSocket chat endpoint
        .websocket("/ws/chat", {
            let clients = Arc::clone(&clients);
            let broadcast_tx = broadcast_tx.clone();

            websocket_handler(move |ws: WebSocketConnection| {
                let clients = Arc::clone(&clients);
                let broadcast_tx = broadcast_tx.clone();
                let mut broadcast_rx = broadcast_tx.subscribe();

                async move {
                    let client_id = uuid::Uuid::new_v4().to_string();
                    clients.write().unwrap().insert(client_id.clone(), ws.clone());

                    // Spawn broadcast listener
                    let ws_clone = ws.clone();
                    tokio::spawn(async move {
                        while let Ok(message) = broadcast_rx.recv().await {
                            if let Err(_) = ws_clone.send_text(message).await {
                                break;
                            }
                        }
                    });

                    // Handle incoming messages
                    while let Some(message) = ws.recv().await {
                        if let Message::Text(text) = message {
                            let chat_message = format!("User {}: {}", client_id, text);
                            let _ = broadcast_tx.send(chat_message);
                        }
                    }

                    // Cleanup
                    clients.write().unwrap().remove(&client_id);
                    Ok(())
                }
            })
        });

    // HTTPS chat server
    let addr = "127.0.0.1:8443".parse()?;
    Server::new(router, addr)
        .enable_https("chat.crt", "chat.key")?
        .ignitia()
        .await
}

Β§πŸ“– Module Documentation

Β§Core Modules

  • cookie: HTTP cookie handling with secure defaults and session management
  • error: Comprehensive error handling with structured error types and custom responses
  • extension: Type-safe request/response extensions for sharing data between middleware
  • handler: Request handlers, extractors, and handler trait implementations
  • middleware: Middleware system including CORS, authentication, logging, and security
  • multipart: Multipart form data parsing with file upload support
  • request: HTTP request representation with efficient parsing and validation
  • response: HTTP response building with content negotiation and streaming
  • router: High-performance route matching with parameter extraction and middleware composition
  • server: Multi-protocol server with HTTP/1.1, HTTP/2, TLS, and WebSocket support
  • utils: Utility functions for common web development tasks

Β§Feature-Gated Modules

  • websocket: WebSocket protocol support with connection management (requires websocket feature)

§🀝 Contributing

We welcome contributions! Please see our Contributing Guidelines for information on:

  • Setting up the development environment
  • Running tests and benchmarks
  • Code style and documentation standards
  • Submitting pull requests
  • Reporting issues and feature requests

Β§πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Β§πŸ”— Resources

Re-exportsΒ§

pub use cookie::Cookie;
pub use cookie::CookieJar;
pub use cookie::SameSite;
pub use error::CustomError;
pub use error::Error;
pub use error::ErrorExt;
pub use error::ErrorHandler;
pub use error::ErrorHandlerType;
pub use error::ErrorHandlerWithRequest;
pub use error::ErrorResponse;
pub use error::Result;
pub use extension::Extension;
pub use extension::Extensions;
pub use handler::extractor::Body;
pub use handler::extractor::Cookies;
pub use handler::extractor::Form;
pub use handler::extractor::Headers;
pub use handler::extractor::Json;
pub use handler::extractor::Method as IgnitiaMethod;
pub use handler::extractor::Path;
pub use handler::extractor::Query;
pub use handler::extractor::State;
pub use handler::extractor::Uri;
pub use handler::handler_fn;
pub use handler::into_handler;
pub use handler::raw_handler;
pub use handler::Handler;
pub use handler::HandlerFn;
pub use handler::IntoHandler;
pub use handler::RawRequest;
pub use middleware::AuthMiddleware;
pub use middleware::BodySizeLimitBuilder;
pub use middleware::BodySizeLimitMiddleware;
pub use middleware::CompressionMiddleware;
pub use middleware::CorsMiddleware;
pub use middleware::ErrorHandlerMiddleware;
pub use middleware::IdGenerator;
pub use middleware::LoggerMiddleware;
pub use middleware::Middleware;
pub use middleware::RateLimitConfig;
pub use middleware::RateLimitInfo;
pub use middleware::RateLimitStats;
pub use middleware::RateLimitingMiddleware;
pub use middleware::RequestIdMiddleware;
pub use middleware::SecurityMiddleware;
pub use request::Request;
pub use response::Response;
pub use response::ResponseBuilder;
pub use router::LayeredHandler;
pub use router::Route;
pub use router::Router;
pub use router::RouterMode;
pub use server::Http2Config;
pub use server::PerformanceConfig;
pub use server::PoolConfig;
pub use server::Server;
pub use server::ServerConfig;
pub use multipart::Field;
pub use multipart::FileField;
pub use multipart::Multipart;
pub use multipart::MultipartConfig;
pub use multipart::MultipartError;
pub use multipart::TextField;
pub use server::tls::TlsConfig;tls
pub use server::tls::TlsError;tls
pub use server::tls::TlsVersion;tls
pub use websocket::handle_websocket_upgrade;websocket
pub use websocket::is_websocket_request;websocket
pub use websocket::upgrade_connection;websocket
pub use websocket::websocket_batch_handler;websocket
pub use websocket::websocket_handler;websocket
pub use websocket::websocket_message_handler;websocket
pub use websocket::BatchMessageHandler;websocket
pub use websocket::CloseFrame;websocket
pub use websocket::Message;websocket
pub use websocket::MessageType;websocket
pub use websocket::OptimizedMessageHandler;websocket
pub use websocket::WebSocketConnection;websocket
pub use websocket::WebSocketHandler;websocket

ModulesΒ§

cookie
Cookie Handling Module
error
Error Handling Module
extension
Extension System Module
handler
Request Handler System
info
Framework information and build details Framework information and build metadata.
middleware
Middleware System Module
multipart
Multipart Form Data Support
prelude
Prelude module for convenient imports
request
HTTP Request Handling Module
response
HTTP Response Generation Module
router
Router Module
server
High-performance HTTP/HTTPS server implementation with advanced optimizations
utils
Utility Functions and Helpers
websocketwebsocket
WebSocket Support Module

MacrosΒ§

define_error
Macro for easily defining custom error enums with automatic trait implementations.

StructsΒ§

HeaderMap
HTTP types from the http crate A set of HTTP headers
HeaderValue
HTTP types from the http crate Represents an HTTP header field value.
Method
HTTP types from the http crate The Request Method (VERB)
StatusCode
HTTP types from the http crate An HTTP status code (status-code in RFC 9110 et al.).

ConstantsΒ§

NAME
The name of the Ignitia framework
VERSION
The current version of the Ignitia framework

Attribute MacrosΒ§

async_trait
Async trait support for defining async traits