Skip to content

Commit ed424bb

Browse files
committed
feat(server): Implement throughput rate limits
1 parent 97d5e91 commit ed424bb

File tree

7 files changed

+323
-1
lines changed

7 files changed

+323
-1
lines changed

Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objectstore-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ tower-http = { version = "0.6.6", default-features = false, features = [
5252
tracing = { workspace = true }
5353
tracing-subscriber = { workspace = true }
5454
uuid = { workspace = true, features = ["v7"] }
55+
papaya = "0.2.3"
5556

5657
[dev-dependencies]
5758
nix = { version = "0.30.1", features = ["signal"] }

objectstore-server/src/config.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use serde::{Deserialize, Serialize};
4646
use tracing::level_filters::LevelFilter;
4747

4848
use crate::killswitches::Killswitches;
49+
use crate::rate_limits::RateLimits;
4950

5051
/// Environment variable prefix for all configuration options.
5152
const ENV_PREFIX: &str = "OS__";
@@ -870,6 +871,9 @@ pub struct Config {
870871

871872
/// A list of matchers for requests to discard without processing.
872873
pub killswitches: Killswitches,
874+
875+
/// Definitions for rate limits to enforce on incoming requests.
876+
pub rate_limits: RateLimits,
873877
}
874878

875879
impl Default for Config {
@@ -890,6 +894,7 @@ impl Default for Config {
890894
metrics: Metrics::default(),
891895
auth: AuthZ::default(),
892896
killswitches: Killswitches::default(),
897+
rate_limits: RateLimits::default(),
893898
}
894899
}
895900
}

objectstore-server/src/extractors/id.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::state::ServiceState;
1515
pub enum ObjectRejection {
1616
Path(PathRejection),
1717
Killswitched,
18+
RateLimited,
1819
}
1920

2021
impl IntoResponse for ObjectRejection {
@@ -26,6 +27,11 @@ impl IntoResponse for ObjectRejection {
2627
"Object access is disabled for this scope through killswitches",
2728
)
2829
.into_response(),
30+
ObjectRejection::RateLimited => (
31+
axum::http::StatusCode::TOO_MANY_REQUESTS,
32+
"Object access is rate limited",
33+
)
34+
.into_response(),
2935
}
3036
}
3137
}
@@ -53,6 +59,10 @@ impl FromRequestParts<ServiceState> for Xt<ObjectId> {
5359
return Err(ObjectRejection::Killswitched);
5460
}
5561

62+
if !state.rate_limiter.check(id.context()) {
63+
return Err(ObjectRejection::RateLimited);
64+
}
65+
5666
Ok(Xt(id))
5767
}
5868
}
@@ -114,6 +124,10 @@ impl FromRequestParts<ServiceState> for Xt<ObjectContext> {
114124
return Err(ObjectRejection::Killswitched);
115125
}
116126

127+
if !state.rate_limiter.check(&context) {
128+
return Err(ObjectRejection::RateLimited);
129+
}
130+
117131
Ok(Xt(context))
118132
}
119133
}

objectstore-server/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ pub mod extractors;
1111
pub mod healthcheck;
1212
pub mod killswitches;
1313
pub mod observability;
14+
pub mod rate_limits;
1415
pub mod state;
1516
pub mod web;

0 commit comments

Comments
 (0)