4个版本 (2个稳定版)
1.0.1 | 2023年5月30日 |
---|---|
0.1.1 | 2023年5月29日 |
0.1.0 | 2023年5月29日 |
#2044 在 Web编程
每月 37次下载
18KB
232 行
thruster-rate-limit
为thruster Web框架提供的超简单速率限制中间件。
目前仅支持thruster的hyper后端,基本上必须启用hyper_server
功能!
目录
简单示例
struct ServerState {
rate_limiter: RateLimiter<MapStore>,
}
#[context_state]
struct RequestState(RateLimiter<MapStore>, Box<RateLimiterConf>);
type Ctx = TypedHyperContext<RequestState>;
struct RateLimiterConf;
impl Configuration<RequestState> for RateLimiterConf {}
#[middleware_fn]
async fn root(mut context: Ctx, _next: MiddlewareNext<Ctx>) -> MiddlewareResult<Ctx> {
context.body(BODY_STR);
return Ok(context);
}
fn generate_context(request: HyperRequest, state: &ServerState, _path: &str) -> Ctx {
return Ctx::new(
request,
RequestState(state.rate_limiter.clone(), Box::new(RateLimiterConf)),
);
}
#[tokio::test]
async fn hello_world() {
let rate_limiter = RateLimiter::default();
let app = App::<HyperRequest, Ctx, ServerState>::create(
generate_context,
ServerState { rate_limiter },
)
.middleware("/", m![rate_limit_middleware])
.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);
}
选项
#[derive(Clone)]
pub struct Options {
pub max: usize,
pub per_s: usize,
}
#[derive(Clone)]
pub struct RateLimiter<S: Store + Clone> {
pub options: Options,
pub routes: Vec<(String, Options)>,
pub store: S,
}
routes
:将不同选项应用于不同路由 更多信息max
:允许的最大请求数量per_s
per_s
:何时重置max
store
:任何实现Store
特质的对象,库提供了2个存储
配置
目前功能相对基础,但您可以通过实现Configuration
特质来根据需求扩展速率限制器的功能
pub trait Configuration<S: Send> {
fn should_limit(&self, _context: &TypedHyperContext<S>) -> bool {
return true;
}
fn get_key(&self, context: &TypedHyperContext<S>) -> String {
if let Some(request) = context.hyper_request.as_ref() {
if let Some(ip) = request.ip {
return ip.to_string();
}
}
return "".to_string();
}
}
存储
简单的内存存储
#[derive(Clone)]
pub struct MapStore {
hash_map: Arc<Mutex<HashMap<String, MapValue>>>,
}
[需要redis_store
功能] Redis存储
#[derive(Clone)]
pub struct RedisStore {
connection_manager: ConnectionManager,
}
不同路由,不同设置
简单来说,这在例如,对于登录路由只想每分钟有5个请求时很有用。
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)),
]);
依赖
~10–20MB
~282K SLoC