From db9262fa43a6e2ac7ea25e4241796daa21ae366a Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 27 Apr 2021 21:39:08 +0200 Subject: [PATCH] client: Add support for reqwest as an HTTP client --- ruma-client/Cargo.toml | 6 ++++ ruma-client/src/http_client.rs | 4 +++ ruma-client/src/http_client/reqwest.rs | 39 ++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 ruma-client/src/http_client/reqwest.rs diff --git a/ruma-client/Cargo.toml b/ruma-client/Cargo.toml index 0ed283cd..d99d96a9 100644 --- a/ruma-client/Cargo.toml +++ b/ruma-client/Cargo.toml @@ -20,6 +20,11 @@ client-api = ["ruma-client-api"] # HTTP clients hyper-native-tls = ["hyper", "hyper-tls"] hyper-rustls = ["hyper", "hyper-rustls-crate"] +reqwest-native-tls = ["reqwest", "reqwest/native-tls"] +reqwest-native-tls-vendored = ["reqwest", "reqwest/native-tls-vendored"] +reqwest-rustls-manual-roots = ["reqwest", "reqwest/rustls-tls-manual-roots"] +reqwest-rustls-webpki-roots = ["reqwest", "reqwest/rustls-tls-webpki-roots"] +reqwest-rustls-native-roots = ["reqwest", "reqwest/rustls-tls-native-roots"] [dependencies] assign = "1.1.1" @@ -31,6 +36,7 @@ http = "0.2.2" hyper = { version = "0.14.2", optional = true, features = ["client", "http1", "http2", "tcp"] } hyper-tls = { version = "0.5.0", optional = true } hyper-rustls-crate = { package = "hyper-rustls", version = "0.22.1", optional = true, default-features = false } +reqwest = { version = "0.11.3", optional = true, default-features = false } ruma-api = { version = "=0.17.0-alpha.4", path = "../ruma-api" } ruma-client-api = { version = "=0.10.0-alpha.3", path = "../ruma-client-api", optional = true, features = ["client"] } ruma-common = { version = "0.5.0", path = "../ruma-common" } diff --git a/ruma-client/src/http_client.rs b/ruma-client/src/http_client.rs index 3973e89b..ffaca64b 100644 --- a/ruma-client/src/http_client.rs +++ b/ruma-client/src/http_client.rs @@ -11,6 +11,8 @@ use crate::ResponseResult; #[cfg(feature = "hyper")] mod hyper; +#[cfg(feature = "reqwest")] +mod reqwest; #[cfg(feature = "hyper")] pub use self::hyper::Hyper; @@ -18,6 +20,8 @@ pub use self::hyper::Hyper; pub use self::hyper::HyperNativeTls; #[cfg(feature = "hyper-rustls")] pub use self::hyper::HyperRustls; +#[cfg(feature = "reqwest")] +pub use self::reqwest::Reqwest; /// An HTTP client that can be used to send requests to a Matrix homeserver. #[async_trait] diff --git a/ruma-client/src/http_client/reqwest.rs b/ruma-client/src/http_client/reqwest.rs new file mode 100644 index 00000000..8ae9c7d5 --- /dev/null +++ b/ruma-client/src/http_client/reqwest.rs @@ -0,0 +1,39 @@ +use std::{convert::TryInto, mem}; + +use async_trait::async_trait; +use bytes::{Bytes, BytesMut}; + +use super::{DefaultConstructibleHttpClient, HttpClient}; + +/// The `reqwest` crate's `Client`. +pub type Reqwest = reqwest::Client; + +#[async_trait] +impl HttpClient for Reqwest { + type RequestBody = BytesMut; + type ResponseBody = Bytes; + type Error = reqwest::Error; + + async fn send_http_request( + &self, + req: http::Request, + ) -> Result, reqwest::Error> { + let req = req.map(|body| body.freeze()).try_into()?; + let mut res = self.execute(req).await?; + + let mut http_builder = + http::Response::builder().status(res.status()).version(res.version()); + mem::swap( + http_builder.headers_mut().expect("http::response::Builder to be usable"), + res.headers_mut(), + ); + + Ok(http_builder.body(res.bytes().await?).expect("http::Response construction to work")) + } +} + +impl DefaultConstructibleHttpClient for Reqwest { + fn default() -> Self { + reqwest::Client::new() + } +}