Skip to content

Commit fbdd957

Browse files
committed
feat: configure request body limit
1 parent a163ae7 commit fbdd957

File tree

4 files changed

+73
-11
lines changed

4 files changed

+73
-11
lines changed

rust/server/src/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use tokio::signal::unix::SignalKind;
1717
use hyper::server::conn::http1;
1818
use hyper_util::rt::TokioIo;
1919

20-
use crate::vss_service::VssService;
20+
use crate::vss_service::{VssService, VssServiceConfig};
2121
use api::auth::{Authorizer, NoopAuthorizer};
2222
use api::kv_store::KvStore;
2323
use impls::postgres_store::{Certificate, PostgresPlaintextBackend, PostgresTlsBackend};
@@ -118,7 +118,10 @@ fn main() {
118118
match res {
119119
Ok((stream, _)) => {
120120
let io_stream = TokioIo::new(stream);
121-
let vss_service = VssService::new(Arc::clone(&store), Arc::clone(&authorizer));
121+
let vss_service_config = if let Some(req_body_size) = config.server_config.maximum_request_body_size {
122+
VssServiceConfig::new(req_body_size)
123+
} else {VssServiceConfig::default()};
124+
let vss_service = VssService::new(Arc::clone(&store), Arc::clone(&authorizer), vss_service_config);
122125
runtime.spawn(async move {
123126
if let Err(err) = http1::Builder::new().serve_connection(io_stream, vss_service).await {
124127
eprintln!("Failed to serve connection: {}", err);

rust/server/src/util/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub(crate) struct Config {
1010
pub(crate) struct ServerConfig {
1111
pub(crate) host: String,
1212
pub(crate) port: u16,
13+
pub(crate) maximum_request_body_size: Option<usize>,
1314
}
1415

1516
#[derive(Deserialize)]

rust/server/src/vss_service.rs

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,45 @@ use std::future::Future;
1818
use std::pin::Pin;
1919
use std::sync::Arc;
2020

21-
const MAXIMUM_REQUEST_BODY_SIZE: u16 = 65_535;
21+
const MAXIMUM_REQUEST_BODY_SIZE: usize = 20 * 1024 * 1024;
22+
const DEFAULT_REQUEST_BODY_SIZE: usize = 10 * 1024 * 1024;
23+
24+
#[derive(Clone)]
25+
pub(crate) struct VssServiceConfig {
26+
maximum_request_body_size: usize,
27+
}
28+
29+
impl VssServiceConfig {
30+
pub fn new(maximum_request_body_size: usize) -> Self {
31+
let capped = maximum_request_body_size.min(MAXIMUM_REQUEST_BODY_SIZE);
32+
if capped < maximum_request_body_size {
33+
eprintln!(
34+
"Warning: maximum_request_body_size {} exceeds limit, capped to {}.",
35+
maximum_request_body_size, MAXIMUM_REQUEST_BODY_SIZE
36+
);
37+
}
38+
Self { maximum_request_body_size: capped }
39+
}
40+
}
41+
42+
impl Default for VssServiceConfig {
43+
fn default() -> Self {
44+
Self { maximum_request_body_size: DEFAULT_REQUEST_BODY_SIZE }
45+
}
46+
}
2247

2348
#[derive(Clone)]
2449
pub struct VssService {
2550
store: Arc<dyn KvStore>,
2651
authorizer: Arc<dyn Authorizer>,
52+
config: VssServiceConfig,
2753
}
2854

2955
impl VssService {
30-
pub(crate) fn new(store: Arc<dyn KvStore>, authorizer: Arc<dyn Authorizer>) -> Self {
31-
Self { store, authorizer }
56+
pub(crate) fn new(
57+
store: Arc<dyn KvStore>, authorizer: Arc<dyn Authorizer>, config: VssServiceConfig,
58+
) -> Self {
59+
Self { store, authorizer, config }
3260
}
3361
}
3462

@@ -43,22 +71,51 @@ impl Service<Request<Incoming>> for VssService {
4371
let store = Arc::clone(&self.store);
4472
let authorizer = Arc::clone(&self.authorizer);
4573
let path = req.uri().path().to_owned();
74+
let maximum_request_body_size = self.config.maximum_request_body_size;
4675

4776
Box::pin(async move {
4877
let prefix_stripped_path = path.strip_prefix(BASE_PATH_PREFIX).unwrap_or_default();
4978

5079
match prefix_stripped_path {
5180
"/getObject" => {
52-
handle_request(store, authorizer, req, handle_get_object_request).await
81+
handle_request(
82+
store,
83+
authorizer,
84+
req,
85+
maximum_request_body_size,
86+
handle_get_object_request,
87+
)
88+
.await
5389
},
5490
"/putObjects" => {
55-
handle_request(store, authorizer, req, handle_put_object_request).await
91+
handle_request(
92+
store,
93+
authorizer,
94+
req,
95+
maximum_request_body_size,
96+
handle_put_object_request,
97+
)
98+
.await
5699
},
57100
"/deleteObject" => {
58-
handle_request(store, authorizer, req, handle_delete_object_request).await
101+
handle_request(
102+
store,
103+
authorizer,
104+
req,
105+
maximum_request_body_size,
106+
handle_delete_object_request,
107+
)
108+
.await
59109
},
60110
"/listKeyVersions" => {
61-
handle_request(store, authorizer, req, handle_list_object_request).await
111+
handle_request(
112+
store,
113+
authorizer,
114+
req,
115+
maximum_request_body_size,
116+
handle_list_object_request,
117+
)
118+
.await
62119
},
63120
_ => {
64121
let error_msg = "Invalid request path.".as_bytes();
@@ -99,7 +156,7 @@ async fn handle_request<
99156
Fut: Future<Output = Result<R, VssError>> + Send,
100157
>(
101158
store: Arc<dyn KvStore>, authorizer: Arc<dyn Authorizer>, request: Request<Incoming>,
102-
handler: F,
159+
maximum_request_body_size: usize, handler: F,
103160
) -> Result<<VssService as Service<Request<Incoming>>>::Response, hyper::Error> {
104161
let (parts, body) = request.into_parts();
105162
let headers_map = parts
@@ -113,7 +170,7 @@ async fn handle_request<
113170
Err(e) => return Ok(build_error_response(e)),
114171
};
115172

116-
let limited_body = Limited::new(body, MAXIMUM_REQUEST_BODY_SIZE.into());
173+
let limited_body = Limited::new(body, maximum_request_body_size);
117174
let bytes = match limited_body.collect().await {
118175
Ok(body) => body.to_bytes(),
119176
Err(_) => {

rust/server/vss-server-config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[server_config]
22
host = "127.0.0.1"
33
port = 8080
4+
# maximum_request_body_size = 10485760 # Optional: maximum request body size in bytes capped at 20971520 (20 MB).
45

56
[postgresql_config]
67
username = "postgres" # Optional in TOML, can be overridden by env var `VSS_POSTGRESQL_USERNAME`

0 commit comments

Comments
 (0)