diff --git a/.changelog/1757207291.md b/.changelog/1757207291.md new file mode 100644 index 00000000000..3ddc103e899 --- /dev/null +++ b/.changelog/1757207291.md @@ -0,0 +1,10 @@ +--- +applies_to: [server] +authors: [drganjoo] +references: [] +breaking: false +new_feature: false +bug_fix: true +--- +Fixed URI path matching for H2 protocol in the ALB health check layer to ensure explicit path comparison. + diff --git a/rust-runtime/aws-smithy-http-server/Cargo.toml b/rust-runtime/aws-smithy-http-server/Cargo.toml index 76d5051bfcd..507835428c9 100644 --- a/rust-runtime/aws-smithy-http-server/Cargo.toml +++ b/rust-runtime/aws-smithy-http-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http-server" -version = "0.65.5" +version = "0.65.6" authors = ["Smithy Rust Server "] edition = "2021" license = "Apache-2.0" diff --git a/rust-runtime/aws-smithy-http-server/src/layer/alb_health_check.rs b/rust-runtime/aws-smithy-http-server/src/layer/alb_health_check.rs index 8c76bf1a9f3..656f511d726 100644 --- a/rust-runtime/aws-smithy-http-server/src/layer/alb_health_check.rs +++ b/rust-runtime/aws-smithy-http-server/src/layer/alb_health_check.rs @@ -108,7 +108,7 @@ where } fn call(&mut self, req: Request) -> Self::Future { - if req.uri() == self.layer.health_check_uri.as_ref() { + if req.uri().path() == self.layer.health_check_uri.as_ref() { let clone = self.layer.health_check_handler.clone(); let service = std::mem::replace(&mut self.layer.health_check_handler, clone); let handler_future = service.oneshot(req); @@ -179,3 +179,39 @@ where } } } + +#[cfg(test)] +mod tests { + use super::*; + use http::Uri; + use tower::{service_fn, ServiceExt}; + + #[tokio::test] + async fn health_check_matches_path_when_uri_contains_scheme_authority_and_path() { + let uri: Uri = "https://example.com/ping".parse().unwrap(); + ensure_health_check_path_matches(uri, "/ping".to_string()).await; + } + + #[tokio::test] + async fn health_check_matches_path_when_uri_contains_only_path() { + let uri: Uri = "/ping".parse().unwrap(); + ensure_health_check_path_matches(uri, "/ping".to_string()).await; + } + + async fn ensure_health_check_path_matches(uri: Uri, health_check_path: String) { + let layer = AlbHealthCheckLayer::from_handler(health_check_path, |_req| async { StatusCode::OK }); + let inner_service = service_fn(|_req| async { + Ok::<_, std::convert::Infallible>( + Response::builder() + .status(StatusCode::IM_A_TEAPOT) + .body(crate::body::empty()) + .expect("infallible"), + ) + }); + + let service = layer.layer(inner_service); + let request = Request::builder().uri(uri).body(Body::empty()).unwrap(); + let response = service.oneshot(request).await.unwrap(); + assert_eq!(response.status(), StatusCode::OK); + } +}