Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for HTTP proxy: replace the HTTP client with reqwest #3424

Merged
merged 12 commits into from
Oct 28, 2024
67 changes: 30 additions & 37 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 17 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ features = ["derive"]
version = "0.10.19"
features = ["env", "yaml", "test"]

# Utilities for dealing with futures
[workspace.dependencies.futures-util]
version = "0.3.31"

# Rate-limiting
[workspace.dependencies.governor]
version = "0.7.0"
Expand Down Expand Up @@ -182,6 +186,12 @@ version = "0.3.0"
[workspace.dependencies.rand]
version = "0.8.5"

# High-level HTTP client
[workspace.dependencies.reqwest]
version = "0.12.8"
default-features = false
features = ["http2", "rustls-tls-manual-roots", "charset", "json", "socks"]

# TLS stack
[workspace.dependencies.rustls]
version = "0.23.15"
Expand Down Expand Up @@ -215,7 +225,7 @@ features = [
[workspace.dependencies.sentry]
version = "0.34.0"
default-features = false
features = ["backtrace", "contexts", "panic", "tower"]
features = ["backtrace", "contexts", "panic", "tower", "reqwest"]

# Sentry tower layer
[workspace.dependencies.sentry-tower]
Expand Down Expand Up @@ -272,7 +282,7 @@ features = ["util"]
# Tower HTTP layers
[workspace.dependencies.tower-http]
version = "0.6.1"
features = ["cors", "fs", "add-extension"]
features = ["cors", "fs", "add-extension", "set-header"]

# Logging and tracing
[workspace.dependencies.tracing]
Expand All @@ -286,7 +296,7 @@ version = "0.24.0"
features = ["trace", "metrics"]
[workspace.dependencies.opentelemetry-http]
version = "0.13.0"
features = ["hyper"]
features = ["reqwest"]
[workspace.dependencies.opentelemetry-semantic-conventions]
version = "0.16.0"
[workspace.dependencies.tracing-opentelemetry]
Expand All @@ -303,6 +313,10 @@ features = ["serde"]
version = "1.1.3"
features = ["serde"]

# HTTP mock server
[workspace.dependencies.wiremock]
version = "0.6.2"

# A few profile opt-level tweaks to make the test suite run faster
[profile.dev.package]
num-bigint-dig.opt-level = 3
Expand Down
2 changes: 2 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ disallowed-methods = [
{ path = "chrono::Utc::now", reason = "source the current time from the clock instead" },
{ path = "ulid::Ulid::from_datetime", reason = "use Ulid::from_datetime_with_source instead" },
{ path = "ulid::Ulid::new", reason = "use Ulid::from_datetime_with_source instead" },
{ path = "reqwest::Client::new", reason = "use mas_http::reqwest_client instead" },
{ path = "reqwest::RequestBuilder::send", reason = "use send_traced instead" },
]

disallowed-types = [
Expand Down
5 changes: 3 additions & 2 deletions crates/axum-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ axum-extra.workspace = true
bytes.workspace = true
chrono.workspace = true
data-encoding = "2.6.0"
futures-util = "0.3.31"
futures-util.workspace = true
headers.workspace = true
http.workspace = true
http-body.workspace = true
Expand All @@ -27,6 +27,7 @@ hyper-util.workspace = true
icu_locid = "1.4.0"
mime = "0.3.17"
rand.workspace = true
reqwest.workspace = true
sentry.workspace = true
serde.workspace = true
serde_with = "3.11.0"
Expand All @@ -41,7 +42,7 @@ ulid.workspace = true

oauth2-types.workspace = true
mas-data-model.workspace = true
mas-http = { workspace = true, features = ["client"] }
mas-http.workspace = true
mas-iana.workspace = true
mas-jose.workspace = true
mas-keystore.workspace = true
Expand Down
31 changes: 12 additions & 19 deletions crates/axum-utils/src/client_authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use axum_extra::typed_header::{TypedHeader, TypedHeaderRejectionReason};
use headers::{authorization::Basic, Authorization};
use http::{Request, StatusCode};
use mas_data_model::{Client, JwksOrJwksUri};
use mas_http::HttpServiceExt;
use mas_http::RequestBuilderExt;
use mas_iana::oauth::OAuthClientAuthenticationMethod;
use mas_jose::{jwk::PublicJsonWebKeySet, jwt::Jwt};
use mas_keystore::Encrypter;
Expand All @@ -28,9 +28,6 @@ use oauth2_types::errors::{ClientError, ClientErrorCode};
use serde::{de::DeserializeOwned, Deserialize};
use serde_json::Value;
use thiserror::Error;
use tower::{Service, ServiceExt};

use crate::http_client_factory::HttpClientFactory;

static JWT_BEARER_CLIENT_ASSERTION: &str = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";

Expand Down Expand Up @@ -104,7 +101,7 @@ impl Credentials {
#[tracing::instrument(skip_all, err)]
pub async fn verify(
&self,
http_client_factory: &HttpClientFactory,
http_client: &reqwest::Client,
encrypter: &Encrypter,
method: &OAuthClientAuthenticationMethod,
client: &Client,
Expand Down Expand Up @@ -146,7 +143,7 @@ impl Credentials {
.as_ref()
.ok_or(CredentialsVerificationError::InvalidClientConfig)?;

let jwks = fetch_jwks(http_client_factory, jwks)
let jwks = fetch_jwks(http_client, jwks)
.await
.map_err(|_| CredentialsVerificationError::JwksFetchFailed)?;

Expand Down Expand Up @@ -181,27 +178,23 @@ impl Credentials {
}

async fn fetch_jwks(
http_client_factory: &HttpClientFactory,
http_client: &reqwest::Client,
jwks: &JwksOrJwksUri,
) -> Result<PublicJsonWebKeySet, BoxError> {
let uri = match jwks {
JwksOrJwksUri::Jwks(j) => return Ok(j.clone()),
JwksOrJwksUri::JwksUri(u) => u,
};

let request = http::Request::builder()
.uri(uri.as_str())
.body(mas_http::EmptyBody::new())
.unwrap();

let mut client = http_client_factory
.client("client.fetch_jwks")
.response_body_to_bytes()
.json_response::<PublicJsonWebKeySet>();

let response = client.ready().await?.call(request).await?;
let response = http_client
.get(uri.as_str())
.send_traced()
.await?
.error_for_status()?
.json()
.await?;

Ok(response.into_body())
Ok(response)
}

#[derive(Debug, Error)]
Expand Down
Loading
Loading