Skip to content

Commit

Permalink
Update HTTP client support
Browse files Browse the repository at this point in the history
- make the default no-client at all, backwards
  incompatible but better overall I think.
- add reqwest 0.12 support
  • Loading branch information
rbtcollins committed May 10, 2024
1 parent cdee650 commit 1b59b85
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 13 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/ci-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ jobs:
- surf-client
# no need for reqwest-client-rustls, it changes only internals of reqwest
- reqwest-client
- reqwest-client-11

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -58,13 +59,13 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: build
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls --all-targets
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls,reqwest-client-11,reqwest-client-11-rustls --all-targets

- uses: actions-rs/cargo@v1
# We test with approximately all-features to ensure that that does build (excludes nightly only backtrace)
with:
command: test
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls --all-targets
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls,reqwest-client-11,reqwest-client-11-rustls --all-targets

- uses: actions-rs/cargo@v1
with:
Expand All @@ -74,7 +75,7 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: clippy
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls --all-targets -- -D warnings
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls,reqwest-client-11,reqwest-client-11-rustls --all-targets -- -D warnings

msrv:
runs-on: ubuntu-latest
Expand Down
12 changes: 11 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ status = "experimental"
[features]
# Enable backtrace feature in anyhow
backtrace = ["anyhow/backtrace"]
default = ["surf-client"]
# Force clients to make a choice about which client to use
default = []
# Enable the functional test suite
functional = []
reqwest-client = ["reqwest", "reqwest/default-tls"]
reqwest-client-11 = ["reqwest-11", "reqwest-11/default-tls"]
# For users that don't want to depend on OpenSSL.
reqwest-client-11-rustls = ["reqwest-11", "reqwest-11/rustls-tls"]
reqwest-client-rustls = ["reqwest", "reqwest/rustls-tls"]
# To error if an unsupported API feature is present
strict = []
Expand Down Expand Up @@ -70,6 +73,13 @@ features = ["json"]
optional = true
version = "0.11.10"

[dependencies.reqwest-11]
default-features = false
features = ["json"]
optional = true
package = "reqwest"
version = "0.12.4"

[dependencies.serde]
features = ["derive"]
version = "1.0"
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ surf or reqwest support is built in, or any async HTTP client can be provided by
the user if they implement the thin trait used to abstract over the actual
client.

Examples with async-std and tokio are in the examples/ in the source
tree.
Examples with async-std (feature 'surf-client') and tokio (feature
'reqwest-client') are in the examples/ in the source tree. See the API docs for
more feature information.

To use it in a sync program, run an async executor and `block_on()` the relevant
calls. As the client specification requires sending background metrics to the
Expand Down
4 changes: 4 additions & 0 deletions benches/is_enabled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ fn batch(c: &mut Criterion) {
use surf::Client as HttpClient;
} else if #[cfg(feature = "reqwest")] {
use reqwest::Client as HttpClient;
} else if #[cfg(feature = "reqwest-11")] {
use reqwest_11::Client as HttpClient;
} else {
compile_error!("Cannot run test suite without a client enabled");
}
Expand Down Expand Up @@ -423,6 +425,8 @@ fn single_call(c: &mut Criterion) {
use surf::Client as HttpClient;
} else if #[cfg(feature = "reqwest")] {
use reqwest::Client as HttpClient;
} else if #[cfg(feature = "reqwest-11")] {
use reqwest_11::Client as HttpClient;
} else {
compile_error!("Cannot run test suite without a client enabled");
}
Expand Down
8 changes: 6 additions & 2 deletions examples/threads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum UserFeatures {

fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
cfg_if::cfg_if! {
if #[cfg(feature = "surf")] {
if #[cfg(feature = "surf-client")] {
use core::future::Future;
use surf::Client as HttpClient;
use async_std::task;
Expand All @@ -34,10 +34,14 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
}
}
let rt = RT{};
} else if #[cfg(feature = "reqwest")] {
} else if #[cfg(feature = "reqwest-client")] {
use reqwest::Client as HttpClient;
use tokio::runtime::Runtime;
let rt = Arc::new(Runtime::new().unwrap());
} else if #[cfg(feature = "reqwest-client-11")] {
use reqwest_11::Client as HttpClient;
use tokio::runtime::Runtime;
let rt = Arc::new(Runtime::new().unwrap());
} else {
compile_error!("Cannot run test suite without a client enabled");
}
Expand Down
2 changes: 2 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,8 @@ mod tests {
use surf::Client as HttpClient;
} else if #[cfg(feature = "reqwest")] {
use reqwest::Client as HttpClient;
} else if #[cfg(feature = "reqwest-11")] {
use reqwest_11::Client as HttpClient;
} else {
compile_error!("Cannot run test suite without a client enabled");
}
Expand Down
2 changes: 2 additions & 0 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#[cfg(feature = "reqwest")]
mod reqwest;
#[cfg(feature = "reqwest-11")]
mod reqwest_11;
mod shim;
#[cfg(feature = "surf")]
mod surf;
Expand Down
48 changes: 48 additions & 0 deletions src/http/reqwest_11.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//! Shim reqwest into an unleash HTTP client
// Copyright 2022 Cognite AS

use async_trait::async_trait;
use serde::{de::DeserializeOwned, Serialize};

use super::HttpClient;

#[async_trait]
impl HttpClient for reqwest_11::Client {
type HeaderName = reqwest_11::header::HeaderName;
type Error = reqwest_11::Error;
type RequestBuilder = reqwest_11::RequestBuilder;

fn build_header(name: &'static str) -> Result<Self::HeaderName, Self::Error> {
Ok(Self::HeaderName::from_static(name))
}

fn get(&self, uri: &str) -> Self::RequestBuilder {
self.get(uri)
}

fn post(&self, uri: &str) -> Self::RequestBuilder {
self.post(uri)
}

fn header(
builder: Self::RequestBuilder,
key: &Self::HeaderName,
value: &str,
) -> Self::RequestBuilder {
builder.header(key.clone(), value)
}

async fn get_json<T: DeserializeOwned>(req: Self::RequestBuilder) -> Result<T, Self::Error> {
req.send().await?.json::<T>().await
}

async fn post_json<T: Serialize + Sync>(
req: Self::RequestBuilder,
content: &T,
) -> Result<bool, Self::Error> {
let req = req.json(content);
let res = req.send().await?;
Ok(res.status().is_success())
}
}
10 changes: 8 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ strategy memoization function.
```no_run
# mod i {
# cfg_if::cfg_if!{
# if #[cfg(not(feature = "surf"))] {
# if #[cfg(not(feature = "surf-client"))] {
# pub fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
# Ok(())
# }
Expand Down Expand Up @@ -99,13 +99,17 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
* **backtrace** -
Enable backtrace feature in anyhow (nightly only)
* **default** -
The default feature enables the async-std/surf feature.
By default no features are enabled.
* **functional** -
Only relevant to developers: enables the functional test suite.
* **reqwest-client** -
Enables reqwest with OpenSSL TLS support
* **reqwest-client-11** -
Enables reqwest 0.11 with OpenSSL TLS support
* **reqwest-client-rustls** -
Enables reqwest with RusTLS support
* **reqwest-client-11-rustls** -
Enables reqwest 0.11 with RusTLS support
* **strict** -
Turn unexpected fields in API responses into errors
* **surf-client** -
Expand Down Expand Up @@ -159,6 +163,8 @@ pub mod prelude {
pub use surf::Client as DefaultClient;
} else if #[cfg(feature = "reqwest")] {
pub use reqwest::Client as DefaultClient;
} else if #[cfg(feature = "reqwest-11")] {
pub use reqwest_11::Client as DefaultClient;
}
}
}
2 changes: 2 additions & 0 deletions tests/clientspec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ mod tests {
use surf::Client as HttpClient;
} else if #[cfg(feature = "reqwest")] {
use reqwest::Client as HttpClient;
} else if #[cfg(feature = "reqwest-11")] {
use reqwest_11::Client as HttpClient;
} else {
compile_error!("Cannot run test suite without a client enabled");
}
Expand Down
18 changes: 15 additions & 3 deletions tests/functional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ mod tests {
}
}

#[cfg(feature = "reqwest")]
#[cfg(or(feature = "reqwest", feature = "reqwest-11"))]
struct TokioJoinHandle {
inner: tokio::task::JoinHandle<()>,
}
Expand All @@ -80,9 +80,9 @@ mod tests {
}
}

#[cfg(feature = "reqwest")]
#[cfg(or(feature = "reqwest", feature = "reqwest-11"))]
struct TokioAsync;
#[cfg(feature = "reqwest")]
#[cfg(or(feature = "reqwest", feature = "reqwest-11"))]
#[async_trait]
impl AsyncImpl for TokioAsync {
type JoinHandle = TokioJoinHandle;
Expand Down Expand Up @@ -142,6 +142,11 @@ mod tests {
async fn test_smoke_async_reqwest() {
test_smoke_async::<reqwest::Client>().await.unwrap();
}
#[cfg(feature = "reqwest-11")]
#[tokio::test]
async fn test_smoke_async_reqwest() {
test_smoke_async::<reqwest_11::Client>().await.unwrap();
}

async fn test_smoke_threaded<C, A>(
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>>
Expand Down Expand Up @@ -204,4 +209,11 @@ mod tests {
.await
.unwrap();
}
#[cfg(feature = "reqwest-11")]
#[tokio::test]
async fn test_smoke_threaded_reqwest() {
test_smoke_threaded::<reqwest_11::Client, TokioAsync>()
.await
.unwrap();
}
}

0 comments on commit 1b59b85

Please sign in to comment.