diff --git a/Cargo.toml b/Cargo.toml index 4931c39..8abb931 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,8 @@ hyper = { version = "0.13.6", features = ["tcp"], optional = true } hyper-tls = { version = "0.4.3", optional = true } futures-util = { version = "0.3.5", features = ["io"], optional = true } tokio = { version = "0.2", features = ["time"], optional = true } +dyn-clone = "1.0.4" +dyn-clonable = "0.9.0" # curl_client [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/src/h1/mod.rs b/src/h1/mod.rs index 6577732..ce02438 100644 --- a/src/h1/mod.rs +++ b/src/h1/mod.rs @@ -40,7 +40,8 @@ type HttpPool = DashMap>; #[cfg(any(feature = "native-tls", feature = "rustls"))] type HttpsPool = DashMap, Error>>; -/// Async-h1 based HTTP Client, with connecton pooling ("Keep-Alive"). +/// Async-h1 based HTTP Client, with connection pooling ("Keep-Alive"). +#[derive(Clone)] pub struct H1Client { http_pools: HttpPool, #[cfg(any(feature = "native-tls", feature = "rustls"))] diff --git a/src/hyper.rs b/src/hyper.rs index c1404fc..a267d89 100644 --- a/src/hyper.rs +++ b/src/hyper.rs @@ -7,6 +7,7 @@ use std::fmt::Debug; use std::io; use std::str::FromStr; +use dyn_clonable::*; use futures_util::stream::TryStreamExt; use http_types::headers::{HeaderName, HeaderValue}; use http_types::StatusCode; @@ -21,7 +22,8 @@ use super::{async_trait, Error, HttpClient, Request, Response}; type HyperRequest = hyper::Request; // Avoid leaking Hyper generics into HttpClient by hiding it behind a dynamic trait object pointer. -trait HyperClientObject: Debug + Send + Sync + 'static { +#[clonable] +trait HyperClientObject: Clone + Debug + Send + Sync + 'static { fn dyn_request(&self, req: hyper::Request) -> hyper::client::ResponseFuture; } @@ -32,7 +34,7 @@ impl HyperClientObject for h } /// Hyper-based HTTP Client. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct HyperClient { client: Box, config: Config, diff --git a/src/isahc.rs b/src/isahc.rs index 30afdc1..7b3e7ce 100644 --- a/src/isahc.rs +++ b/src/isahc.rs @@ -13,7 +13,7 @@ use crate::Config; use super::{async_trait, Body, Error, HttpClient, Request, Response}; /// Curl-based HTTP Client. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct IsahcClient { client: isahc::HttpClient, config: Config, diff --git a/src/lib.rs b/src/lib.rs index 91ccfd5..4824f8d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,6 +48,8 @@ pub type Request = http_types::Request; /// An HTTP Response type with a streaming body. pub type Response = http_types::Response; +use dyn_clonable::*; + pub use async_trait::async_trait; pub use http_types; @@ -64,7 +66,8 @@ pub use http_types; /// though middleware for one of its own requests, and in order to do so should be wrapped in an /// `Rc`/`Arc` to enable reference cloning. #[async_trait] -pub trait HttpClient: std::fmt::Debug + Unpin + Send + Sync + 'static { +#[clonable] +pub trait HttpClient: Clone + std::fmt::Debug + Unpin + Send + Sync + 'static { /// Perform a request. async fn send(&self, req: Request) -> Result; diff --git a/src/wasm.rs b/src/wasm.rs index cec9103..b2557a3 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -9,7 +9,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; /// WebAssembly HTTP Client. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct WasmClient { _priv: (), }