servers/http/memory_limit.rs
1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Middleware for limiting total memory usage of concurrent HTTP request bodies.
16
17use axum::extract::{Request, State};
18use axum::middleware::Next;
19use axum::response::{IntoResponse, Response};
20use http::StatusCode;
21
22use crate::request_memory_limiter::ServerMemoryLimiter;
23
24pub async fn memory_limit_middleware(
25 State(limiter): State<ServerMemoryLimiter>,
26 req: Request,
27 next: Next,
28) -> Response {
29 let content_length = req
30 .headers()
31 .get(http::header::CONTENT_LENGTH)
32 .and_then(|v| v.to_str().ok())
33 .and_then(|v| v.parse::<u64>().ok())
34 .unwrap_or(0);
35
36 let _guard = match limiter.acquire(content_length).await {
37 Ok(guard) => guard,
38 Err(e) => {
39 return (
40 StatusCode::TOO_MANY_REQUESTS,
41 format!("Request body memory limit exceeded: {}", e),
42 )
43 .into_response();
44 }
45 };
46
47 next.run(req).await
48}