Expand description
Static file serving for hybrid HTTP/WebSocket servers.
This module provides functionality to serve static files (HTML, CSS, JavaScript, images, etc.) alongside WebSocket connections on the same port. This allows you to build complete web applications where the frontend UI and WebSocket backend share a single server.
§Overview
The static file handler:
- Serves files from a specified directory
- Automatically detects MIME types
- Handles index files (e.g.,
index.htmlfor directory requests) - Prevents path traversal attacks
- Supports percent-encoded URLs
- Returns proper HTTP responses with status codes
§Security
The handler includes built-in security features:
- Path traversal prevention: Attempts to access
../or similar patterns are blocked - Canonical path validation: All paths are canonicalized and checked against the root
- Access control: Only files within the configured root directory can be served
§MIME Type Detection
File types are automatically detected based on file extensions:
| Extension | MIME Type | Use Case |
|---|---|---|
.html | text/html | Web pages |
.css | text/css | Stylesheets |
.js | application/javascript | JavaScript |
.json | application/json | JSON data |
.png | image/png | PNG images |
.jpg, .jpeg | image/jpeg | JPEG images |
.svg | image/svg+xml | SVG graphics |
.wasm | application/wasm | WebAssembly |
§Architecture
┌─────────────────┐
│ HTTP Request │
└────────┬────────┘
│
├──→ Parse URL path
│
├──→ Decode percent-encoding
│
├──→ Validate against root directory
│
├──→ Check if directory → serve index.html
│
├──→ Read file contents
│
└──→ Return HTTP response with MIME type§Examples
§Basic Static File Serving
use wsforge::prelude::*;
async fn ws_handler(msg: Message) -> Result<Message> {
Ok(msg)
}
let router = Router::new()
.serve_static("public") // Serve files from ./public directory
.default_handler(handler(ws_handler));
// Now accessible:
// http://localhost:8080/ -> public/index.html
// http://localhost:8080/app.js -> public/app.js
// http://localhost:8080/style.css -> public/style.css
// ws://localhost:8080 -> WebSocket handler
router.listen("127.0.0.1:8080").await?;§Web Chat Application
use wsforge::prelude::*;
use std::sync::Arc;
async fn chat_handler(
msg: Message,
State(manager): State<Arc<ConnectionManager>>,
) -> Result<()> {
manager.broadcast(msg);
Ok(())
}
let router = Router::new()
.serve_static("chat-ui") // Serve chat UI from ./chat-ui
.default_handler(handler(chat_handler));
// Directory structure:
// chat-ui/
// ├── index.html <- Main chat page
// ├── app.js <- WebSocket client logic
// ├── style.css <- Chat styling
// └── assets/
// └── logo.png <- Static assets
router.listen("127.0.0.1:8080").await?;§Single Page Application
use wsforge::prelude::*;
async fn api_handler(msg: Message) -> Result<Message> {
// Handle API WebSocket messages
Ok(msg)
}
let router = Router::new()
.serve_static("dist") // Serve built SPA from ./dist
.default_handler(handler(api_handler));
// Typical SPA structure:
// dist/
// ├── index.html
// ├── bundle.js
// ├── styles.css
// └── assets/
router.listen("0.0.0.0:3000").await?;Structs§
- Static
File Handler - Handler for serving static files from a directory.
Functions§
- http_
response - Constructs an HTTP response with the given status, content type, and body.