Rate Limit

Per-IP request limiting with sliding window.

● ● ●
use runique::macros::routeur::register_url::register_pending;
use runique::prelude::*;
use std::sync::Arc;

pub fn routes() -> Router {
    let limiter = Arc::new(
        RateLimiter::new()
            .max_requests(5)
            .retry_after(60),
    );

    // register_pending is required for {% link ''route_name'' %}
    // to work in Tera templates.
    register_pending("upload_image", "/upload-image");

    let upload_route = Router::new()
        .route("/upload-image", view!(upload_handler))
        .route_layer(middleware::from_fn_with_state(limiter, rate_limit_middleware));

    urlpatterns! {
        // other routes...
    }.merge(upload_route)
}
// 5 requests per minute
RateLimiter::new().max_requests(5).retry_after(60)

// 3 requests per 5 minutes
RateLimiter::new().max_requests(3).retry_after(300)

// 100 requests per minute (default: 60/60)
RateLimiter::new().max_requests(100).retry_after(60)
// Sliding window per IP address.
// Counter reset after retry_after seconds.

// Response when the limit is exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 42

// The Retry-After header indicates
// the delay before the next window.
// Custom middlewares are inserted at slot 20+.
// They execute BEFORE session and CSRF.

Extensions(0)
  -> ErrorHandler(10)
  -> RateLimiter(20)   // here
  -> Cache(40)
  -> Session(50)
  -> CSRF(60)
  -> routes