mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-31 09:18:28 +00:00
fix(server): preserve non-S3 trace context (#5450)
This commit is contained in:
@@ -254,7 +254,7 @@ where
|
|||||||
req.headers_mut().insert(REQUEST_ID_HEADER, request_id);
|
req.headers_mut().insert(REQUEST_ID_HEADER, request_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RequestContext::from_headers_without_trace_context(req.headers())
|
RequestContext::from_propagated_headers(req.headers())
|
||||||
};
|
};
|
||||||
let request_id = if is_s3 {
|
let request_id = if is_s3 {
|
||||||
HeaderValue::from_str(&request_context.request_id).ok()
|
HeaderValue::from_str(&request_context.request_id).ok()
|
||||||
@@ -2369,6 +2369,39 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn non_s3_request_context_preserves_propagated_trace_context() {
|
||||||
|
global::set_text_map_propagator(TraceContextPropagator::new());
|
||||||
|
let capture = HeaderCaptureService::default();
|
||||||
|
let captured_context = capture.request_context();
|
||||||
|
let mut service = ExternalRequestContextLayer::default().layer(capture);
|
||||||
|
let request = Request::builder()
|
||||||
|
.uri("/rustfs/admin/v3/info")
|
||||||
|
.header(REQUEST_ID_HEADER, "client-request-id")
|
||||||
|
.header("traceparent", "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")
|
||||||
|
.body(())
|
||||||
|
.expect("build admin request");
|
||||||
|
|
||||||
|
let response = service.call(request).await.expect("admin response");
|
||||||
|
let context = captured_context
|
||||||
|
.lock()
|
||||||
|
.expect("captured request context")
|
||||||
|
.clone()
|
||||||
|
.expect("admin request context");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
response
|
||||||
|
.headers()
|
||||||
|
.get(REQUEST_ID_HEADER)
|
||||||
|
.and_then(|value| value.to_str().ok()),
|
||||||
|
Some("client-request-id")
|
||||||
|
);
|
||||||
|
assert_eq!(context.request_id, "client-request-id");
|
||||||
|
assert_eq!(context.x_amz_request_id, "client-request-id");
|
||||||
|
assert_eq!(context.trace_id.as_deref(), Some("4bf92f3577b34da6a3ce929d0e0e4736"));
|
||||||
|
assert_eq!(context.span_id.as_deref(), Some("00f067aa0ba902b7"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn console_redirect_request_id_contract_follows_redirect_enablement() {
|
fn console_redirect_request_id_contract_follows_redirect_enablement() {
|
||||||
for path in ["/", "/rustfs", "/index.html"] {
|
for path in ["/", "/rustfs", "/index.html"] {
|
||||||
|
|||||||
@@ -100,15 +100,18 @@ impl RequestContext {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a context from propagated request headers without copying trace
|
/// Create a context for a non-S3 request while mirroring the propagated
|
||||||
/// state into the request context.
|
/// canonical request ID into the compatibility alias.
|
||||||
pub(crate) fn from_headers_without_trace_context(headers: &HeaderMap) -> Self {
|
pub(crate) fn from_propagated_headers(headers: &HeaderMap) -> Self {
|
||||||
let request_id = extract_request_id_from_headers(headers);
|
let request_id = extract_request_id_from_headers(headers);
|
||||||
|
let (trace_id, span_id) = extract_trace_context_ids_from_headers(headers)
|
||||||
|
.map(|(trace_id, span_id)| (Some(trace_id), Some(span_id)))
|
||||||
|
.unwrap_or((None, None));
|
||||||
Self {
|
Self {
|
||||||
x_amz_request_id: request_id.clone(),
|
x_amz_request_id: request_id.clone(),
|
||||||
request_id,
|
request_id,
|
||||||
trace_id: None,
|
trace_id,
|
||||||
span_id: None,
|
span_id,
|
||||||
start_time: Instant::now(),
|
start_time: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,17 +332,22 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_propagated_request_context_mirrors_canonical_request_id() {
|
fn test_propagated_request_context_mirrors_canonical_id_and_preserves_trace_context() {
|
||||||
|
global::set_text_map_propagator(TraceContextPropagator::new());
|
||||||
let mut headers = HeaderMap::new();
|
let mut headers = HeaderMap::new();
|
||||||
headers.insert("x-request-id", HeaderValue::from_static("canonical-request-id"));
|
headers.insert("x-request-id", HeaderValue::from_static("canonical-request-id"));
|
||||||
headers.insert("x-amz-request-id", HeaderValue::from_static("untrusted-amz-request-id"));
|
headers.insert("x-amz-request-id", HeaderValue::from_static("untrusted-amz-request-id"));
|
||||||
|
headers.insert(
|
||||||
|
"traceparent",
|
||||||
|
HeaderValue::from_static("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"),
|
||||||
|
);
|
||||||
|
|
||||||
let ctx = RequestContext::from_headers_without_trace_context(&headers);
|
let ctx = RequestContext::from_propagated_headers(&headers);
|
||||||
|
|
||||||
assert_eq!(ctx.request_id, "canonical-request-id");
|
assert_eq!(ctx.request_id, "canonical-request-id");
|
||||||
assert_eq!(ctx.x_amz_request_id, "canonical-request-id");
|
assert_eq!(ctx.x_amz_request_id, "canonical-request-id");
|
||||||
assert!(ctx.trace_id.is_none());
|
assert_eq!(ctx.trace_id.as_deref(), Some("4bf92f3577b34da6a3ce929d0e0e4736"));
|
||||||
assert!(ctx.span_id.is_none());
|
assert_eq!(ctx.span_id.as_deref(), Some("00f067aa0ba902b7"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user