pub struct App { /* private fields */ }Expand description
Main application struct
Implementations§
Source§impl App
impl App
pub fn new() -> Self
Sourcepub fn max_body_size(self, size: Option<usize>) -> Self
pub fn max_body_size(self, size: Option<usize>) -> Self
Set maximum request body size in bytes (None = unlimited)
Sourcepub fn body_limit(self, prefix: &str, limit: Option<usize>) -> Self
pub fn body_limit(self, prefix: &str, limit: Option<usize>) -> Self
Different request body limit for everything under prefix
None removes the limit. The longest matching prefix wins over the
default from App::max_body_size, e.g. a small default with a large
limit for an upload route:
App::new().max_body_size(Some(64 * 1024)).body_limit("/api/files", Some(25 << 20)).
Sourcepub fn state<T: Send + Sync + 'static>(self, value: T) -> Self
pub fn state<T: Send + Sync + 'static>(self, value: T) -> Self
Register shared application state, readable in handlers and
middleware with Request::state
One value per type; registering the same type again replaces it. Use
interior mutability (Mutex, RwLock, atomics) for mutable state: the
value is shared by all requests and is not cloned.
use ullun::prelude::*;
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Default)]
struct Hits(AtomicU64);
async fn count(req: Request) -> Result<Response> {
let hits = req.state::<Hits>()?.0.fetch_add(1, Ordering::Relaxed) + 1;
Ok(Response::text(hits.to_string()))
}
let app = App::new().state(Hits::default()).get("/", count);Sourcepub fn background<F, Fut>(self, task: F) -> Self
pub fn background<F, Fut>(self, task: F) -> Self
Run task alongside the server, started when it starts serving
The task gets a Context with the shared state and the shutdown
signal; it should return when ctx.sleep(..) reports false or
ctx.shutdown().wait() completes. Finished tasks are awaited during
shutdown, for at most App::shutdown_grace.
use std::time::Duration;
use ullun::prelude::*;
struct Jobs;
let app = App::new().state(Jobs).background(|ctx: Context| async move {
while ctx.sleep(Duration::from_secs(60)).await {
let _jobs = ctx.state::<Jobs>().unwrap();
// purge expired sessions, refresh caches, ...
}
});Sourcepub fn tls(self, config: TlsConfig) -> Self
pub fn tls(self, config: TlsConfig) -> Self
Serve HTTPS instead of HTTP (feature tls), see crate::tls
Sourcepub fn tls_reload_every(self, interval: Duration) -> Self
pub fn tls_reload_every(self, interval: Duration) -> Self
Check the certificate files for changes this often and switch to renewed
certificates without a restart (feature tls; needs
TlsConfig::from_pem_files). A failed reload is logged and the previous
certificate stays in use.
Sourcepub fn header_read_timeout(self, timeout: impl Into<Option<Duration>>) -> Self
pub fn header_read_timeout(self, timeout: impl Into<Option<Duration>>) -> Self
How long a client may take to send the request headers (default 30
seconds, None disables). Also applies to an idle keep-alive connection
waiting for its next request, and stops slowloris-style clients that
trickle bytes to hold connections open.
Sourcepub fn max_connections(self, max: usize) -> Self
pub fn max_connections(self, max: usize) -> Self
Cap on simultaneously open connections. Further connections get an
immediate 503 with Retry-After and are closed (plain 503 bytes
even on a TLS port, which a TLS client reports as a failed handshake).
Sourcepub fn max_connections_per_ip(self, max: usize) -> Self
pub fn max_connections_per_ip(self, max: usize) -> Self
Cap on simultaneously open connections from one peer IP, so a single
client cannot use up App::max_connections. Behind a reverse proxy
every connection comes from the proxy: leave this unset there.
Sourcepub fn shutdown_grace(self, grace: Duration) -> Self
pub fn shutdown_grace(self, grace: Duration) -> Self
How long shutdown waits for in-flight requests and background tasks (default 10 seconds)
Sourcepub fn stream_body(self, prefix: &str, max_bytes: Option<u64>) -> Self
pub fn stream_body(self, prefix: &str, max_bytes: Option<u64>) -> Self
Do not buffer request bodies under prefix: handlers read them with
Request::body_stream, see crate::upload. max_bytes caps the
body (enforced while it arrives, None for no cap); max_body_size and
body_limit do not apply to these routes.
Sourcepub fn shutdown_delay(self, delay: Duration) -> Self
pub fn shutdown_delay(self, delay: Duration) -> Self
Keep serving normally for this long after the stop signal before
refusing connections (default none). Readiness checks
(Health::readiness) answer 503
during this time, so a load balancer or Kubernetes stops routing to the
instance first and no request is cut off; set it a little above the
balancer’s probe interval.
Sourcepub fn group(
self,
prefix: &str,
configure: impl FnOnce(RouteGroup) -> RouteGroup,
) -> Self
pub fn group( self, prefix: &str, configure: impl FnOnce(RouteGroup) -> RouteGroup, ) -> Self
Create a route group with a common prefix
Sourcepub fn doc(self, method: &str, path: &str, operation: Operation) -> Self
pub fn doc(self, method: &str, path: &str, operation: Operation) -> Self
Describe a registered route for the OpenAPI document
path is the path exactly as registered, e.g. /users/{id}.
Sourcepub fn openapi(self, info: OpenApiInfo) -> Self
pub fn openapi(self, info: OpenApiInfo) -> Self
Publish an OpenAPI 3.1 document of all routes (and optionally Swagger UI)
See the openapi module.
Sourcepub fn get_with_params<F, Fut>(self, path: &str, handler: F) -> Self
pub fn get_with_params<F, Fut>(self, path: &str, handler: F) -> Self
Add GET route with path params extractor
Sourcepub fn ws<F, Fut>(self, path: &str, handler: F) -> Self
pub fn ws<F, Fut>(self, path: &str, handler: F) -> Self
Accept WebSocket connections on path (feature websocket)
The handler receives the original request (path params, query, headers, extensions set by middleware) and the upgraded socket, and runs on its own task until it returns.
Sourcepub fn ws_with<F, Fut>(self, path: &str, options: WsOptions, handler: F) -> Self
pub fn ws_with<F, Fut>(self, path: &str, options: WsOptions, handler: F) -> Self
Like App::ws with explicit size limit and allowed origins
Sourcepub fn middleware<M>(self, middleware: M) -> Selfwhere
M: Middleware,
pub fn middleware<M>(self, middleware: M) -> Selfwhere
M: Middleware,
Add middleware
Sourcepub fn serve_static(self, route_prefix: &str, dir_path: &str) -> Self
pub fn serve_static(self, route_prefix: &str, dir_path: &str) -> Self
Serve static files from a directory
Sourcepub async fn run(self, addr: &str) -> Result<()>
pub async fn run(self, addr: &str) -> Result<()>
Run the server until CTRL+C or SIGTERM, then shut down gracefully
Stops accepting connections, lets in-flight requests finish and waits
for background tasks, each for at most App::shutdown_grace.
Sourcepub async fn serve(self, listener: TcpListener) -> Result<()>
pub async fn serve(self, listener: TcpListener) -> Result<()>
Serve on an already bound listener until the future is dropped.
Useful for tests, benchmarks and embedding: bind to port 0, read the
assigned port from listener.local_addr(), then call serve.
Unlike App::run, this does not install signal handlers; use
App::serve_with_shutdown for a graceful stop.
Sourcepub async fn serve_with_shutdown(
self,
listener: TcpListener,
signal: impl Future<Output = ()>,
) -> Result<()>
pub async fn serve_with_shutdown( self, listener: TcpListener, signal: impl Future<Output = ()>, ) -> Result<()>
Serve until signal completes, then shut down gracefully
New connections are refused, idle keep-alive connections are closed,
running requests finish, the shutdown signal reaches
Request::shutdown_signal and background tasks, and the call returns
once everything has stopped or App::shutdown_grace has passed.