cb8f7c6
commit cb8f7c6
2 files changed
+26 -13
Showing 2 changed files+26-13
▼crates/justapi-core/src/middleware.rs
+18-8
| @@ -8,6 +8,7 @@ use anyhow::Result; | ||
8 | 8 | use async_trait::async_trait; |
9 | 9 | use futures::future::BoxFuture; |
10 | 10 | use governor::clock::Clock; |
11 | +use http::HeaderValue; | |
11 | 12 | use http_body_util::combinators::UnsyncBoxBody; |
12 | 13 | use http_body_util::BodyExt; |
13 | 14 | use hyper::body::{Bytes, Incoming}; |
| @@ -270,9 +271,12 @@ impl<B: Send + 'static> Middleware<B> for Cors { | ||
270 | 271 | let add_vary = !allow_all; |
271 | 272 | |
272 | 273 | if req.method() == Method::OPTIONS { |
274 | + let origin_val: HeaderValue = matched_origin | |
275 | + .parse() | |
276 | + .map_err(|e| anyhow::anyhow!("invalid CORS origin header value: {e}"))?; | |
273 | 277 | let mut builder = Response::builder() |
274 | 278 | .status(StatusCode::NO_CONTENT) |
275 | - .header("access-control-allow-origin", matched_origin) | |
279 | + .header("access-control-allow-origin", origin_val) | |
276 | 280 | .header("access-control-allow-methods", &self.allow_methods) |
277 | 281 | .header("access-control-allow-headers", &self.allow_headers) |
278 | 282 | .header("access-control-max-age", &self.max_age); |
| @@ -298,18 +302,24 @@ impl<B: Send + 'static> Middleware<B> for Cors { | ||
298 | 302 | } |
299 | 303 | |
300 | 304 | let mut resp = next.run(req).await?; |
301 | - resp.headers_mut().insert("access-control-allow-origin", matched_origin.parse().unwrap()); | |
305 | + let origin_val: HeaderValue = matched_origin | |
306 | + .parse() | |
307 | + .map_err(|e| anyhow::anyhow!("invalid CORS origin header value: {e}"))?; | |
308 | + resp.headers_mut().insert("access-control-allow-origin", origin_val); | |
302 | 309 | if self.allow_credentials { |
303 | - resp.headers_mut().insert("access-control-allow-credentials", "true".parse().unwrap()); | |
310 | + resp.headers_mut() | |
311 | + .insert("access-control-allow-credentials", HeaderValue::from_static("true")); | |
304 | 312 | } |
305 | 313 | if !self.expose_headers.is_empty() { |
306 | - resp.headers_mut().insert( | |
307 | - "access-control-expose-headers", | |
308 | - self.expose_headers.join(", ").parse().unwrap(), | |
309 | - ); | |
314 | + let val: HeaderValue = self | |
315 | + .expose_headers | |
316 | + .join(", ") | |
317 | + .parse() | |
318 | + .map_err(|e| anyhow::anyhow!("invalid CORS expose-headers value: {e}"))?; | |
319 | + resp.headers_mut().insert("access-control-expose-headers", val); | |
310 | 320 | } |
311 | 321 | if add_vary { |
312 | - resp.headers_mut().insert("vary", "Origin".parse().unwrap()); | |
322 | + resp.headers_mut().insert("vary", HeaderValue::from_static("Origin")); | |
313 | 323 | } |
314 | 324 | Ok(resp) |
315 | 325 | } |
316 | 326 | |
▼crates/justapi-core/src/server/mod.rs
+8-5
| @@ -1297,7 +1297,10 @@ async fn serve_connection( | ||
1297 | 1297 | // Bound concurrent connections: a permit is held for the life of |
1298 | 1298 | // the connection so a flood of accepts can't exhaust FDs/memory |
1299 | 1299 | // (connection-flood / slowloris resource exhaustion). |
1300 | - let _permit = conn_semaphore.acquire_owned().await.expect("connection semaphore closed"); | |
1300 | + let Ok(_permit) = conn_semaphore.acquire_owned().await else { | |
1301 | + tracing::warn!("connection semaphore closed, dropping connection"); | |
1302 | + return; | |
1303 | + }; | |
1301 | 1304 | let io = TokioIo::new(stream); |
1302 | 1305 | let token_clone = shutdown.clone(); |
1303 | 1306 | let spawn_metrics = metrics.clone(); |
| @@ -1987,10 +1990,10 @@ async fn serve_with_tls( | ||
1987 | 1990 | let conn_semaphore = conn_semaphore.clone(); |
1988 | 1991 | connections.spawn(async move { |
1989 | 1992 | // Bound concurrent connections (see serve_http for rationale). |
1990 | - let _permit = conn_semaphore | |
1991 | - .acquire_owned() | |
1992 | - .await | |
1993 | - .expect("connection semaphore closed"); | |
1993 | + let Ok(_permit) = conn_semaphore.acquire_owned().await else { | |
1994 | + tracing::warn!("TLS connection semaphore closed, dropping connection"); | |
1995 | + return; | |
1996 | + }; | |
1994 | 1997 | match acceptor.accept(stream).await { |
1995 | 1998 | Ok(tls_stream) => { |
1996 | 1999 | let io = TokioIo::new(tls_stream); |
1997 | 2000 | |