fix: resolve concurrency hardening lint failures

Use typed connection admission errors, group HTTP limits, and make test lock lifetimes explicit. Handle fixture reads and remove unnecessary cloning and manual divisibility checks.
This commit is contained in:
elky
2026-09-10 08:31:47 +08:00
parent 3a8dadcd6b
commit 6aeadcd1d7
8 changed files with 82 additions and 67 deletions
@@ -1242,7 +1242,7 @@ mod tests {
let server = tokio::spawn(async move {
let (mut socket, _) = listener.accept().await.unwrap();
let mut request = [0_u8; 4096];
socket.read(&mut request).await.unwrap();
assert!(socket.read(&mut request).await.unwrap() > 0);
let response = if content_type == "application/json" {
format!("HTTP/1.1 200 OK\r\ncontent-type: {content_type}\r\ncontent-length: 1024\r\n\r\n{first_chunk}")
} else {
+33 -29
View File
@@ -1879,39 +1879,38 @@ fn gateway_listeners(
Ok(listeners)
}
async fn serve_gateway_router(
listeners: Vec<tokio::net::TcpListener>,
router: axum::Router,
connection_budget: Arc<HttpConnectionBudget>,
#[derive(Clone, Copy)]
struct GatewayHttpLimits {
http2_max_concurrent_streams: u32,
http_header_read_timeout_ms: u64,
http_header_max_bytes: usize,
http_max_headers: usize,
}
async fn serve_gateway_router(
listeners: Vec<tokio::net::TcpListener>,
router: axum::Router,
connection_budget: Arc<HttpConnectionBudget>,
limits: GatewayHttpLimits,
shutdown: CancellationToken,
) -> Result<(), Box<dyn std::error::Error>> {
let http2_max_concurrent_streams =
gateway_http2_max_concurrent_streams(http2_max_concurrent_streams);
let http_header_read_timeout_ms =
gateway_http_header_read_timeout_ms(http_header_read_timeout_ms);
let http_header_max_bytes = gateway_http_header_max_bytes(http_header_max_bytes);
let http_max_headers = gateway_http_max_headers(http_max_headers);
let limits = GatewayHttpLimits {
http2_max_concurrent_streams: gateway_http2_max_concurrent_streams(
limits.http2_max_concurrent_streams,
),
http_header_read_timeout_ms: gateway_http_header_read_timeout_ms(
limits.http_header_read_timeout_ms,
),
http_header_max_bytes: gateway_http_header_max_bytes(limits.http_header_max_bytes),
http_max_headers: gateway_http_max_headers(limits.http_max_headers),
};
let mut servers = tokio::task::JoinSet::new();
for listener in listeners {
let router = router.clone();
let connection_budget = Arc::clone(&connection_budget);
let shutdown = shutdown.clone();
servers.spawn(async move {
serve_gateway_listener(
listener,
router,
connection_budget,
http2_max_concurrent_streams,
http_header_read_timeout_ms,
http_header_max_bytes,
http_max_headers,
shutdown,
)
.await
serve_gateway_listener(listener, router, connection_budget, limits, shutdown).await
});
}
let mut failure = None;
@@ -1941,12 +1940,15 @@ async fn serve_gateway_listener(
listener: tokio::net::TcpListener,
router: axum::Router,
connection_budget: Arc<HttpConnectionBudget>,
http2_max_concurrent_streams: u32,
http_header_read_timeout_ms: u64,
http_header_max_bytes: usize,
http_max_headers: usize,
limits: GatewayHttpLimits,
shutdown: CancellationToken,
) -> Result<(), std::io::Error> {
let GatewayHttpLimits {
http2_max_concurrent_streams,
http_header_read_timeout_ms,
http_header_max_bytes,
http_max_headers,
} = limits;
let mut make_service = router.into_make_service_with_connect_info::<std::net::SocketAddr>();
let mut connections = tokio::task::JoinSet::new();
loop {
@@ -2594,10 +2596,12 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
listeners,
router,
Arc::clone(&http_connection_budget),
args.http2_max_concurrent_streams,
args.http_header_read_timeout_ms,
args.http_header_max_bytes,
args.http_max_headers,
GatewayHttpLimits {
http2_max_concurrent_streams: args.http2_max_concurrent_streams,
http_header_read_timeout_ms: args.http_header_read_timeout_ms,
http_header_max_bytes: args.http_header_max_bytes,
http_max_headers: args.http_max_headers,
},
shutdown.clone(),
);
tokio::pin!(server);
+7 -5
View File
@@ -7,7 +7,7 @@ use tokio::net::{TcpListener, TcpStream};
use tokio::sync::Notify;
use tokio_util::sync::CancellationToken;
use super::super::{serve_gateway_router, HttpConnectionBudget};
use super::super::{serve_gateway_router, GatewayHttpLimits, HttpConnectionBudget};
async fn start(
router: Router,
@@ -28,10 +28,12 @@ async fn start(
vec![listener],
router,
shared,
16,
10_000,
32_768,
100,
GatewayHttpLimits {
http2_max_concurrent_streams: 16,
http_header_read_timeout_ms: 10_000,
http_header_max_bytes: 32_768,
http_max_headers: 100,
},
stop,
)
.await