elif-http 0.8.8

HTTP server core for the elif.rs LLM-friendly web framework
Documentation
# Middleware System

## Overview

The elif.rs framework provides a comprehensive middleware system supporting both legacy and modern patterns. All middleware uses the new V2 system with Laravel-style `handle(request, next)` pattern.

## New Middleware (V2 System)

### CompressionMiddleware

Provides response compression using tower-http's battle-tested CompressionLayer.

```rust
use elif_http::middleware::CompressionMiddleware;
use tower_http::compression::CompressionLevel;

let middleware = CompressionMiddleware::new()
    .best()                 // Maximum compression level
    .gzip_only()           // Only use gzip (disable brotli)
    .level(CompressionLevel::Precise(6)); // Custom compression level

// Usage in pipeline
let pipeline = MiddlewarePipelineV2::new()
    .add(CompressionMiddleware::new())
    .add(other_middleware);
```

Features:
- Uses tower-http's proven compression implementation
- Gzip, Brotli, and Deflate support
- Configurable compression levels (fast/best/precise)
- Automatic Accept-Encoding negotiation
- Built-in content-type and size filtering

### ETagMiddleware

Generates HTTP ETags and handles conditional requests (If-None-Match, If-Match).

```rust
use elif_http::middleware::{ETagMiddleware, ETagStrategy};

let middleware = ETagMiddleware::new()
    .strategy(ETagStrategy::WeakBodyHash)  // Use weak ETags
    .min_size(512)                        // Minimum response size
    .content_type("text/html");           // Additional content types

// Usage
let pipeline = MiddlewarePipelineV2::new()
    .add(ETagMiddleware::new())
    .add(other_middleware);
```

Features:
- Strong and weak ETag generation
- RFC 7232 compliant conditional request handling
- 304 Not Modified for GET/HEAD, 412 Precondition Failed for state-changing methods
- Configurable generation strategies
- Content-type filtering

### ContentNegotiationMiddleware

Handles HTTP content negotiation based on Accept headers.

```rust
use elif_http::middleware::{ContentNegotiationMiddleware, ContentType};

let middleware = ContentNegotiationMiddleware::new()
    .default_type(ContentType::Html)    // Default when negotiation fails
    .support(ContentType::Csv)          // Add CSV support
    .converter(ContentType::Xml, |json_value| {
        // Custom XML converter
        Ok(b"<xml>converted</xml>".to_vec())
    });
```

Supported formats:
- JSON (default)
- HTML with pretty formatting
- Plain text
- XML (with custom converter)
- CSV (with custom converter)

### RequestIdMiddleware

Generates and tracks unique request IDs for distributed tracing.

```rust
use elif_http::middleware::{RequestIdMiddleware, RequestIdStrategy};

let middleware = RequestIdMiddleware::new()
    .header_name("x-trace-id")          // Custom header name
    .prefixed("api")                    // Prefix: "api-{uuid}"
    .override_existing()                // Replace existing request IDs
    .no_logging();                      // Disable automatic logging

// Access request ID in handlers
use elif_http::middleware::RequestIdExt;

async fn handler(request: ElifRequest) -> ElifResponse {
    if let Some(request_id) = request.request_id() {
        println!("Processing request: {}", request_id);
    }
    ElifResponse::ok().text("Hello")
}
```

ID generation strategies:
- UUID v4 (random, default)
- UUID v1 (timestamp-based)
- Counter (not recommended for distributed systems)
- Prefixed UUID
- Custom generator function

### MaintenanceModeMiddleware

Enables temporary service maintenance mode.

```rust
use elif_http::middleware::{MaintenanceModeMiddleware, MaintenanceResponse, PathMatch};

let middleware = MaintenanceModeMiddleware::new()
    .allow_path("/health")              // Always allow health checks
    .allow_prefix("/admin")             // Allow admin panel
    .allow_ip("192.168.1.100")          // Bypass for specific IP
    .bypass_header("x-admin-key", "secret") // Bypass with header
    .response(MaintenanceResponse::Html(
        r#"<h1>Under Maintenance</h1><p>Back soon!</p>"#.to_string()
    ))
    .retry_after(3600);                 // 1 hour retry

// Dynamic control
let builder = MaintenanceModeBuilder::new();
let middleware = builder.build();

// Enable/disable at runtime
builder.enable();   // Activate maintenance mode
builder.disable();  // Deactivate maintenance mode
```

Features:
- Dynamic enable/disable
- Path whitelisting (exact, prefix, regex)
- IP whitelisting
- Bypass headers
- Custom maintenance responses (HTML, JSON, text, file)
- Retry-After header support

## Usage Patterns

### Basic Pipeline

```rust
use elif_http::middleware::v2::MiddlewarePipelineV2;
use elif_http::middleware::{
    CompressionMiddleware, ETagMiddleware, ContentNegotiationMiddleware,
    RequestIdMiddleware, MaintenanceModeMiddleware
};

let pipeline = MiddlewarePipelineV2::new()
    .add(MaintenanceModeMiddleware::new())      // Check maintenance first
    .add(RequestIdMiddleware::new())            // Add request ID
    .add(ETagMiddleware::new())                 // Handle conditional requests
    .add(ContentNegotiationMiddleware::new())   // Content negotiation
    .add(CompressionMiddleware::new());         // Compress responses last
```

### Advanced Configuration

```rust
// Comprehensive setup
let pipeline = MiddlewarePipelineV2::new()
    .add(MaintenanceModeMiddleware::new()
        .allow_path("/health")
        .bypass_header("x-admin", "secret"))
    .add(RequestIdMiddleware::new()
        .prefixed("api")
        .header_name("x-request-id"))
    .add(ETagMiddleware::new()
        .weak()                    // Use weak ETags
        .min_size(1024))
    .add(ContentNegotiationMiddleware::new()
        .default_type(ContentType::Json))
    .add(CompressionMiddleware::new()
        .level(9)                  // Maximum compression
        .min_size(2048));
```

### Router Integration

```rust
use elif_http::Router;

let router = Router::new()
    .middleware_pipeline(pipeline)
    .get("/api/data", handler)
    .post("/api/submit", submit_handler);
```

## Testing

All middleware includes comprehensive unit tests. To run tests:

```bash
cargo test middleware::utils
```

Individual middleware tests:
```bash
cargo test compression
cargo test etag  
cargo test content_negotiation
cargo test request_id
cargo test maintenance_mode
```

## Performance Considerations

1. **Middleware Order**: Place cheaper middleware first (RequestId) and expensive ones last (Compression)
2. **Compression**: Only enable for appropriate content types and sizes
3. **ETag**: Use weak ETags for better performance when semantic equivalence is sufficient
4. **Content Negotiation**: Consider caching converted responses for high-traffic endpoints
5. **Maintenance Mode**: Minimal overhead when disabled

## Migration from V1

The old middleware system is deprecated. To migrate:

```rust
// Old V1 middleware
impl Middleware for MyMiddleware {
    fn process_request(&self, request: Request) -> BoxFuture<Result<Request, Response>> {
        // ... 
    }
    fn process_response(&self, response: Response) -> BoxFuture<Response> {
        // ...
    }
}

// New V2 middleware  
#[derive(Debug)]
struct MyMiddleware;

impl crate::middleware::v2::Middleware for MyMiddleware {
    fn handle(&self, request: ElifRequest, next: Next) -> NextFuture<'static> {
        Box::pin(async move {
            // Before request processing
            
            let response = next.run(request).await;
            
            // After response processing
            
            response
        })
    }
}
```

For backward compatibility, use `MiddlewareAdapter`:

```rust
use elif_http::middleware::v2::MiddlewareAdapter;

let pipeline = MiddlewarePipelineV2::new()
    .add(MiddlewareAdapter::new(OldMiddleware::new()))  // Wrap old middleware
    .add(NewV2Middleware::new());                       // Use new directly
```

## Error Handling

All middleware follows the framework error format:

```json
{
    "error": {
        "code": "middleware_error",
        "message": "Human readable message",
        "hint": "Optional hint for resolution"
    }
}
```

Common error scenarios:
- **406 Not Acceptable**: Content negotiation failed
- **412 Precondition Failed**: ETag validation failed  
- **503 Service Unavailable**: Maintenance mode active

## Best Practices

1. **Always implement Debug** for middleware structs
2. **Use builder patterns** for configuration
3. **Handle errors gracefully** - don't panic
4. **Log important events** but avoid sensitive data
5. **Test edge cases** including malformed headers
6. **Document configuration options** clearly
7. **Follow the Laravel-style pattern** consistently