Skip to main content

Crate rainier_middleware

Crate rainier_middleware 

Source
Expand description

§rainier-middleware

Middleware as values: the Middleware contract, the Pipeline that runs a chain of it, and the MiddlewareStack a route or a group attaches.

use rainier_http::{Request, Response, StatusCode};
use rainier_middleware::{Middleware, Next, Pipeline};

struct RequireApiKey;

#[async_trait::async_trait]
impl Middleware for RequireApiKey {
    async fn handle(&self, request: Request, next: Next) -> Response {
        match request.header("x-api-key") {
            Some("secret") => next.run(request).await,
            _ => Response::new(StatusCode::UNAUTHORIZED),
        }
    }
}

let pipeline = Pipeline::new()
    .through(RequireApiKey)
    .then(|_: Request| async { Response::text("secrets") });

let denied = pipeline.run(Request::builder().build()).await;
assert_eq!(denied.status(), StatusCode::UNAUTHORIZED);

let allowed = pipeline.run(Request::builder().header("x-api-key", "secret").build()).await;
assert_eq!(allowed.status(), StatusCode::OK);

§No names anywhere

A route attaches .middleware(Authenticate::new(auth)), not .middleware("auth"). A name-keyed kernel needs the string because a dynamic language has nowhere to put the type; Rust does not, and the indirection costs more than it saves — a misspelled alias is a route that runs unguarded, and only an integration test notices.

The router still does not depend on rainier-auth or rainier-session. It only ever sees dyn Middleware, which is defined here; the application names the concrete type, because the application is the crate that knows it.

The name-based equivalentRainier
a route-middleware alias mapnothing — attach the value
a named group in a mapa function returning a MiddlewareStack
the global listMiddlewareRegistry::global
a throttle spelled as a stringThrottleRequests::per_minute(60)
excluding middleware by name.without_middleware::<Authenticate<User>>()

The one thing a name genuinely bought — middleware that cannot be built until the container is populated — is MiddlewareStack::deferred, which runs a closure when the router compiles.

Re-exports§

pub use builtin::AddHeaders;
pub use builtin::AllowedOrigins;
pub use builtin::ConvertEmptyStringsToNull;
pub use builtin::HandleCors;
pub use builtin::SharedThrottle;
pub use builtin::ThrottleRequests;
pub use builtin::TrimStrings;
pub use compression::Compress;
pub use method_override::MethodOverride;
pub use pipeline::ConcreteMiddleware;
pub use pipeline::Destination;
pub use pipeline::Middleware;
pub use pipeline::Next;
pub use pipeline::Pipeline;
pub use pipeline::ReadyPipeline;
pub use proxy::Cidr;
pub use proxy::TrustProxies;
pub use proxy::Trusted;
pub use rate_limit::Hit;
pub use rate_limit::MemoryRateLimitStore;
pub use rate_limit::RateLimitStore;
pub use registry::MiddlewareRegistry;
pub use stack::IntoMiddlewareStack;
pub use stack::MiddlewareStack;
pub use timeout::Timeout;

Modules§

builtin
The middleware Rainier ships with — what a fresh application’s HTTP kernel expects to find already written.
compression
Compressing responses on the way out — Compress.
method_override
Letting an HTML form spell DELETE — MethodOverride.
pipeline
The request pipeline — Middleware, Next and Pipeline.
proxy
TrustProxies — deciding which client address to believe.
rate_limit
Where a throttle keeps its counters — RateLimitStore.
registry
The global middleware stack — MiddlewareRegistry.
stack
Middleware as values — MiddlewareStack and IntoMiddlewareStack.
timeout
A ceiling on how long a request may take — Timeout.

Attribute Macros§

async_trait