From dd68a419e3539ec8b6779ddc8708e0f03fbd7984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Mon, 6 Apr 2026 20:35:37 +0800 Subject: [PATCH] test(server): cover request context layer propagation (#2398) Co-authored-by: loverustfs --- rustfs/src/server/layer.rs | 62 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/rustfs/src/server/layer.rs b/rustfs/src/server/layer.rs index 13a198141..09f6cf10a 100644 --- a/rustfs/src/server/layer.rs +++ b/rustfs/src/server/layer.rs @@ -678,11 +678,30 @@ where #[cfg(test)] mod tests { use super::*; + use futures::future::{Ready, ready}; use http::Request; use http_body_util::BodyExt; use http_body_util::Full; + use std::convert::Infallible; use temp_env::with_var; + #[derive(Clone, Debug)] + struct CaptureService; + + impl Service> for CaptureService { + type Response = Request; + type Error = Infallible; + type Future = Ready>; + + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, req: Request) -> Self::Future { + ready(Ok(req)) + } + } + #[test] fn admin_chunked_put_without_content_length_is_normalized() { let request = Request::builder() @@ -816,6 +835,49 @@ mod tests { }); } + #[test] + fn request_context_layer_populates_context_and_s3_request_id_from_x_request_id() { + let mut service = RequestContextLayer.layer(CaptureService); + let request = Request::builder() + .uri("/bucket/object") + .header("x-request-id", "req-123") + .body(()) + .expect("request"); + + let request = service.call(request).into_inner().expect("service call should succeed"); + let context = request + .extensions() + .get::() + .expect("request context should be present"); + + assert_eq!(context.request_id, "req-123"); + assert_eq!(context.x_amz_request_id, "req-123"); + assert!(context.trace_id.is_none()); + assert!(context.span_id.is_none()); + assert_eq!(request.headers().get(AMZ_REQUEST_ID).unwrap(), "req-123"); + } + + #[test] + fn request_context_layer_preserves_upstream_s3_request_id() { + let mut service = RequestContextLayer.layer(CaptureService); + let request = Request::builder() + .uri("/bucket/object") + .header("x-request-id", "req-123") + .header(AMZ_REQUEST_ID, "amz-456") + .body(()) + .expect("request"); + + let request = service.call(request).into_inner().expect("service call should succeed"); + let context = request + .extensions() + .get::() + .expect("request context should be present"); + + assert_eq!(context.request_id, "req-123"); + assert_eq!(context.x_amz_request_id, "amz-456"); + assert_eq!(request.headers().get(AMZ_REQUEST_ID).unwrap(), "amz-456"); + } + #[tokio::test] async fn test_resolve_s3_options_cors_headers_no_headers_without_match() { let mut req_headers = HeaderMap::new();