# mini-static API Reference
## Server Initialization
```rust
use mini_static::Server;
use std::path::Path;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let server = Server::new(Path::new("./public"))?;
let (_port, handle) = server.run_ephemeral().await?;
// Graceful shutdown
handle.shutdown().await;
Ok(())
}
```
## Configuration
### max_connections
Control concurrent connection limits:
```rust
let server = Server::new(Path::new("./public"))?
.with_max_connections(512);
```
Default: 1024 concurrent connections
### minify
Enable CSS/JS minification:
```rust
let server = Server::new(Path::new("./public"))?
.with_minify();
```
Default: disabled. Minified output is cached in-memory, keyed by file path and mtime.
### css_bundling and bundle_root
Enable recursive `@import` bundling and register additional source directories:
```rust
let server = Server::new(Path::new("./public"))?
.with_minify()
.with_css_bundling()
.with_bundle_root(Path::new("./styles/shared"))?
.with_bundle_root(Path::new("./styles/tokens"))?;
```
- `with_css_bundling()` — recursively inlines `@import` statements in CSS files
(requires `with_minify()` first).
- `with_bundle_root(path)` — registers an external source directory for import resolution.
Can be called multiple times to add multiple external roots. Files under a bundle root
can be imported but are never directly HTTP-servable.
Default: bundling disabled.
### run() vs run_ephemeral()
- `run_ephemeral()` — binds to `127.0.0.1` with 30-second header timeout
- `run(Duration)` — binds to `127.0.0.1` with custom header timeout
Both return `(port, ServerHandle)` for graceful shutdown.
## Request Handling
Supports GET and HEAD methods on any path within the root directory.
### Responses
- **200 OK** — file content with ETag and Content-Length
- **304 Not Modified** — if If-None-Match or If-Modified-Since match
- **404 Not Found** — file not found or traversal attempt
- **405 Method Not Allowed** — methods other than GET/HEAD
### Conditional Requests
Clients can optimize bandwidth with conditional headers:
```
GET /file.js HTTP/1.1
If-None-Match: "1024-1721936400"
```
Returns 304 if the ETag matches, allowing the client to use a cached copy.
## Security
- Path traversal protection via segment-based checking
- All 404 responses identical (no filesystem oracle)
- Non-ASCII filename support with full traversal guards
- Header-read timeout prevents slowloris attacks
- Runs as unprivileged user in Docker
## Performance
- Real streaming: 64 KB chunks, bounded memory per request
- No per-chunk zero-fill overhead
- Blocking syscalls (`canonicalize`, file I/O) on dedicated thread pool
- Graceful backoff on transient accept() errors