1
0
Fork 0
mirror of https://gitlab.com/famedly/conduit.git synced 2025-06-27 16:35:59 +00:00

allow for different timeframes for configuration

This commit is contained in:
Matthias Ahouansou 2024-06-26 13:36:04 +01:00
parent bdf12c2bbd
commit 024f910bf9
No known key found for this signature in database
3 changed files with 32 additions and 7 deletions

View file

@ -20,7 +20,10 @@ use axum_extra::{
use bytes::{BufMut, BytesMut};
use http::{Request, StatusCode};
use ruma::{
api::{client::error::ErrorKind, AuthScheme, IncomingRequest, OutgoingResponse},
api::{
client::error::{ErrorKind, RetryAfter},
AuthScheme, IncomingRequest, OutgoingResponse,
},
server_util::authorization::XMatrix,
CanonicalJsonValue, MilliSecondsSinceUnixEpoch, OwnedDeviceId, OwnedUserId, UserId,
};
@ -357,14 +360,16 @@ where
}
};
if let Err(retry_after_ms) = {
if let Err(retry_after) = {
services()
.rate_limiting
.update_or_reject(target, metadata)
.map_err(Some)
} {
return Err(Error::BadRequest(
ErrorKind::LimitExceeded { retry_after_ms },
ErrorKind::LimitExceeded {
retry_after: retry_after.map(|dur| RetryAfter::Delay(dur)),
},
"Rate limit exceeded.",
));
}

View file

@ -115,10 +115,30 @@ pub enum Restriction {
CatchAll,
}
#[derive(Deserialize, Clone, Copy, Debug)]
#[serde(rename_all = "snake_case")]
pub enum Timeframe {
PerSecond(NonZeroU64),
PerMinute(NonZeroU64),
PerHour(NonZeroU64),
PerDay(NonZeroU64),
}
impl Timeframe {
pub fn nano_gap(&self) -> u64 {
match self {
Timeframe::PerSecond(t) => 1000 * 1000 * 1000 / t.get(),
Timeframe::PerMinute(t) => 1000 * 1000 * 1000 * 60 / t.get(),
Timeframe::PerHour(t) => 1000 * 1000 * 1000 * 60 * 60 / t.get(),
Timeframe::PerDay(t) => 1000 * 1000 * 1000 * 60 * 60 * 24 / t.get(),
}
}
}
#[derive(Clone, Copy, Debug, Deserialize)]
pub struct Limitation {
#[serde(default = "default_non_zero")]
pub per_minute: NonZeroU64,
#[serde(default = "default_non_zero", flatten)]
pub timeframe: Timeframe,
#[serde(default = "default_non_zero")]
pub burst_capacity: NonZeroU64,
#[serde(default = "default_non_zero")]
@ -340,7 +360,7 @@ pub fn default_rate_limit() -> BTreeMap<Restriction, Limitation> {
BTreeMap::from_iter([(
Restriction::default(),
Limitation {
per_minute: default_non_zero(),
timeframe: Timeframe::PerMinute(default_non_zero()),
burst_capacity: default_non_zero(),
weight: default_non_zero(),
},

View file

@ -78,7 +78,7 @@ impl Service {
tracing::info!(?limit);
let increment = 1_000_000_000u64 / limit.per_minute.get() * limit.weight.get();
let increment = 1_000_000_000u64 / limit.timeframe.nano_gap() * limit.weight.get();
tracing::info!(?increment);
let mut prev_expectation = self