Skip to content

Commit c492604

Browse files
committed
feat: configure request body limit
1 parent 9ff4069 commit c492604

File tree

4 files changed

+84
-19
lines changed

4 files changed

+84
-19
lines changed

rust/server/src/main.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use api::kv_store::KvStore;
2323
use auth_impls::JWTAuthorizer;
2424
use impls::postgres_store::{Certificate, PostgresPlaintextBackend, PostgresTlsBackend};
2525
use util::config::{Config, ServerConfig};
26-
use vss_service::VssService;
26+
use vss_service::{VssService, VssServiceConfig};
2727

2828
mod util;
2929
mod vss_service;
@@ -35,14 +35,17 @@ fn main() {
3535
std::process::exit(1);
3636
}
3737

38-
let Config { server_config: ServerConfig { host, port }, jwt_auth_config, postgresql_config } =
39-
match util::config::load_config(&args[1]) {
40-
Ok(cfg) => cfg,
41-
Err(e) => {
42-
eprintln!("Failed to load configuration: {}", e);
43-
std::process::exit(1);
44-
},
45-
};
38+
let Config {
39+
server_config: ServerConfig { host, port, maximum_request_body_size },
40+
jwt_auth_config,
41+
postgresql_config,
42+
} = match util::config::load_config(&args[1]) {
43+
Ok(cfg) => cfg,
44+
Err(e) => {
45+
eprintln!("Failed to load configuration: {}", e);
46+
std::process::exit(1);
47+
},
48+
};
4649
let addr: SocketAddr = match format!("{}:{}", host, port).parse() {
4750
Ok(addr) => addr,
4851
Err(e) => {
@@ -144,7 +147,10 @@ fn main() {
144147
match res {
145148
Ok((stream, _)) => {
146149
let io_stream = TokioIo::new(stream);
147-
let vss_service = VssService::new(Arc::clone(&store), Arc::clone(&authorizer));
150+
let vss_service_config = if let Some(req_body_size) = maximum_request_body_size {
151+
VssServiceConfig::new(req_body_size)
152+
} else {VssServiceConfig::default()};
153+
let vss_service = VssService::new(Arc::clone(&store), Arc::clone(&authorizer), vss_service_config);
148154
runtime.spawn(async move {
149155
if let Err(err) = http1::Builder::new().serve_connection(io_stream, vss_service).await {
150156
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
@@ -11,6 +11,7 @@ pub(crate) struct Config {
1111
pub(crate) struct ServerConfig {
1212
pub(crate) host: String,
1313
pub(crate) port: u16,
14+
pub(crate) maximum_request_body_size: Option<usize>,
1415
}
1516

1617
#[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
# Uncomment the table below to verify JWT tokens in the HTTP Authorization header against the given RSA public key,
67
# can be overridden by env var `VSS_JWT_RSA_PEM`

0 commit comments

Comments
 (0)