1use std::sync::OnceLock;
8
9use http::header::HeaderName;
10use tower_http::cors::CorsLayer;
11
12static PROPAGATOR_HEADERS: OnceLock<Vec<HeaderName>> = OnceLock::new();
13
14pub fn set_propagator(propagator: &dyn opentelemetry::propagation::TextMapPropagator) {
21 let headers = propagator
22 .fields()
23 .map(|h| HeaderName::try_from(h).unwrap())
24 .collect();
25
26 tracing::debug!(
27 ?headers,
28 "Headers allowed in CORS requests for trace propagators set"
29 );
30 PROPAGATOR_HEADERS
31 .set(headers)
32 .expect(concat!(module_path!(), "::set_propagator was called twice"));
33}
34
35pub trait CorsLayerExt {
36 #[must_use]
37 fn allow_otel_headers<H>(self, headers: H) -> Self
38 where
39 H: IntoIterator<Item = HeaderName>;
40}
41
42impl CorsLayerExt for CorsLayer {
43 fn allow_otel_headers<H>(self, headers: H) -> Self
44 where
45 H: IntoIterator<Item = HeaderName>,
46 {
47 let base = PROPAGATOR_HEADERS.get().cloned().unwrap_or_default();
48 let headers: Vec<_> = headers.into_iter().chain(base).collect();
49 self.allow_headers(headers)
50 }
51}