thruster-rate-limit

A super simple rate limiting middleware for the thruster web framework.

Currently supports only the hyper backend of thruster, basically hyper_server feature must be enabled!

Table of Contents

Simple example

```rust struct ServerState { rate_limiter: RateLimiter, }

[context_state]

struct RequestState(RateLimiter, Box); type Ctx = TypedHyperContext;

struct RateLimiterConf; impl Configuration for RateLimiterConf {}

[middleware_fn]

async fn root(mut context: Ctx, next: MiddlewareNext) -> MiddlewareResult { context.body(BODYSTR); return Ok(context); }

fn generatecontext(request: HyperRequest, state: &ServerState, _path: &str) -> Ctx { return Ctx::new( request, RequestState(state.ratelimiter.clone(), Box::new(RateLimiterConf)), ); }

[tokio::test]

async fn helloworld() { let ratelimiter = RateLimiter::default();

let app = create_app(ServerState { rate_limiter })
    .get(ROUTE, m![root])
    .commit();

let response = Testable::get(&app, ROUTE, vec![])
    .await
    .unwrap()
    .expect_status(200, "OK");

assert_eq!(response.body_string(), BODY_STR);

} ```

Options

```rust

[derive(Clone)]

pub struct Options { pub max: usize, pub per_s: usize, }

[derive(Clone)]

pub struct RateLimiter { pub options: Options, pub routes: Vec<(String, Options)>, pub store: S, } ```

Configuration

This is currently pretty basic, but you can extend the functionality of the rate limiter based on your needs by implementing the Configuration trait

```rust pub trait Configuration { fn shouldlimit(&self, _context: &TypedHyperContext) -> bool { return true; } fn getkey(&self, context: &TypedHyperContext) -> String { if let Some(request) = context.hyperrequest.asref() { if let Some(ip) = request.ip { return ip.to_string(); } }

    return "".to_string();
}

} ```

Stores

Simple in-memory store: ```rust

[derive(Clone)]

pub struct MapStore { hash_map: Arc>>, } ```

[needs redis_store feature] Redis store: ```rust

[derive(Clone)]

pub struct RedisStore { connection_manager: ConnectionManager, } ```

Different routes, different settings

Simply put, this is useful when, for example, for a login route you want to have only 5 requests per minute.

rust let rate_limiter = RateLimiter::new(Options::new(1, 100), MapStore::new()) .override_routes(vec![ // Options::new(max, per_s) ("/user/login".to_string(), Options::new(5, 60)), // limit some expensive route for example, reset every 2 minutes ("/user/:id/calculate".to_string(), Options::new(20, 60 * 2)), ]);