Upgrade http, ruma, reqwest and wiremock dependencies (#3362)

They need to be updated together
because the latters depend on the former.

matrix-authentication-service is still using http 0.2
so we need to add a conversion layer between both major versions
for OIDC requests.

We need to update vodozemac too because of a dependency resolution issue.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
Kévin Commaille
2024-04-30 14:04:56 +02:00
committed by GitHub
parent ea1a01000f
commit 856dd01009
13 changed files with 523 additions and 408 deletions

679
Cargo.lock generated
View File

File diff suppressed because it is too large Load Diff

View File

@@ -36,10 +36,10 @@ futures-executor = "0.3.21"
futures-util = { version = "0.3.26", default-features = false, features = [
"alloc",
] }
http = "0.2.6"
http = "1.1.0"
imbl = "2.0.0"
itertools = "0.12.0"
ruma = { git = "https://github.com/ruma/ruma", rev = "21b644ac6ae1c7d4a4f7e98a6481a3318f2deeaa", features = [
ruma = { git = "https://github.com/ruma/ruma", rev = "b6200c01a120120faf9f744ab4f171ff3beefd72", features = [
"client-api-c",
"compat-upload-signatures",
"compat-user-id",
@@ -48,7 +48,7 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "21b644ac6ae1c7d4a4f7e98a64
"unstable-msc3401",
"unstable-msc3266",
] }
ruma-common = { git = "https://github.com/ruma/ruma", rev = "21b644ac6ae1c7d4a4f7e98a6481a3318f2deeaa" }
ruma-common = { git = "https://github.com/ruma/ruma", rev = "b6200c01a120120faf9f744ab4f171ff3beefd72" }
once_cell = "1.16.0"
rand = "0.8.5"
serde = "1.0.151"
@@ -63,8 +63,8 @@ tracing = { version = "0.1.40", default-features = false, features = ["std"] }
tracing-core = "0.1.32"
uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "789a9023b522562a95618443cee5a0d4f111c4c7" }
uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "789a9023b522562a95618443cee5a0d4f111c4c7" }
vodozemac = { git="https://github.com/matrix-org/vodozemac", rev = "0c75746fc8a5eda4a0e490d345d1798b4c6cbd67" }
wiremock = "0.5.21"
vodozemac = { git="https://github.com/matrix-org/vodozemac", rev = "2722fb9518059ccd2ad55470f4c4d3ba5e447bd9" }
wiremock = "0.6.0"
zeroize = "1.6.0"
matrix-sdk = { path = "crates/matrix-sdk", version = "0.7.0", default-features = false }

View File

@@ -66,11 +66,9 @@ pub fn create_otlp_tracer(
let auth = STANDARD.encode(format!("{user}:{password}"));
let headers = HashMap::from([("Authorization".to_owned(), format!("Basic {auth}"))]);
let http_client = matrix_sdk::reqwest::ClientBuilder::new().build()?;
let exporter = opentelemetry_otlp::new_exporter()
.http()
.with_http_client(http_client)
.with_protocol(Protocol::HttpBinary)
.with_endpoint(otlp_endpoint)
.with_headers(headers);

View File

@@ -661,7 +661,7 @@ mod tests {
impl Match for SlidingSyncMatcher {
fn matches(&self, request: &Request) -> bool {
request.url.path() == "/_matrix/client/unstable/org.matrix.msc3575/sync"
&& request.method == Method::Post
&& request.method == Method::POST
}
}

View File

@@ -48,7 +48,7 @@ pub(crate) struct PartialSlidingSyncRequest {
impl Match for SlidingSyncMatcher {
fn matches(&self, request: &Request) -> bool {
request.url.path() == "/_matrix/client/unstable/org.matrix.msc3575/sync"
&& request.method == Method::Post
&& request.method == Method::POST
}
}

View File

@@ -299,7 +299,7 @@ struct SlidingSyncMatcher;
impl Match for SlidingSyncMatcher {
fn matches(&self, request: &Request) -> bool {
request.url.path() == "/_matrix/client/unstable/org.matrix.msc3575/sync"
&& request.method == Method::Post
&& request.method == Method::POST
}
}

View File

@@ -46,6 +46,7 @@ uniffi = ["dep:uniffi", "matrix-sdk-base/uniffi"]
experimental-oidc = [
"ruma/unstable-msc2967",
"dep:chrono",
"dep:http_old",
"dep:language-tags",
"dep:mas-oidc-client",
"dep:rand",
@@ -83,6 +84,7 @@ eyre = { version = "0.6.8", optional = true }
futures-core = { workspace = true }
futures-util = { workspace = true }
http = { workspace = true }
http_old = { package = "http", version = "0.2", optional = true }
imbl = { workspace = true, features = ["serde"] }
indexmap = "2.0.2"
js_int = "0.2.2"
@@ -120,14 +122,14 @@ optional = true
[target.'cfg(target_arch = "wasm32")'.dependencies]
gloo-timers = { version = "0.3.0", features = ["futures"] }
reqwest = { version = "0.11.10", default_features = false }
reqwest = { version = "0.12.4", default_features = false }
tokio = { workspace = true, features = ["macros"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
backoff = { version = "0.4.0", features = ["tokio"] }
# only activate reqwest's stream feature on non-wasm, the wasm part seems to not
# support *sending* streams, which makes it useless for us.
reqwest = { version = "0.11.10", default_features = false, features = ["stream"] }
reqwest = { version = "0.12.4", default_features = false, features = ["stream"] }
tokio = { workspace = true, features = ["fs", "rt", "macros"] }
tokio-util = "0.7.9"
wiremock = { workspace = true, optional = true }
@@ -151,7 +153,7 @@ wasm-bindgen-test = "0.3.33"
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
wiremock = { version = "0.5.13" }
wiremock = { workspace = true }
[[test]]
name = "integration"

View File

@@ -0,0 +1,179 @@
//! Helper traits to convert between http 0.2 and http 1.x.
/// Convert from http 1.x to http 0.2
pub trait ToHttpOld {
type Output;
fn to_http_old(self) -> Self::Output;
}
impl<T> ToHttpOld for http::Response<T> {
type Output = http_old::Response<T>;
fn to_http_old(self) -> Self::Output {
let (parts, body) = self.into_parts();
let mut response = http_old::Response::new(body);
*response.status_mut() = parts.status.to_http_old();
*response.version_mut() = parts.version.to_http_old();
*response.headers_mut() = parts.headers.to_http_old();
// We cannot do anything about extensions because we cannot iterate over them.
response
}
}
impl ToHttpOld for http::StatusCode {
type Output = http_old::StatusCode;
fn to_http_old(self) -> Self::Output {
http_old::StatusCode::from_u16(self.as_u16())
.expect("status code should be valid between both versions")
}
}
impl ToHttpOld for http::Version {
type Output = http_old::Version;
fn to_http_old(self) -> Self::Output {
if self == http::Version::HTTP_09 {
http_old::Version::HTTP_09
} else if self == http::Version::HTTP_10 {
http_old::Version::HTTP_10
} else if self == http::Version::HTTP_11 {
http_old::Version::HTTP_11
} else if self == http::Version::HTTP_2 {
http_old::Version::HTTP_2
} else if self == http::Version::HTTP_3 {
http_old::Version::HTTP_3
} else {
// Current http code doesn't have other variants.
unreachable!()
}
}
}
impl ToHttpOld for http::HeaderMap<http::HeaderValue> {
type Output = http_old::HeaderMap<http_old::HeaderValue>;
fn to_http_old(self) -> Self::Output {
let mut map = http_old::HeaderMap::new();
map.extend(
self.into_iter()
.map(|(name, value)| (name.map(ToHttpOld::to_http_old), value.to_http_old())),
);
map
}
}
impl ToHttpOld for http::HeaderName {
type Output = http_old::HeaderName;
fn to_http_old(self) -> Self::Output {
http_old::HeaderName::from_bytes(self.as_ref())
.expect("header name should be valid between both versions")
}
}
impl ToHttpOld for http::HeaderValue {
type Output = http_old::HeaderValue;
fn to_http_old(self) -> Self::Output {
http_old::HeaderValue::from_bytes(self.as_bytes())
.expect("header value should be valid between both versions")
}
}
/// Convert from http 0.2 to http 1.x
pub trait ToHttpNew {
type Output;
fn to_http_new(self) -> Self::Output;
}
impl<T> ToHttpNew for http_old::Request<T> {
type Output = http::Request<T>;
fn to_http_new(self) -> Self::Output {
let (parts, body) = self.into_parts();
let mut request = http::Request::new(body);
*request.method_mut() = parts.method.to_http_new();
*request.uri_mut() = parts.uri.to_http_new();
*request.version_mut() = parts.version.to_http_new();
*request.headers_mut() = parts.headers.to_http_new();
// We cannot do anything about extensions because we cannot iterate over them.
request
}
}
impl ToHttpNew for http_old::Method {
type Output = http::Method;
fn to_http_new(self) -> Self::Output {
self.as_str().parse().expect("method should be valid between both versions")
}
}
impl ToHttpNew for http_old::Uri {
type Output = http::Uri;
fn to_http_new(self) -> Self::Output {
self.to_string().parse().expect("URI should be valid between both versions")
}
}
impl ToHttpNew for http_old::Version {
type Output = http::Version;
fn to_http_new(self) -> Self::Output {
if self == http_old::Version::HTTP_09 {
http::Version::HTTP_09
} else if self == http_old::Version::HTTP_10 {
http::Version::HTTP_10
} else if self == http_old::Version::HTTP_11 {
http::Version::HTTP_11
} else if self == http_old::Version::HTTP_2 {
http::Version::HTTP_2
} else if self == http_old::Version::HTTP_3 {
http::Version::HTTP_3
} else {
// Current http code doesn't have other variants.
unreachable!()
}
}
}
impl ToHttpNew for http_old::HeaderMap<http_old::HeaderValue> {
type Output = http::HeaderMap<http::HeaderValue>;
fn to_http_new(self) -> Self::Output {
let mut map = http::HeaderMap::new();
map.extend(
self.into_iter()
.map(|(name, value)| (name.map(ToHttpNew::to_http_new), value.to_http_new())),
);
map
}
}
impl ToHttpNew for http_old::HeaderName {
type Output = http::HeaderName;
fn to_http_new(self) -> Self::Output {
http::HeaderName::from_bytes(self.as_ref())
.expect("header name should be valid between both versions")
}
}
impl ToHttpNew for http_old::HeaderValue {
type Output = http::HeaderValue;
fn to_http_new(self) -> Self::Output {
http::HeaderValue::from_bytes(self.as_bytes())
.expect("header value should be valid between both versions")
}
}

View File

@@ -34,11 +34,15 @@ use tracing::{debug, field::debug, instrument, trace};
use crate::{config::RequestConfig, error::HttpError};
#[cfg(feature = "experimental-oidc")]
mod http_helpers;
#[cfg(not(target_arch = "wasm32"))]
mod native;
#[cfg(target_arch = "wasm32")]
mod wasm;
#[cfg(feature = "experimental-oidc")]
use http_helpers::{ToHttpNew, ToHttpOld};
#[cfg(not(target_arch = "wasm32"))]
pub(crate) use native::HttpSettings;
@@ -225,8 +229,8 @@ async fn response_to_http_response(
}
#[cfg(feature = "experimental-oidc")]
impl tower::Service<http::Request<Bytes>> for HttpClient {
type Response = http::Response<Bytes>;
impl tower::Service<http_old::Request<Bytes>> for HttpClient {
type Response = http_old::Response<Bytes>;
type Error = tower::BoxError;
type Future = futures_core::future::BoxFuture<'static, Result<Self::Response, Self::Error>>;
@@ -237,13 +241,19 @@ impl tower::Service<http::Request<Bytes>> for HttpClient {
std::task::Poll::Ready(Ok(()))
}
fn call(&mut self, req: http::Request<Bytes>) -> Self::Future {
fn call(&mut self, req: http_old::Request<Bytes>) -> Self::Future {
let inner = self.inner.clone();
let fut = async move {
native::send_request(&inner, &req, DEFAULT_REQUEST_TIMEOUT, Default::default())
.await
.map_err(Into::into)
native::send_request(
&inner,
&req.to_http_new(),
DEFAULT_REQUEST_TIMEOUT,
Default::default(),
)
.await
.map(ToHttpOld::to_http_old)
.map_err(Into::into)
};
Box::pin(fut)
}

View File

@@ -16,7 +16,7 @@
use std::sync::{Arc, Mutex};
use http::StatusCode;
use http_old::StatusCode;
use mas_oidc_client::{
error::{
DiscoveryError,

View File

@@ -1093,7 +1093,7 @@ mod tests {
impl Match for SlidingSyncMatcher {
fn matches(&self, request: &Request) -> bool {
request.url.path() == "/_matrix/client/unstable/org.matrix.msc3575/sync"
&& request.method == Method::Post
&& request.method == Method::POST
}
}
@@ -1167,7 +1167,7 @@ mod tests {
fn matches(&self, request: &Request) -> bool {
request.url.path()
== format!("/_matrix/client/r0/rooms/{room_id}/members", room_id = self.0)
&& request.method == Method::Get
&& request.method == Method::GET
}
}

View File

@@ -15,14 +15,14 @@ eyeball-im = { workspace = true }
futures = { version = "0.3.29", features = ["executor"] }
futures-core = { workspace = true }
futures-util = { workspace = true }
http = "0.2.11"
http = { workspace = true }
matrix-sdk = { workspace = true, default-features = true, features = ["testing", "qrcode"] }
matrix-sdk-ui = { workspace = true, default-features = true }
matrix-sdk-test = { workspace = true }
once_cell = { workspace = true }
rand = { workspace = true }
stream_assert = "0.1.1"
reqwest = "0.11.20"
reqwest = "0.12.4"
serde_json = "1.0.108"
tempfile = "3.3.0"
tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros"] }

View File

@@ -713,16 +713,11 @@ impl CustomResponder {
impl wiremock::Respond for &CustomResponder {
fn respond(&self, request: &wiremock::Request) -> wiremock::ResponseTemplate {
// Convert the mocked request to an actual server request.
let mut req = self.client.request(
request.method.to_string().parse().expect("All methods exist"),
request.url.clone(),
);
for header in &request.headers {
for value in header.1 {
req = req.header(header.0.to_string(), value.to_string());
}
}
req = req.body(request.body.clone());
let req = self
.client
.request(request.method.clone(), request.url.clone())
.headers(request.headers.clone())
.body(request.body.clone());
// Run await inside of non-async fn by spawning a new thread and creating a new
// runtime. We need to do this because the current runtime can't run blocking