Skip to main content

App

Struct App 

Source
pub struct App { /* private fields */ }
Expand description

Main application struct

Implementations§

Source§

impl App

Source

pub fn new() -> Self

Source

pub fn max_body_size(self, size: Option<usize>) -> Self

Set maximum request body size in bytes (None = unlimited)

Source

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)).

Source

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);
Source

pub fn background<F, Fut>(self, task: F) -> Self
where F: FnOnce(Context) -> Fut + Send + 'static, Fut: Future<Output = ()> + Send + 'static,

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, ...
    }
});
Source

pub fn tls(self, config: TlsConfig) -> Self

Serve HTTPS instead of HTTP (feature tls), see crate::tls

Source

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.

Source

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.

Source

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).

Source

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.

Source

pub fn shutdown_grace(self, grace: Duration) -> Self

How long shutdown waits for in-flight requests and background tasks (default 10 seconds)

Source

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.

Source

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.

Source

pub fn group( self, prefix: &str, configure: impl FnOnce(RouteGroup) -> RouteGroup, ) -> Self

Create a route group with a common prefix

Source

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}.

Source

pub fn openapi(self, info: OpenApiInfo) -> Self

Publish an OpenAPI 3.1 document of all routes (and optionally Swagger UI)

See the openapi module.

Source

pub fn get<H>(self, path: &str, handler: H) -> Self
where H: Handler,

Add GET route

Source

pub fn get_with_params<F, Fut>(self, path: &str, handler: F) -> Self
where F: Fn(Params) -> Fut + Send + Sync + 'static, Fut: Future<Output = Result<Response>> + Send + 'static,

Add GET route with path params extractor

Source

pub fn post<H>(self, path: &str, handler: H) -> Self
where H: Handler,

Add POST route

Source

pub fn put<H>(self, path: &str, handler: H) -> Self
where H: Handler,

Add PUT route

Source

pub fn delete<H>(self, path: &str, handler: H) -> Self
where H: Handler,

Add DELETE route

Source

pub fn patch<H>(self, path: &str, handler: H) -> Self
where H: Handler,

Add PATCH route

Source

pub fn ws<F, Fut>(self, path: &str, handler: F) -> Self
where F: Fn(Request, WebSocket) -> Fut + Send + Sync + 'static, Fut: Future<Output = ()> + Send + 'static,

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.

Source

pub fn ws_with<F, Fut>(self, path: &str, options: WsOptions, handler: F) -> Self
where F: Fn(Request, WebSocket) -> Fut + Send + Sync + 'static, Fut: Future<Output = ()> + Send + 'static,

Like App::ws with explicit size limit and allowed origins

Source

pub fn middleware<M>(self, middleware: M) -> Self
where M: Middleware,

Add middleware

Source

pub fn serve_static(self, route_prefix: &str, dir_path: &str) -> Self

Serve static files from a directory

Source

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.

Source

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.

Source

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.

Trait Implementations§

Source§

impl Default for App

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !Freeze for App

§

impl !RefUnwindSafe for App

§

impl !Sync for App

§

impl !UnwindSafe for App

§

impl Send for App

§

impl Unpin for App

§

impl UnsafeUnpin for App

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more