You are reading the docs for rws 18.2 The latest release is 18.8. Read this page for the latest release.

All Features

A complete checklist of rust-web-server capabilities organized by category, with feature flag annotations.

This page is a single-page reference for everything the crate ships. Items that require an opt-in feature flag are annotated with the flag name in backticks.


Server / Protocol

  • HTTP/1.1 — keep-alive, chunked transfer encoding, gzip compression, ETags, range requests, 30-second idle read timeout, 30 s to receive a whole request head (408)
  • HTTP/2 — ALPN negotiation, full multiplexing, forbidden-header stripping, Alt-Svc advertisement — http2
  • HTTP/3 / QUIC — UDP listener via quinn, h3 + h3-quinn, QUIC connection-level SNI — http3 (default)
  • TLS — rustls with aws-lc-rs crypto backend; no system OpenSSL dependency; FIPS-compatible — http2
  • mTLS — client certificate verification via WebPkiClientVerifier; set RWS_CONFIG_TLS_CLIENT_CA_FILE — http2
  • Virtual-host routing — per-domain TLS certificates via SniCertResolver; .with_host("example.com") on any Router — http2
  • HTTP → HTTPS redirect — Server::run_redirect() listens on a second port and issues 301 responses — http2
  • ACME / automatic TLS — automatic certificate provisioning compatible with Let's Encrypt — acme
  • Hot reload — SIGHUP (or POST /admin/config/reload) reloads CORS rules, rate limits, log format, and TLS certs without restarting — http2
  • Graceful shutdown — SIGINT / SIGTERM drain in-flight requests before exit; SERVER_READY flag cleared on shutdown
  • Gzip compression — applied automatically based on Accept-Encoding to text bodies of at least 512 bytes (compression::MIN_COMPRESS_SIZE)
  • Static file serving — a directory with no index.html renders a dark/light-adaptive directory listing page by default; files over 256 KiB streamed (sendfile(2) on plain TCP); ETag + Last-Modified with 304 revalidation, Cache-Control: no-cache by default (RWS_CONFIG_STATIC_CACHE_CONTROL)
  • SPA fallback — RWS_CONFIG_SPA_FALLBACK=index.html serves a fallback file for unmatched routes instead of 404, for React Router/Vue Router/etc. deep links; opt-in, scoped by an extension heuristic and RWS_CONFIG_SPA_FALLBACK_EXCLUDE_PREFIXES
  • Thread pool (http1 only) — hand-rolled ThreadPool; connection-per-thread; no tokio — http1
  • Tokio async runtime — used for http2 and http3 builds; http1 is fully synchronous
  • Request framing — heads up to 64 KiB across any number of reads (431 beyond), pipelining, chunked request bodies; Content-Length + Transfer-Encoding or conflicting lengths are rejected (400) so a proxy in front can't be desynced (request smuggling)
  • Expect: 100-continue — 100 Continue is sent before the body is read, after the body-size check
  • Max request body size — RWS_CONFIG_MAX_BODY_SIZE_IN_BYTES rejects oversized bodies with 413 before buffering, on HTTP/1.1, HTTP/2 and HTTP/3
  • Outbound HTTP client — Client (sync) and AsyncClient (http2); HTTPS with http-client or http2; redirects, .form(), .body_json()
  • WebSocket (RFC 6455) — handshake and frame codec built in
  • WASM guest component — rws-wasm-shim runs App/Router/middleware inside a wasi:http/proxy component (Wasmtime, Spin, Fastly Compute); see WASM

Routing & App Building

  • App — zero-config entry point; wraps all built-in controllers (static files, CORS, health, metrics, MCP, …)
  • App::with_state(S) — state-aware dynamic router; Arc<S> shared across all handlers; builder methods .get(), .post(), .put(), .patch(), .delete()
  • App::with_async_state(S) — same API with async fn handlers — http2
  • routes! macro — ergonomic route registration: GET "/path" => handler — macros
  • Router — standalone path-based router with named parameters (:name) and trailing wildcards (*name); PathParams::get(name)
  • Controller trait — low-level is_matching / process interface; register in App::execute for maximum control
  • Typed extractors — Body (raw bytes), BodyText (UTF-8), Query (parsed query string), RequestHeaders (case-insensitive header map)
  • Typed errors — AppError enum (BadRequest, Unauthorized, Forbidden, NotFound, Conflict, UnprocessableEntity, TooManyRequests, Internal) with IntoResponse trait
  • Middleware trait — handle(request, connection, next) -> Result<Response, String>; compose via .wrap(layer)
  • WithMiddleware<A> — wraps any Application; layers applied in push order (first-pushed is outermost)
  • JSON (de)serialization — serde / serde_json integration (e.g. http_client::Response::json::<T>()) — serde
  • Tera templates — render .html templates with a serde_json::Value context via tera::render — tera
  • In-process test client — TestClient::new(app) dispatches requests without opening a TCP socket; use in unit and integration tests
  • WebSocket — RFC 6455 handshake and frame codec built in; no third-party WebSocket library
  • SSE (Server-Sent Events) — Sse builder for streaming events; ideal for streaming AI model output
  • Background scheduler — Scheduler::new().every(duration, fn).cron("…", fn).start()
  • Background job queue — JobQueue (in-memory) or PersistentJobQueue (crash-safe, model-backed); retry with exponential backoff — jobs
  • File / object storage — Storage trait; LocalStorage (disk), S3Storage (AWS S3, R2, MinIO via AWS SigV4, no SDK), or AzureBlobStorage (Azure Blob via Shared Key/Managed Identity, no SDK) — storage-local / storage-s3 / storage-azure
  • OpenAPI / Swagger — .openapi(OpenApiConfig) generates GET /openapi.json + GET /docs (Swagger UI) from registered routes — openapi
  • Email / SMTP — mailer module, plain SMTP; STARTTLS/SMTPS also needs http-client or http2 — mailer
  • Outbound HTTP client — http_client::Client (always compiled for plain HTTP); HTTPS without the server TLS stack — http-client
  • Per-route timeouts — with_timeout/with_timeout_state/with_timeout_async wrap a handler with its own deadline; TimeoutLayer for a whole app; config-driven proxy's timeout_ms
  • Request ID middleware — RequestIdLayer injects/echoes X-Request-Id on every request and response; RequestId extractor to read it

Proxy & Gateway

  • ReverseProxy — HTTP/1.1 reverse proxy middleware; round-robin backend selection
  • H2ReverseProxy — HTTP/2 upstream proxy; bridges sync middleware into async via an isolated-runtime helper (works under any tokio runtime flavor) — http2
  • GrpcProxy — wraps H2ReverseProxy; filters on Content-Type: application/grpc* — http2
  • TcpProxy — standalone L4 TCP proxy; bidirectional std::io::copy relay; round-robin backends
  • UdpProxy — standalone UDP datagram proxy; per-datagram ephemeral socket; round-robin backends
  • WsProxy — standalone WebSocket proxy; relays raw bytes after upgrade handshake
  • Config-driven proxy mode — rws.config.toml with [[upstream]] + [[route]] sections; no code required
  • Health checking — per-upstream background health checker; dead backends removed automatically; configurable thresholds and intervals
  • Load balancing — round_robin, random, ip_hash, or least_connections across live backends
  • RewriteLayer — rewrite request headers, URI, and response headers / body / status code per route; regex URI rewrites via request_uri_regex_rewrite — rewrite-regex
  • Per-route rate limiting — PerRouteRateLimit in config-driven mode; RateLimitLayer in code
  • Per-route Bearer auth — BearerAuthMiddleware in config-driven mode; JwtLayer in code
  • Route matching — host, path prefix, exact path, HTTP method, Content-Type prefix; first-match wins
  • Service discovery — BackendPool with Static/EnvPrefix/File/Dns/DnsSrv (weighted)/Consul/Docker (label value as address) sources on a poll loop, plus EtcdWatch on a dedicated live watch stream
  • Circuit breaker + retries — CircuitBreaker (Closed → Open → HalfOpen, capped probes), RedisCircuitBreaker (state shared across instances), RetryLayer on 502/503/504; ReverseProxy::with_circuit_breaker; rws_circuit_breaker_state metric
  • Canary / traffic splitting — CanaryLayer with smooth weighted round-robin, live weight updates, BackendPool groups
  • Kubernetes Ingress — KubernetesIngressWatcher watches the API (Exact/Prefix pathType, ingressClassName), .from_service_account() in-cluster
  • Private-CA upstreams — [[upstream]] tls_ca_file / ReverseProxy::tls_ca_file
  • Non-blocking proxying — config routes without middleware forward on the event loop, holding no thread

Security

  • RateLimitLayer — sliding-window rate limiter keyed by client IP; global singleton via rate_limit::global(); returns 429 when budget exceeded
  • RedisRateLimiter — fixed-window limiter in Redis for a budget shared across instances
  • BasicAuthLayer — HTTP Basic authentication middleware — auth
  • JwtLayer — JWT Bearer token validation middleware (HS256) — auth; RS256/ES256 against a static public key via ::rs256/::es256 — auth-asymmetric
  • ForwardAuthLayer — delegates the allow/deny decision to an external HTTP service (Traefik/nginx auth_request style) — auth
  • IpFilter — allowlist / denylist middleware keyed by client IP
  • crypto — Argon2id password hashing and verification; signed_cookie/verify_signed_cookie (HMAC-SHA256) and encrypted_cookie/decrypt_cookie (AES-256-GCM) — crypto
  • CSRF tokens — secure random token generation and validation — csrf
  • SSO / OAuth 2.0 / OIDC — OidcAuth login flow, RS256/ES256 id_token verification via JWKS, outbound HTTPS token exchange — sso
  • OAuth 2.0 Authorization Server — AuthServer: rws issues its own HS256 tokens (/oauth/token, /oauth/authorize) — sso-server
  • SAML 2.0 Service Provider — SamlSp: metadata, login, ACS, logout — sso-saml
  • Webhook verification — verify_webhook_signature for GitHub, Shopify, Stripe — webhook
  • Secrets manager references — secrets::resolve() for vault://, aws-sm://, azkv:// — secrets
  • CORS — built-in CORS controller; configurable origins, methods, and headers; hot-reloadable
  • mTLS — mutual TLS client certificate verification — http2
  • No OpenSSL — TLS via rustls + aws-lc-rs; fully static binaries

Observability & Ops

  • /healthz — liveness probe; always 200 OK while the server is up
  • /readyz — readiness probe; returns 503 after graceful shutdown begins (SERVER_READY flag)
  • /metrics — Prometheus text-format scrape endpoint
  • MetricsLayer — per-route rws_route_requests_total{method,path,status} counters and rws_route_duration_seconds{method,path} histograms
  • Global metrics — record_request(), record_error(), connection_open() / connection_close() counters
  • OtelLayer — OpenTelemetry trace propagation middleware
  • CacheLayer — response caching middleware
  • Structured logging — RWS_CONFIG_LOG_FORMAT=json (default), combined, or off; hot-reloadable
  • Config hot reload — SIGHUP or POST /admin/config/reload reloads CORS, rate limits, log format, TLS certs; no restart required
  • Kubernetes-ready — /healthz, /readyz, /metrics all built in; graceful SIGTERM drain; static binary with no system dependencies
  • rws --check — validates rws.config.toml (unknown keys, bad values, TLS files, undeclared upstreams, unset auth secrets) and exits 1 on errors, like nginx -t; --format=json
  • Helm chart — helm/rws/
  • Background scheduler — fixed-rate, fixed-delay and 6-field cron tasks
  • Job queue — JobQueue (in-memory) and PersistentJobQueue (model-backed); retries with exponential backoff — jobs
  • Email — Mailer over SMTP, STARTTLS or SMTPS; text + HTML — mailer

AI & MCP

  • McpServer — implements Application; serves the MCP Streamable HTTP protocol (POST /mcp, JSON-RPC 2.0)
  • Tool registration — .tool(name, description, schema, handler) — any function returning a string
  • Resource registration — .resource(uri_template, name, description, handler)
  • Prompt registration — .prompt(name, description, handler)
  • Bearer auth gate — .require_bearer(token) gates all MCP requests behind a static token
  • Fallthrough — .wrap(app) passes non-MCP requests to another Application
  • 20 built-in rws tools in the binary — config, metrics, routes, cache, rate limits, CORS, static files, reload, maintenance mode, IP blocklist, feature flags, recent requests/errors (see MCP)
  • SSE streaming — Sse builder for streaming AI tokens to browser clients
  • Protocol coverage — session context (.tool_with_context), tool annotations, image/embedded content, JSON-RPC batches, list pagination, GET /mcp SSE push, logging/setLevel, dynamic registration with list_changed, progress, completion/complete, cancellation, resources/subscribe, server-side sampling, roots/list, async tools (http2), OAuth (.require_oauth, sso)

Database / ORM

All ORM features require at least one of model-sqlite, model-postgres, or model-mysql (async, backed by sqlx; several can be compiled in, pick one with RWS_DB_BACKEND).

  • #[derive(Model)] — generates impl Model, Struct::repository(), Struct::query() — macros
  • Table and column mapping — #[table(name = "…")], #[column(name = "…")], #[primary_key], #[primary_key(auto_increment)], #[ignore]
  • DbPool — async sqlx pool: execute, query_rows, query::<T>, query_raw, begin (→ DbTransaction with commit/rollback), transaction(closure), migrate
  • Repository<T, ID> — save (INSERT or UPDATE by primary key), save_all, find_by_id, find_all, delete_by_id, delete_all_by_id, count, exists_by_id
  • QueryBuilder — fluent where_eq, filter, order_by, limit, offset, paginate, fetch_all, fetch_one, count, delete, update; placeholder tokens auto-converted to ? (SQLite/MySQL) or $N (PostgreSQL)
  • Migrations — reads *.sql files in lexicographic order; _schema_migrations table tracks applied versions; each migration wrapped in a transaction
  • Relations — HasMany<T>, HasOne<O>, BelongsTo<O> with explicit .load(&pool); no lazy loading, no hidden N+1 queries
  • SQLite — sqlx SQLite driver — model-sqlite
  • PostgreSQL — sqlx Postgres driver — model-postgres
  • MySQL / MariaDB — sqlx MySQL driver — model-mysql

Sessions & Cookies

  • CookieJar / SetCookie — parse request cookies, write every RFC 6265 attribute
  • Sessions — SessionStore (in-memory TTL), DbSessionStore (model-backed), RedisSessionStore

File / Object Storage

  • Storage trait — put / get / delete / url; swap backends without touching handlers
  • LocalStorage — local disk — storage-local
  • S3Storage — AWS S3, Cloudflare R2, MinIO via SigV4; static keys or EKS IRSA / ECS task role / EC2 IMDSv2; no AWS SDK — storage-s3
  • AzureBlobStorage — Shared Key or Managed Identity; no Azure SDK — storage-azure

Secrets

  • secrets::resolve — vault://path#field, aws-sm://name[#field], azkv://vault/secret resolved over HTTPS — secrets
  • Any RWS_CONFIG_* can be a reference — resolve_env_vars() runs in Server::setup(); a broken reference fails startup instead of running with the literal string

Dependency Injection

  • Container — TypeId-keyed service store for concrete types and dyn Trait objects
  • register::<T>(value) — wraps in Arc<T>, keyed by TypeId::of::<T>()
  • provide::<T: ?Sized>(Arc<T>) — stores trait objects directly
  • Named services — get_named::<T>(name) / register_named::<T>(name, value) for multiple instances of the same type
  • App::with_state(container) — pass the container directly as state; it's Send + Sync + 'static like any other state type, no wrapping needed
  • into_arc() — for sharing one container across multiple hand-built Applications outside of with_state
  • No external dependencies

Edit this page on GitHub