diff --git a/Cargo.lock b/Cargo.lock index e1896fef55..d439a3131c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1525,6 +1525,7 @@ dependencies = [ "http-body-util", "httpmock", "libc", + "libdd-capabilities", "libdd-capabilities-impl", "libdd-common", "libdd-common-ffi", @@ -2853,6 +2854,7 @@ version = "0.1.0" dependencies = [ "bytes", "http", + "http-body-util", "libdd-capabilities", "libdd-common", ] @@ -2878,7 +2880,6 @@ dependencies = [ "hyper-util", "indexmap 2.12.1", "libc", - "libdd-capabilities", "maplit", "mime", "multer", diff --git a/datadog-sidecar/Cargo.toml b/datadog-sidecar/Cargo.toml index 59c749de59..258d3a9e79 100644 --- a/datadog-sidecar/Cargo.toml +++ b/datadog-sidecar/Cargo.toml @@ -18,6 +18,7 @@ anyhow = { version = "1.0" } arrayref = "0.3.7" priority-queue = "2.1.1" libdd-common = { path = "../libdd-common" } +libdd-capabilities = { path = "../libdd-capabilities", version = "0.1.0" } datadog-sidecar-macros = { path = "../datadog-sidecar-macros" } libdd-telemetry = { path = "../libdd-telemetry", features = ["tracing"] } diff --git a/datadog-sidecar/src/service/agent_info.rs b/datadog-sidecar/src/service/agent_info.rs index a97765f2fe..82c94769a7 100644 --- a/datadog-sidecar/src/service/agent_info.rs +++ b/datadog-sidecar/src/service/agent_info.rs @@ -16,7 +16,7 @@ use datadog_ipc::platform::NamedShmHandle; use futures::future::Shared; use futures::FutureExt; use http::uri::PathAndQuery; -use libdd_common::DefaultHttpClient; +use libdd_capabilities_impl::DefaultHttpClient; use libdd_common::{Endpoint, MutexExt}; use libdd_data_pipeline::agent_info::schema::AgentInfoStruct; use libdd_data_pipeline::agent_info::{fetch_info_with_state, FetchInfoStatus}; diff --git a/datadog-sidecar/src/service/tracing/trace_flusher.rs b/datadog-sidecar/src/service/tracing/trace_flusher.rs index c522bd024a..53d09c5823 100644 --- a/datadog-sidecar/src/service/tracing/trace_flusher.rs +++ b/datadog-sidecar/src/service/tracing/trace_flusher.rs @@ -5,8 +5,9 @@ use super::TraceSendData; use crate::agent_remote_config::AgentRemoteConfigWriter; use datadog_ipc::platform::NamedShmHandle; use futures::future::join_all; -use libdd_common::capabilities::HttpClientTrait; -use libdd_common::{DefaultHttpClient, Endpoint, MutexExt}; +use libdd_capabilities::HttpClientTrait; +use libdd_capabilities_impl::DefaultHttpClient; +use libdd_common::{Endpoint, MutexExt}; use libdd_trace_utils::trace_utils; use libdd_trace_utils::trace_utils::SendData; use libdd_trace_utils::trace_utils::SendDataResult; diff --git a/libdd-capabilities-impl/Cargo.toml b/libdd-capabilities-impl/Cargo.toml index 9b4e4af7b8..6eded7215d 100644 --- a/libdd-capabilities-impl/Cargo.toml +++ b/libdd-capabilities-impl/Cargo.toml @@ -21,6 +21,9 @@ http = "1" libdd-capabilities = { path = "../libdd-capabilities", version = "0.1.0" } libdd-common = { path = "../libdd-common", version = "3.0.2", default-features = false } +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +http-body-util = "0.1" + [features] default = ["https"] https = ["libdd-common/https"] diff --git a/libdd-capabilities-impl/src/http.rs b/libdd-capabilities-impl/src/http.rs index 418436818a..b0ae9b3c75 100644 --- a/libdd-capabilities-impl/src/http.rs +++ b/libdd-capabilities-impl/src/http.rs @@ -1,7 +1,60 @@ // Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 -//! Re-exports `DefaultHttpClient` from `libdd-common`, where it lives alongside -//! the hyper infrastructure it wraps. +//! Native HTTP client implementation backed by hyper. -pub use libdd_common::DefaultHttpClient; +mod native { + use libdd_capabilities::http::{HttpClientTrait, HttpError}; + use libdd_capabilities::maybe_send::MaybeSend; + use libdd_common::connector::Connector; + use libdd_common::http_common::{new_default_client, Body, GenericHttpClient}; + + use http_body_util::BodyExt; + + #[derive(Clone)] + pub struct DefaultHttpClient { + client: GenericHttpClient, + } + + impl std::fmt::Debug for DefaultHttpClient { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("DefaultHttpClient").finish() + } + } + + impl HttpClientTrait for DefaultHttpClient { + fn new_client() -> Self { + Self { + client: new_default_client(), + } + } + + #[allow(clippy::manual_async_fn)] + fn request( + &self, + req: http::Request, + ) -> impl std::future::Future, HttpError>> + MaybeSend + { + let client = self.client.clone(); + async move { + let hyper_req = req.map(Body::from_bytes); + + let response = client + .request(hyper_req) + .await + .map_err(|e| HttpError::Network(e.into()))?; + + let (parts, body) = response.into_parts(); + let collected = body + .collect() + .await + .map_err(|e| HttpError::ResponseBody(e.into()))? + .to_bytes(); + + Ok(http::Response::from_parts(parts, collected)) + } + } + } +} + +pub use native::DefaultHttpClient; diff --git a/libdd-capabilities-impl/src/lib.rs b/libdd-capabilities-impl/src/lib.rs index b9e09cb636..6b3f6cd959 100644 --- a/libdd-capabilities-impl/src/lib.rs +++ b/libdd-capabilities-impl/src/lib.rs @@ -9,40 +9,53 @@ mod http; -use core::future::Future; +pub use libdd_capabilities::HttpClientTrait; +#[cfg(not(target_arch = "wasm32"))] pub use http::DefaultHttpClient; -use libdd_capabilities::http::HttpError; -pub use libdd_capabilities::HttpClientTrait; -use libdd_capabilities::MaybeSend; - -/// Bundle struct for native platform capabilities. -/// -/// Delegates to [`DefaultHttpClient`] for HTTP. As more capability traits are -/// added (spawn, sleep, etc.), additional fields and impls are added here -/// without changing the type identity — consumers see the same -/// `NativeCapabilities` throughout. -/// -/// Individual capability traits keep minimal per-function bounds (e.g. -/// functions that only need HTTP require just `H: HttpClientTrait`, not the -/// full bundle) so that native callers like the sidecar can use -/// `DefaultHttpClient` directly without pulling in this bundle. -#[derive(Clone, Debug)] -pub struct NativeCapabilities { - http: DefaultHttpClient, -} -impl HttpClientTrait for NativeCapabilities { - fn new_client() -> Self { - Self { - http: DefaultHttpClient::new_client(), - } +#[cfg(not(target_arch = "wasm32"))] +mod native { + use core::future::Future; + + use libdd_capabilities::http::HttpError; + use libdd_capabilities::MaybeSend; + + use super::DefaultHttpClient; + use super::HttpClientTrait; + + /// Bundle struct for native platform capabilities. + /// + /// Delegates to [`DefaultHttpClient`] for HTTP. As more capability traits are + /// added (spawn, sleep, etc.), additional fields and impls are added here + /// without changing the type identity — consumers see the same + /// `NativeCapabilities` throughout. + /// + /// Individual capability traits keep minimal per-function bounds (e.g. + /// functions that only need HTTP require just `H: HttpClientTrait`, not the + /// full bundle) so that native callers like the sidecar can use + /// `DefaultHttpClient` directly without pulling in this bundle. + #[derive(Clone, Debug)] + pub struct NativeCapabilities { + http: DefaultHttpClient, } - fn request( - &self, - req: ::http::Request, - ) -> impl Future, HttpError>> + MaybeSend { - self.http.request(req) + impl HttpClientTrait for NativeCapabilities { + fn new_client() -> Self { + Self { + http: DefaultHttpClient::new_client(), + } + } + + fn request( + &self, + req: ::http::Request, + ) -> impl Future, HttpError>> + MaybeSend + { + self.http.request(req) + } } } + +#[cfg(not(target_arch = "wasm32"))] +pub use native::NativeCapabilities; diff --git a/libdd-common/Cargo.toml b/libdd-common/Cargo.toml index ae1f2bf164..f9d4f1ac19 100644 --- a/libdd-common/Cargo.toml +++ b/libdd-common/Cargo.toml @@ -16,7 +16,6 @@ crate-type = ["lib"] bench = false [dependencies] -libdd-capabilities = { path = "../libdd-capabilities", version = "0.1.0" } anyhow = "1.0" futures = "0.3" futures-core = { version = "0.3.0", default-features = false } diff --git a/libdd-common/src/capabilities/mod.rs b/libdd-common/src/capabilities/mod.rs deleted file mode 100644 index 90dcfe384f..0000000000 --- a/libdd-common/src/capabilities/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/ -// SPDX-License-Identifier: Apache-2.0 - -//! Re-exports of capability trait types for convenience. - -pub use libdd_capabilities::{HttpClientTrait, HttpError}; diff --git a/libdd-common/src/http_common.rs b/libdd-common/src/http_common.rs index 39b2c97f73..1ffd3246fe 100644 --- a/libdd-common/src/http_common.rs +++ b/libdd-common/src/http_common.rs @@ -300,56 +300,6 @@ mod native { pub fn client_builder() -> hyper_util::client::legacy::Builder { hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::default()) } - - // --- DefaultHttpClient: portable HttpClientTrait backed by hyper --- - - use libdd_capabilities::http::{HttpClientTrait, HttpError}; - use libdd_capabilities::maybe_send::MaybeSend; - - #[derive(Clone)] - pub struct DefaultHttpClient { - client: GenericHttpClient, - } - - impl std::fmt::Debug for DefaultHttpClient { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("DefaultHttpClient").finish() - } - } - - impl HttpClientTrait for DefaultHttpClient { - fn new_client() -> Self { - Self { - client: new_default_client(), - } - } - - #[allow(clippy::manual_async_fn)] - fn request( - &self, - req: http::Request, - ) -> impl std::future::Future, HttpError>> + MaybeSend - { - let client = self.client.clone(); - async move { - let hyper_req = req.map(Body::from_bytes); - - let response = client - .request(hyper_req) - .await - .map_err(|e| HttpError::Network(e.into()))?; - - let (parts, body) = response.into_parts(); - let collected = body - .collect() - .await - .map_err(|e| HttpError::ResponseBody(e.into()))? - .to_bytes(); - - Ok(http::Response::from_parts(parts, collected)) - } - } - } } #[cfg(not(target_arch = "wasm32"))] diff --git a/libdd-common/src/lib.rs b/libdd-common/src/lib.rs index 786af97cd9..1922446c6c 100644 --- a/libdd-common/src/lib.rs +++ b/libdd-common/src/lib.rs @@ -14,7 +14,6 @@ use std::sync::{Mutex, MutexGuard}; use std::{borrow::Cow, ops::Deref, path::PathBuf, str::FromStr}; pub mod azure_app_services; -pub mod capabilities; #[cfg(not(target_arch = "wasm32"))] pub mod cc_utils; #[cfg(not(target_arch = "wasm32"))] @@ -113,8 +112,6 @@ pub mod header { HeaderName::from_static("x-datadog-test-session-token"); } -#[cfg(not(target_arch = "wasm32"))] -pub use http_common::DefaultHttpClient; #[cfg(not(target_arch = "wasm32"))] pub type HttpClient = http_common::GenericHttpClient; #[cfg(not(target_arch = "wasm32"))]