Rate Limit

Per-IP request limiting with sliding window.

● ● ●
use runique::prelude::*;

pub fn routes() -> Router {
    urlpatterns! {
        // other routes...
    }
    // .rate_limit(path, name, view!, max_requests, retry_after_secs, methods)
    .rate_limit(
        "/upload-image",
        "upload_image",
        view!(upload_handler),
        5,
        60,
        vec![Method::POST],   // only POST counts; vec![] = every method
    )
}
// 5 requests per minute, every method
.rate_limit("/login", "login", view!(login_handler), 5, 60, vec![])

// 3 submissions per 5 minutes — GET stays free
.rate_limit("/register", "register", view!(register_handler), 3, 300, vec![Method::POST])

// Several routes sharing one limiter
.rate_limit_many(100, 60, vec![], vec![
    ("/api/a".into(), "api_a".into(), view!(api_a)),
    ("/api/b".into(), "api_b".into(), view!(api_b)),
])
// 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.
// .rate_limit() is not a global middleware: it wraps its own
// routes only (route layer), after the global middlewares.

Extensions(0)
  -> Compression(5)
  -> ErrorHandler(10)
  -> HostValidation(15)
  -> HttpsRedirect(17)
  -> Custom(20+)
  -> CSP / headers(30)
  -> Cache(40)
  -> Session(50)
  -> CSRF(60)
  -> RateLimiter      // here, on the limited routes only
  -> handler