Skip to content

Commit

Permalink
Make futures Send and Sync
Browse files Browse the repository at this point in the history
This requires `reqwest` >= 0.11.11, which is the earliest version of
`reqwest` that depends on `hyper` >= 0.14.14, in which the returned
futures became `Sync`.

BREAKING CHANGES: All parameters passed to request_async() methods
must now be Send and Sync, as must generic types stored in `*Request`
types on which `request_async()` is called. Notably, this also means
that futures returned by `AsyncHttpClient::call()` must be `Send` and
`Sync`.

Resolves #260.
  • Loading branch information
ramosbugs committed Mar 10, 2024
1 parent 4f7a22f commit 73df219
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 118 deletions.
331 changes: 232 additions & 99 deletions Cargo-1.65.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ base64 = "0.13"
thiserror = "1.0"
http = "0.2"
rand = "0.8"
reqwest = { version = "0.11", optional = true, default-features = false }
reqwest = { version = "0.11.11", optional = true, default-features = false }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sha2 = "0.10"
Expand Down
13 changes: 8 additions & 5 deletions src/devicecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ where

impl<'a, TE> DeviceAuthorizationRequest<'a, TE>
where
TE: ErrorResponse + 'static,
TE: ErrorResponse + Send + Sync + 'static,
{
/// Appends an extra param to the token request.
///
Expand Down Expand Up @@ -196,7 +196,7 @@ where
) -> Pin<Box<DeviceAuthorizationRequestFuture<'c, C, EF, TE>>>
where
Self: 'c,
C: AsyncHttpClient<'c>,
C: AsyncHttpClient<'c> + Send + Sync,
EF: ExtraDeviceAuthorizationFields,
{
Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) })
Expand Down Expand Up @@ -331,9 +331,12 @@ where
>
where
Self: 'c,
C: AsyncHttpClient<'c>,
S: Fn(Duration) -> SF + 'c,
SF: Future<Output = ()>,
C: AsyncHttpClient<'c> + Send + Sync,
EF: Send + Sync,
S: Fn(Duration) -> SF + Send + Sync + 'c,
SF: Future<Output = ()> + Send + Sync,
TR: Send + Sync,
TT: Send + Sync,
{
Box::pin(async move {
// Get the request timeout and starting interval
Expand Down
10 changes: 5 additions & 5 deletions src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@ pub type HttpResponse = http::Response<Vec<u8>>;
/// An asynchronous (future-based) HTTP client.
pub trait AsyncHttpClient<'c> {
/// Error type returned by HTTP client.
type Error: Error + 'static;
type Error: Error + Send + Sync + 'static;

/// Perform a single HTTP request.
fn call(
&'c self,
request: HttpRequest,
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + 'c>>;
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + Send + Sync + 'c>>;
}
impl<'c, E, F, T> AsyncHttpClient<'c> for T
where
E: Error + 'static,
F: Future<Output = Result<HttpResponse, E>> + 'c,
E: Error + Send + Sync + 'static,
F: Future<Output = Result<HttpResponse, E>> + Send + Sync + 'c,
// We can't implement this for FnOnce because the device authorization flow requires clients to
// supportmultiple calls.
T: Fn(HttpRequest) -> F,
Expand All @@ -43,7 +43,7 @@ where
fn call(
&'c self,
request: HttpRequest,
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + 'c>> {
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + Send + Sync + 'c>> {
Box::pin(self(request))
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/introspection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ where
) -> Pin<Box<TokenRequestFuture<'c, <C as AsyncHttpClient<'c>>::Error, TE, TIR>>>
where
Self: 'c,
C: AsyncHttpClient<'c>,
C: AsyncHttpClient<'c> + Send + Sync,
TE: Send + Sync,
TIR: Send + Sync,
TT: Send + Sync,
{
Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) })
}
Expand Down
2 changes: 1 addition & 1 deletion src/reqwest_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ impl<'c> AsyncHttpClient<'c> for reqwest::Client {
fn call(
&'c self,
request: HttpRequest,
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + 'c>> {
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + Send + Sync + 'c>> {
Box::pin(async move {
let response = self
.execute(request.try_into().map_err(Box::new)?)
Expand Down
4 changes: 3 additions & 1 deletion src/revocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,9 @@ where
) -> Pin<Box<TokenRequestFuture<'c, <C as AsyncHttpClient<'c>>::Error, TE, ()>>>
where
Self: 'c,
C: AsyncHttpClient<'c>,
C: AsyncHttpClient<'c> + Send + Sync,
RT: Send + Sync,
TE: Send + Sync,
{
Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) })
}
Expand Down
22 changes: 17 additions & 5 deletions src/token/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ where

/// Future returned by `request_async` methods.
pub type TokenRequestFuture<'c, RE, TE, TR> =
dyn Future<Output = Result<TR, RequestTokenError<RE, TE>>> + 'c;
dyn Future<Output = Result<TR, RequestTokenError<RE, TE>>> + Send + Sync + 'c;

/// A request to exchange an authorization code for an access token.
///
Expand Down Expand Up @@ -240,7 +240,10 @@ where
) -> Pin<Box<TokenRequestFuture<'c, <C as AsyncHttpClient<'c>>::Error, TE, TR>>>
where
Self: 'c,
C: AsyncHttpClient<'c>,
C: AsyncHttpClient<'c> + Send + Sync,
TE: Send + Sync,
TR: Send + Sync,
TT: Send + Sync,
{
Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) })
}
Expand Down Expand Up @@ -325,7 +328,10 @@ where
) -> Pin<Box<TokenRequestFuture<'c, <C as AsyncHttpClient<'c>>::Error, TE, TR>>>
where
Self: 'c,
C: AsyncHttpClient<'c>,
C: AsyncHttpClient<'c> + Send + Sync,
TE: Send + Sync,
TR: Send + Sync,
TT: Send + Sync,
{
Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) })
}
Expand Down Expand Up @@ -432,7 +438,10 @@ where
) -> Pin<Box<TokenRequestFuture<'c, <C as AsyncHttpClient<'c>>::Error, TE, TR>>>
where
Self: 'c,
C: AsyncHttpClient<'c>,
C: AsyncHttpClient<'c> + Send + Sync,
TE: Send + Sync,
TR: Send + Sync,
TT: Send + Sync,
{
Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) })
}
Expand Down Expand Up @@ -538,7 +547,10 @@ where
) -> Pin<Box<TokenRequestFuture<'c, <C as AsyncHttpClient<'c>>::Error, TE, TR>>>
where
Self: 'c,
C: AsyncHttpClient<'c>,
C: AsyncHttpClient<'c> + Send + Sync,
TE: Send + Sync,
TR: Send + Sync,
TT: Send + Sync,
{
Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) })
}
Expand Down

0 comments on commit 73df219

Please sign in to comment.