use crate::logging::CorrelationContext;
use crate::response::ErrorResult;
use futures::FutureExt;
pub fn rate_limiter(
limiter: std::sync::Arc<dyn crate::middleware::rate::RateLimiter>,
limit: u32,
) -> crate::controller::Middleware {
std::sync::Arc::new(move |ctx: &mut CorrelationContext| {
let headers = ctx.headers();
let cloned = limiter.clone();
async move {
let key = ctx.user_id().unwrap_or_else(|| {
headers
.get("x-forwarded-for")
.and_then(|v| v.to_str().ok())
.unwrap_or("anonymous")
.to_string()
}) + ":"
+ &base64::Engine::encode(&base64::engine::general_purpose::STANDARD, "path");
if !cloned.is_allowed(&key, limit).await {
return Err(ErrorResult::new("Too many requests", None, 429));
}
Ok(())
}
.boxed()
})
}