servers/http/
memory_limit.rs1use axum::extract::{Request, State};
18use axum::middleware::Next;
19use axum::response::{IntoResponse, Response};
20use http::StatusCode;
21
22use crate::metrics::{METRIC_HTTP_MEMORY_USAGE_BYTES, METRIC_HTTP_REQUESTS_REJECTED_TOTAL};
23use crate::request_limiter::RequestMemoryLimiter;
24
25pub async fn memory_limit_middleware(
26 State(limiter): State<RequestMemoryLimiter>,
27 req: Request,
28 next: Next,
29) -> Response {
30 let content_length = req
31 .headers()
32 .get(http::header::CONTENT_LENGTH)
33 .and_then(|v| v.to_str().ok())
34 .and_then(|v| v.parse::<usize>().ok())
35 .unwrap_or(0);
36
37 let _guard = match limiter.try_acquire(content_length) {
38 Ok(guard) => guard.inspect(|g| {
39 METRIC_HTTP_MEMORY_USAGE_BYTES.set(g.current_usage() as i64);
40 }),
41 Err(e) => {
42 METRIC_HTTP_REQUESTS_REJECTED_TOTAL.inc();
43 return (
44 StatusCode::TOO_MANY_REQUESTS,
45 format!("Request body memory limit exceeded: {}", e),
46 )
47 .into_response();
48 }
49 };
50
51 next.run(req).await
52}