diff options
| author | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2024-10-16 10:40:36 +0200 |
|---|---|---|
| committer | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2024-10-16 10:40:36 +0200 |
| commit | 0b6e0873b6d997cf9c488251e09b7943b40ae831 (patch) | |
| tree | bcbabb3658fef51f93a7889f874733893b46a8f6 | |
| parent | 9aa62fb7b1834ad4e98139e54c388999c9f942c6 (diff) | |
| parent | 74b278a2a1538a4931f6a8afc606947e82f84e9b (diff) | |
| download | mullvadvpn-0b6e0873b6d997cf9c488251e09b7943b40ae831.tar.xz mullvadvpn-0b6e0873b6d997cf9c488251e09b7943b40ae831.zip | |
Merge branch 'hyper-1'
| -rw-r--r-- | Cargo.lock | 203 | ||||
| -rw-r--r-- | Cargo.toml | 4 | ||||
| -rw-r--r-- | mullvad-api/Cargo.toml | 11 | ||||
| -rw-r--r-- | mullvad-api/src/abortable_stream.rs | 2 | ||||
| -rw-r--r-- | mullvad-api/src/https_client_with_sni.rs | 13 | ||||
| -rw-r--r-- | mullvad-api/src/lib.rs | 3 | ||||
| -rw-r--r-- | mullvad-api/src/proxy.rs | 21 | ||||
| -rw-r--r-- | mullvad-api/src/relay_list.rs | 4 | ||||
| -rw-r--r-- | mullvad-api/src/rest.rs | 262 | ||||
| -rw-r--r-- | mullvad-api/src/tls_stream.rs | 23 | ||||
| -rw-r--r-- | mullvad-daemon/src/geoip.rs | 2 | ||||
| -rw-r--r-- | test/Cargo.lock | 399 | ||||
| -rw-r--r-- | test/Cargo.toml | 2 | ||||
| -rw-r--r-- | test/connection-checker/Cargo.toml | 2 | ||||
| -rw-r--r-- | test/test-rpc/src/net.rs | 10 |
15 files changed, 519 insertions, 442 deletions
diff --git a/Cargo.lock b/Cargo.lock index 3a3bd52289..994944c41c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -234,7 +234,7 @@ dependencies = [ "bytes", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body", "http-body-util", "itoa", "matchit", @@ -244,8 +244,8 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper", - "tower", + "sync_wrapper 1.0.1", + "tower 0.4.13", "tower-layer", "tower-service", ] @@ -260,12 +260,12 @@ dependencies = [ "bytes", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper", + "sync_wrapper 1.0.1", "tower-layer", "tower-service", ] @@ -412,9 +412,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.95" +version = "1.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" +checksum = "3bbb537bb4a30b90362caddba8f360c0a56bc13d3a5570028e7197204cb54a17" +dependencies = [ + "shlex", +] [[package]] name = "cesu8" @@ -1355,13 +1358,13 @@ dependencies = [ "ipnet", "once_cell", "rand 0.8.5", - "rustls", - "rustls-pemfile", + "rustls 0.21.11", + "rustls-pemfile 1.0.4", "serde", "thiserror", "tinyvec", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tracing", "url", ] @@ -1381,12 +1384,12 @@ dependencies = [ "parking_lot", "rand 0.8.5", "resolv-conf", - "rustls", + "rustls 0.21.11", "serde", "smallvec", "thiserror", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tracing", ] @@ -1486,17 +1489,6 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" @@ -1507,14 +1499,14 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body", "pin-project-lite", ] @@ -1547,29 +1539,6 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" @@ -1579,7 +1548,7 @@ dependencies = [ "futures-util", "h2 0.4.4", "http 1.1.0", - "http-body 1.0.0", + "http-body", "httparse", "httpdate", "itoa", @@ -1595,7 +1564,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "hyper 1.4.1", + "hyper", "hyper-util", "pin-project-lite", "tokio", @@ -1604,20 +1573,19 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", - "hyper 1.4.1", + "http-body", + "hyper", "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] @@ -2353,14 +2321,16 @@ dependencies = [ "cbindgen", "chrono", "futures", - "http 0.2.12", - "hyper 0.14.28", + "http 1.1.0", + "http-body-util", + "hyper", + "hyper-util", "ipnetwork", "libc", "log", "mullvad-fs", "mullvad-types", - "rustls-pemfile", + "rustls-pemfile 2.1.3", "serde", "serde_json", "shadowsocks", @@ -2368,8 +2338,9 @@ dependencies = [ "talpid-types", "thiserror", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.0", "tokio-socks", + "tower 0.5.1", "uuid", ] @@ -2447,7 +2418,7 @@ dependencies = [ "env_logger 0.10.2", "hickory-resolver", "log", - "rustls", + "rustls 0.21.11", "tokio", "webpki-roots", ] @@ -2486,7 +2457,7 @@ dependencies = [ "talpid-types", "tokio", "tonic", - "tower", + "tower 0.5.1", "tunnel-obfuscation", ] @@ -2530,7 +2501,7 @@ dependencies = [ "tokio", "tonic", "tonic-build", - "tower", + "tower 0.5.1", ] [[package]] @@ -3624,11 +3595,26 @@ checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] [[package]] +name = "rustls" +version = "0.23.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + +[[package]] name = "rustls-pemfile" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3638,6 +3624,22 @@ dependencies = [ ] [[package]] +name = "rustls-pemfile" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +dependencies = [ + "base64 0.22.0", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" + +[[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3648,6 +3650,17 @@ dependencies = [ ] [[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] name = "rustversion" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3871,7 +3884,7 @@ dependencies = [ "futures", "http-body-util", "httparse", - "hyper 1.4.1", + "hyper", "idna 1.0.2", "ipnet", "iprange", @@ -3910,6 +3923,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" [[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] name = "signal-hook-registry" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4060,6 +4079,12 @@ dependencies = [ [[package]] name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" @@ -4234,7 +4259,7 @@ dependencies = [ "tokio", "tonic", "tonic-build", - "tower", + "tower 0.5.1", "winapi", "windows-sys 0.52.0", "winres", @@ -4316,7 +4341,7 @@ dependencies = [ "tokio", "tonic", "tonic-build", - "tower", + "tower 0.5.1", "windows-sys 0.52.0", "zeroize", ] @@ -4510,7 +4535,18 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.11", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls 0.23.13", + "rustls-pki-types", "tokio", ] @@ -4604,9 +4640,9 @@ dependencies = [ "bytes", "h2 0.4.4", "http 1.1.0", - "http-body 1.0.0", + "http-body", "http-body-util", - "hyper 1.4.1", + "hyper", "hyper-timeout", "hyper-util", "percent-encoding", @@ -4615,7 +4651,7 @@ dependencies = [ "socket2", "tokio", "tokio-stream", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -4655,16 +4691,30 @@ dependencies = [ ] [[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + +[[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -4672,7 +4722,6 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", diff --git a/Cargo.toml b/Cargo.toml index 32757afc78..3817c32040 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,10 +72,10 @@ futures = "0.3.15" # Tonic and related crates tonic = "0.12.3" tonic-build = { version = "0.10.0", default-features = false } -tower = "0.4" +tower = { version = "0.5.1", features = ["util"] } prost = "0.13.3" prost-types = "0.13.3" -hyper-util = "0.1.8" +hyper-util = {version = "0.1.8", features = ["client", "client-legacy", "http2"]} env_logger = "0.10.0" thiserror = "1.0.57" diff --git a/mullvad-api/Cargo.toml b/mullvad-api/Cargo.toml index fe29981069..ebb456ad6f 100644 --- a/mullvad-api/Cargo.toml +++ b/mullvad-api/Cargo.toml @@ -19,16 +19,19 @@ libc = "0.2" chrono = { workspace = true } thiserror = { workspace = true } futures = { workspace = true } -http = "0.2" -hyper = { version = "0.14", features = ["client", "stream", "http1", "tcp" ] } +http = "1.1.0" +hyper = { version = "1.4.1", features = ["client", "http1"] } +hyper-util = { workspace = true} +http-body-util = "0.1.2" +tower = { workspace = true } ipnetwork = { workspace = true } log = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true, features = ["macros", "time", "rt-multi-thread", "net", "io-std", "io-util", "fs"] } -tokio-rustls = "0.24.1" +tokio-rustls = { version = "0.26.0", features = ["logging", "tls12", "ring"], default-features = false} tokio-socks = "0.5.1" -rustls-pemfile = "1.0.3" +rustls-pemfile = "2.1.3" mullvad-fs = { path = "../mullvad-fs" } mullvad-types = { path = "../mullvad-types" } diff --git a/mullvad-api/src/abortable_stream.rs b/mullvad-api/src/abortable_stream.rs index 0258a7e650..331505de5d 100644 --- a/mullvad-api/src/abortable_stream.rs +++ b/mullvad-api/src/abortable_stream.rs @@ -2,7 +2,7 @@ //! immediately instead of after the socket times out. use futures::{channel::oneshot, future::Fuse, FutureExt}; -use hyper::client::connect::{Connected, Connection}; +use hyper_util::client::legacy::connect::{Connected, Connection}; use std::{ future::Future, io, diff --git a/mullvad-api/src/https_client_with_sni.rs b/mullvad-api/src/https_client_with_sni.rs index afd044aa30..574d0a6309 100644 --- a/mullvad-api/src/https_client_with_sni.rs +++ b/mullvad-api/src/https_client_with_sni.rs @@ -8,10 +8,10 @@ use futures::{channel::mpsc, future, pin_mut, StreamExt}; #[cfg(target_os = "android")] use futures::{channel::oneshot, sink::SinkExt}; use http::uri::Scheme; -use hyper::{ - client::connect::dns::{GaiResolver, Name}, - service::Service, - Uri, +use hyper::Uri; +use hyper_util::{ + client::legacy::connect::dns::{GaiResolver, Name}, + rt::TokioIo, }; use shadowsocks::{ config::ServerType, @@ -39,6 +39,7 @@ use tokio::{ net::{TcpSocket, TcpStream}, time::timeout, }; +use tower::Service; #[cfg(feature = "api-override")] use crate::{proxy::ConnectionDecorator, API}; @@ -407,7 +408,7 @@ impl fmt::Debug for HttpsConnectorWithSni { } impl Service<Uri> for HttpsConnectorWithSni { - type Response = AbortableStream<ApiConnection>; + type Response = TokioIo<AbortableStream<ApiConnection>>; type Error = io::Error; type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>; @@ -472,7 +473,7 @@ impl Service<Uri> for HttpsConnectorWithSni { inner.stream_handles.push(socket_handle); } - Ok(stream) + Ok(TokioIo::new(stream)) }; Box::pin(fut) diff --git a/mullvad-api/src/lib.rs b/mullvad-api/src/lib.rs index fc731ee6ea..6b3ac3c951 100644 --- a/mullvad-api/src/lib.rs +++ b/mullvad-api/src/lib.rs @@ -1,7 +1,6 @@ #![allow(rustdoc::private_intra_doc_links)] #[cfg(target_os = "android")] use futures::channel::mpsc; -use hyper::Method; #[cfg(target_os = "android")] use mullvad_types::account::{PlayPurchase, PlayPurchasePaymentToken}; use mullvad_types::{ @@ -710,7 +709,7 @@ impl AppVersionProxy { let service = self.handle.service.clone(); let path = format!("{APP_URL_PREFIX}/releases/{platform}/{app_version}"); - let request = self.handle.factory.request(&path, Method::GET); + let request = self.handle.factory.get(&path); async move { let request = request? diff --git a/mullvad-api/src/proxy.rs b/mullvad-api/src/proxy.rs index 0915d1d23c..2fb2c4bf35 100644 --- a/mullvad-api/src/proxy.rs +++ b/mullvad-api/src/proxy.rs @@ -1,4 +1,4 @@ -use hyper::client::connect::Connected; +use hyper_util::client::legacy::connect::{Connected, Connection}; use serde::{Deserialize, Serialize}; use std::{ fmt, io, @@ -192,7 +192,7 @@ impl ApiConnectionMode { } } -/// Implements `hyper::client::connect::Connection` by wrapping a type. +/// Implements `Connection` by wrapping a type. pub struct ConnectionDecorator<T: AsyncRead + AsyncWrite>(pub T); impl<T: AsyncRead + AsyncWrite + Unpin> AsyncRead for ConnectionDecorator<T> { @@ -223,26 +223,21 @@ impl<T: AsyncRead + AsyncWrite + Unpin> AsyncWrite for ConnectionDecorator<T> { } } -impl<T: AsyncRead + AsyncWrite> hyper::client::connect::Connection for ConnectionDecorator<T> { +impl<T: AsyncRead + AsyncWrite> Connection for ConnectionDecorator<T> { fn connected(&self) -> Connected { Connected::new() } } -trait Connection: AsyncRead + AsyncWrite + Unpin + hyper::client::connect::Connection + Send {} +trait ConnectionMullvad: AsyncRead + AsyncWrite + Unpin + Connection + Send {} -impl<T: AsyncRead + AsyncWrite + Unpin + hyper::client::connect::Connection + Send> Connection - for T -{ -} +impl<T: AsyncRead + AsyncWrite + Unpin + Connection + Send> ConnectionMullvad for T {} /// Stream that represents a Mullvad API connection -pub struct ApiConnection(Box<dyn Connection>); +pub struct ApiConnection(Box<dyn ConnectionMullvad>); impl ApiConnection { - pub fn new< - T: AsyncRead + AsyncWrite + Unpin + hyper::client::connect::Connection + Send + 'static, - >( + pub fn new<T: AsyncRead + AsyncWrite + Unpin + Connection + Send + 'static>( conn: Box<T>, ) -> Self { Self(conn) @@ -277,7 +272,7 @@ impl AsyncWrite for ApiConnection { } } -impl hyper::client::connect::Connection for ApiConnection { +impl Connection for ApiConnection { fn connected(&self) -> Connected { self.0.connected() } diff --git a/mullvad-api/src/relay_list.rs b/mullvad-api/src/relay_list.rs index 5f2b2d6d81..f1375b5f6f 100644 --- a/mullvad-api/src/relay_list.rs +++ b/mullvad-api/src/relay_list.rs @@ -2,7 +2,7 @@ use crate::rest; -use hyper::{header, Method, StatusCode}; +use hyper::{header, StatusCode}; use mullvad_types::{location, relay_list}; use talpid_types::net::wireguard; @@ -34,7 +34,7 @@ impl RelayListProxy { etag: Option<String>, ) -> impl Future<Output = Result<Option<relay_list::RelayList>, rest::Error>> { let service = self.handle.service.clone(); - let request = self.handle.factory.request("app/v1/relays", Method::GET); + let request = self.handle.factory.get("app/v1/relays"); async move { let mut request = request? diff --git a/mullvad-api/src/rest.rs b/mullvad-api/src/rest.rs index c8df2aea8e..f6098c3b49 100644 --- a/mullvad-api/src/rest.rs +++ b/mullvad-api/src/rest.rs @@ -11,14 +11,17 @@ use futures::{ channel::{mpsc, oneshot}, stream::StreamExt, }; +use http_body_util::{combinators::BoxBody, BodyExt, Empty, Full}; use hyper::{ - client::{connect::Connect, Client}, + body::{Body, Bytes, Incoming}, header::{self, HeaderValue}, Method, Uri, }; +use hyper_util::client::legacy::connect::Connect; use mullvad_types::account::AccountNumber; use std::{ borrow::Cow, + convert::Infallible, error::Error as StdError, str::FromStr, sync::{Arc, Weak}, @@ -42,6 +45,9 @@ pub enum Error { #[error("Request cancelled")] Aborted, + #[error("Legacy hyper error")] + LegacyHyperError(#[from] Arc<hyper_util::client::legacy::Error>), + #[error("Hyper error")] HyperError(#[from] Arc<hyper::Error>), @@ -62,22 +68,31 @@ pub enum Error { ApiError(StatusCode, String), /// The string given was not a valid URI. - #[error("Not a valid URI")] - InvalidUri, + #[error("Not a valid URI {0}")] + InvalidUri(#[from] Arc<http::uri::InvalidUri>), #[error("Set account number on factory with no access token store")] NoAccessTokenStore, } +impl From<Infallible> for Error { + fn from(_: Infallible) -> Self { + unreachable!() + } +} + impl Error { pub fn is_network_error(&self) -> bool { - matches!(self, Error::HyperError(_) | Error::TimeoutError) + matches!( + self, + Error::HyperError(_) | Error::LegacyHyperError(_) | Error::TimeoutError + ) } /// Return true if there was no route to the destination pub fn is_offline(&self) -> bool { match self { - Error::HyperError(error) if error.is_connect() => { + Error::LegacyHyperError(error) if error.is_connect() => { if let Some(cause) = error.source() { if let Some(err) = cause.downcast_ref::<std::io::Error>() { return err.raw_os_error() == Some(libc::ENETUNREACH); @@ -85,6 +100,9 @@ impl Error { } false } + // TODO: Currently, we use the legacy hyper client for all REST requests. If this + // changes in the future, we likely need to match on `Error::HyperError` here and + // determine how to achieve the equivalent behavior. See DES-1288. _ => false, } } @@ -113,13 +131,17 @@ impl Error { } } +// TODO: Look into an alternative to using the legacy hyper client `DES-1288` +type RequestClient = + hyper_util::client::legacy::Client<HttpsConnectorWithSni, BoxBody<Bytes, Error>>; + /// A service that executes HTTP requests, allowing for on-demand termination of all in-flight /// requests pub(crate) struct RequestService<T: ConnectionModeProvider> { command_tx: Weak<mpsc::UnboundedSender<RequestCommand>>, command_rx: mpsc::UnboundedReceiver<RequestCommand>, connector_handle: HttpsConnectorWithSniHandle, - client: hyper::Client<HttpsConnectorWithSni, hyper::Body>, + client: RequestClient, connection_mode_provider: T, connection_mode_generation: usize, api_availability: ApiAvailability, @@ -144,7 +166,9 @@ impl<T: ConnectionModeProvider + 'static> RequestService<T> { connector_handle.set_connection_mode(connection_mode_provider.initial()); let (command_tx, command_rx) = mpsc::unbounded(); - let client = Client::builder().build(connector); + let client = + hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()) + .build(connector); let command_tx = Arc::new(command_tx); @@ -203,13 +227,15 @@ impl<T: ConnectionModeProvider + 'static> RequestService<T> { fn handle_new_request( &mut self, - request: Request, - completion_tx: oneshot::Sender<Result<Response>>, + request: Request<BoxBody<Bytes, Error>>, + completion_tx: oneshot::Sender<Result<Response<Incoming>>>, ) { let tx = self.command_tx.upgrade(); let api_availability = self.api_availability.clone(); - let request_future = request.into_future(self.client.clone(), api_availability.clone()); + let request_future = request + .map(|r| http::Request::map(r, BodyExt::boxed)) + .into_future(self.client.clone(), api_availability.clone()); let connection_mode_generation = self.connection_mode_generation; @@ -246,8 +272,14 @@ impl RequestServiceHandle { } /// Submits a `RestRequest` for execution to the request service. - pub async fn request(&self, request: Request) -> Result<Response> { + pub async fn request<B>(&self, request: Request<B>) -> Result<Response<Incoming>> + where + B: Body + Send + Sync + 'static, + Error: From<B::Error>, + Bytes: From<B::Data>, + { let (completion_tx, completion_rx) = oneshot::channel(); + let request = request.map(|r| r.map(box_body)); self.tx .unbounded_send(RequestCommand::NewRequest(request, completion_tx)) .map_err(|_| Error::RestServiceDown)?; @@ -258,8 +290,8 @@ impl RequestServiceHandle { #[derive(Debug)] pub(crate) enum RequestCommand { NewRequest( - Request, - oneshot::Sender<std::result::Result<Response, Error>>, + Request<BoxBody<Bytes, Error>>, + oneshot::Sender<std::result::Result<Response<Incoming>, Error>>, ), Reset, NextApiConfig(usize), @@ -267,38 +299,36 @@ pub(crate) enum RequestCommand { /// A REST request that is sent to the RequestService to be executed. #[derive(Debug)] -pub struct Request { - request: hyper::Request<hyper::Body>, +pub struct Request<B> { + request: hyper::Request<B>, timeout: Duration, access_token_store: Option<AccessTokenStore>, account: Option<AccountNumber>, expected_status: &'static [hyper::StatusCode], } -impl Request { - /// Constructs a GET request with the given URI. Returns an error if the URI is not valid. - pub fn get(uri: &str) -> Result<Self> { - let uri = hyper::Uri::from_str(uri).map_err(|_| Error::InvalidUri)?; +// TODO: merge with `RequestFactory::get` +/// Constructs a GET request with the given URI. Returns an error if the URI is not valid. +pub fn get(uri: &str) -> Result<Request<Empty<Bytes>>> { + let uri = hyper::Uri::from_str(uri)?; - let mut builder = http::request::Builder::new() - .method(Method::GET) - .header(header::USER_AGENT, HeaderValue::from_static(USER_AGENT)) - .header(header::ACCEPT, HeaderValue::from_static("application/json")); - if let Some(host) = uri.host() { - builder = builder.header( - header::HOST, - HeaderValue::from_str(host).map_err(|_| Error::InvalidHeaderError)?, - ); - }; + let mut builder = http::request::Builder::new() + .method(Method::GET) + .header(header::USER_AGENT, HeaderValue::from_static(USER_AGENT)) + .header(header::ACCEPT, HeaderValue::from_static("application/json")); + if let Some(host) = uri.host() { + builder = builder.header( + header::HOST, + HeaderValue::from_str(host).map_err(|_e| Error::InvalidHeaderError)?, + ); + }; - let request = builder.uri(uri).body(hyper::Body::empty())?; - Ok(Self::new(request, None)) - } + let request = builder.uri(uri).body(Empty::<Bytes>::new())?; + Ok(Request::new(request, None)) +} - fn new( - request: hyper::Request<hyper::Body>, - access_token_store: Option<AccessTokenStore>, - ) -> Self { +impl<B: Body> Request<B> { + fn new(request: hyper::Request<B>, access_token_store: Option<AccessTokenStore>) -> Self { Self { request, timeout: DEFAULT_TIMEOUT, @@ -336,11 +366,64 @@ impl Request { Ok(self) } + /// Returns the URI of the request + pub fn uri(&self) -> &Uri { + self.request.uri() + } +} +impl<B> Request<B> { + /// Map the underlying [`hyper::Request`] type + fn map<F, B2>(self, f: F) -> Request<B2> + where + F: FnOnce(hyper::Request<B>) -> hyper::Request<B2>, + { + Request { + request: f(self.request), + timeout: self.timeout, + access_token_store: self.access_token_store, + account: self.account, + expected_status: self.expected_status, + } + } +} + +fn box_body<B>(body: B) -> BoxBody<Bytes, Error> +where + B: Body + Send + Sync + 'static, + Error: From<B::Error>, + Bytes: From<B::Data>, +{ + try_downcast(body).unwrap_or_else(|body| { + body.map_frame(|frame| frame.map_data(Bytes::from)) + .map_err(Error::from) + .boxed() + }) +} + +pub(crate) fn try_downcast<T, K>(k: K) -> core::result::Result<T, K> +where + T: 'static, + K: Send + 'static, +{ + let mut k = Some(k); + if let Some(k) = <dyn std::any::Any>::downcast_mut::<Option<T>>(&mut k) { + Ok(k.take().unwrap()) + } else { + Err(k.unwrap()) + } +} + +impl<B> Request<B> +where + B: Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into<Box<dyn StdError + Send + Sync>>, +{ async fn into_future<C: Connect + Clone + Send + Sync + 'static>( self, - hyper_client: hyper::Client<C>, + hyper_client: hyper_util::client::legacy::Client<C, B>, api_availability: ApiAvailability, - ) -> Result<Response> { + ) -> Result<Response<Incoming>> { let timeout = self.timeout; let inner_fut = self.into_future_without_timeout(hyper_client, api_availability); tokio::time::timeout(timeout, inner_fut) @@ -348,11 +431,14 @@ impl Request { .map_err(|_| Error::TimeoutError)? } - async fn into_future_without_timeout<C: Connect + Clone + Send + Sync + 'static>( + async fn into_future_without_timeout<C>( mut self, - hyper_client: hyper::Client<C>, + hyper_client: hyper_util::client::legacy::Client<C, B>, api_availability: ApiAvailability, - ) -> Result<Response> { + ) -> Result<Response<Incoming>> + where + C: Connect + Clone + Send + Sync + 'static, + { let _ = api_availability.wait_for_unsuspend().await; // Obtain access token first @@ -399,21 +485,19 @@ impl Request { Ok(Response::new(response)) } - - /// Returns the URI of the request - pub fn uri(&self) -> &Uri { - self.request.uri() - } } /// Successful result of a REST request #[derive(Debug)] -pub struct Response { - response: hyper::Response<hyper::Body>, +pub struct Response<B> { + response: hyper::Response<B>, } -impl Response { - fn new(response: hyper::Response<hyper::Body>) -> Self { +impl<B: Body> Response<B> +where + Error: From<<B as Body>::Error>, +{ + fn new(response: hyper::Response<B>) -> Self { Self { response } } @@ -426,8 +510,7 @@ impl Response { } pub async fn deserialize<T: serde::de::DeserializeOwned>(self) -> Result<T> { - let body_length = get_body_length(&self.response); - deserialize_body_inner(self.response, body_length).await + deserialize_body_inner(self.response).await } } @@ -462,38 +545,46 @@ impl RequestFactory { } } - pub fn request(&self, path: &str, method: Method) -> Result<Request> { + pub fn request<B: Body + Default>(&self, path: &str, method: Method) -> Result<Request<B>> { Ok( Request::new(self.hyper_request(path, method)?, self.token_store.clone()) .timeout(self.default_timeout), ) } - pub fn get(&self, path: &str) -> Result<Request> { + pub fn get(&self, path: &str) -> Result<Request<Empty<Bytes>>> { self.request(path, Method::GET) } - pub fn post(&self, path: &str) -> Result<Request> { + pub fn post(&self, path: &str) -> Result<Request<Empty<Bytes>>> { self.request(path, Method::POST) } - pub fn put(&self, path: &str) -> Result<Request> { + pub fn put(&self, path: &str) -> Result<Request<Empty<Bytes>>> { self.request(path, Method::PUT) } - pub fn delete(&self, path: &str) -> Result<Request> { + pub fn delete(&self, path: &str) -> Result<Request<Empty<Bytes>>> { self.request(path, Method::DELETE) } - pub fn head(&self, path: &str) -> Result<Request> { + pub fn head(&self, path: &str) -> Result<Request<Empty<Bytes>>> { self.request(path, Method::HEAD) } - pub fn post_json<S: serde::Serialize>(&self, path: &str, body: &S) -> Result<Request> { + pub fn post_json<S: serde::Serialize>( + &self, + path: &str, + body: &S, + ) -> Result<Request<Full<Bytes>>> { self.json_request(Method::POST, path, body) } - pub fn put_json<S: serde::Serialize>(&self, path: &str, body: &S) -> Result<Request> { + pub fn put_json<S: serde::Serialize>( + &self, + path: &str, + body: &S, + ) -> Result<Request<Full<Bytes>>> { self.json_request(Method::PUT, path, body) } @@ -501,18 +592,17 @@ impl RequestFactory { self.default_timeout = timeout; self } - fn json_request<S: serde::Serialize>( &self, method: Method, path: &str, body: &S, - ) -> Result<Request> { + ) -> Result<Request<Full<Bytes>>> { let mut request = self.hyper_request(path, method)?; - let json_body = serde_json::to_string(&body)?; - let body_length = json_body.as_bytes().len(); - *request.body_mut() = json_body.into_bytes().into(); + let json_body = serde_json::to_vec(&body)?; + let body_length = json_body.len(); + *request.body_mut() = Full::new(Bytes::from(json_body)); let headers = request.headers_mut(); headers.insert(header::CONTENT_LENGTH, HeaderValue::from(body_length)); @@ -524,7 +614,7 @@ impl RequestFactory { Ok(Request::new(request, self.token_store.clone()).timeout(self.default_timeout)) } - fn hyper_request(&self, path: &str, method: Method) -> Result<hyper::Request<hyper::Body>> { + fn hyper_request<B: Default>(&self, path: &str, method: Method) -> Result<http::Request<B>> { let uri = self.get_uri(path)?; let request = http::request::Builder::new() .method(method) @@ -536,17 +626,17 @@ impl RequestFactory { HeaderValue::from_str(&self.hostname).map_err(|_| Error::InvalidHeaderError)?, ); - let result = request.body(hyper::Body::empty())?; + let result = request.body(B::default())?; Ok(result) } fn get_uri(&self, path: &str) -> Result<Uri> { let uri = format!("https://{}/{}", self.hostname, path); - hyper::Uri::from_str(&uri).map_err(|_| Error::InvalidUri) + Ok(hyper::Uri::from_str(&uri)?) } } -fn get_body_length(response: &hyper::Response<hyper::Body>) -> usize { +fn get_body_length<B>(response: &hyper::Response<B>) -> usize { response .headers() .get(header::CONTENT_LENGTH) @@ -555,20 +645,22 @@ fn get_body_length(response: &hyper::Response<hyper::Body>) -> usize { .unwrap_or(0) } -async fn handle_error_response<T>(response: hyper::Response<hyper::Body>) -> Result<T> { +async fn handle_error_response<T, B: Body>(response: hyper::Response<B>) -> Result<T> +where + Error: From<B::Error>, +{ let status = response.status(); let error_message = match status { hyper::StatusCode::METHOD_NOT_ALLOWED => "Method not allowed", status => match get_body_length(&response) { 0 => status.canonical_reason().unwrap_or("Unexpected error"), - body_length => { + _length => { return match response.headers().get("content-type") { Some(content_type) if content_type == "application/problem+json" => { // TODO: We should make sure we unify the new error format and the old // error format so that they both produce the same Errors for the same // problems after being processed. - let err: NewErrorResponse = - deserialize_body_inner(response, body_length).await?; + let err: NewErrorResponse = deserialize_body_inner(response).await?; // The new error type replaces the `code` field with the `type` field. // This is what is used to programmatically check the error. Err(Error::ApiError( @@ -578,8 +670,7 @@ async fn handle_error_response<T>(response: hyper::Response<hyper::Body>) -> Res )) } _ => { - let err: OldErrorResponse = - deserialize_body_inner(response, body_length).await?; + let err: OldErrorResponse = deserialize_body_inner(response).await?; Err(Error::ApiError(status, err.code)) } }; @@ -589,16 +680,17 @@ async fn handle_error_response<T>(response: hyper::Response<hyper::Body>) -> Res Err(Error::ApiError(status, error_message.to_owned())) } -async fn deserialize_body_inner<T: serde::de::DeserializeOwned>( - mut response: hyper::Response<hyper::Body>, - body_length: usize, -) -> Result<T> { - let mut body: Vec<u8> = Vec::with_capacity(body_length); - while let Some(chunk) = response.body_mut().next().await { - body.extend(&chunk?); - } +async fn deserialize_body_inner<T, B>(response: hyper::Response<B>) -> Result<T> +where + T: serde::de::DeserializeOwned, + B: Body, + Error: From<B::Error>, +{ + use http_body_util::BodyExt; - serde_json::from_slice(&body).map_err(Error::from) + let collected = BodyExt::collect(response).await?; + let res = serde_json::from_slice(&collected.to_bytes())?; + Ok(res) } #[derive(Clone)] @@ -637,5 +729,7 @@ macro_rules! impl_into_arc_err { } impl_into_arc_err!(hyper::Error); +impl_into_arc_err!(hyper_util::client::legacy::Error); impl_into_arc_err!(serde_json::Error); impl_into_arc_err!(http::Error); +impl_into_arc_err!(http::uri::InvalidUri); diff --git a/mullvad-api/src/tls_stream.rs b/mullvad-api/src/tls_stream.rs index bf4ff336f5..b36de484e8 100644 --- a/mullvad-api/src/tls_stream.rs +++ b/mullvad-api/src/tls_stream.rs @@ -6,11 +6,11 @@ use std::{ task::{self, Poll}, }; -use hyper::client::connect::{Connected, Connection}; +use hyper_util::client::legacy::connect::{Connected, Connection}; use std::sync::LazyLock; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_rustls::{ - rustls::{self, ClientConfig, ServerName}, + rustls::{self, pki_types::ServerName, ClientConfig}, TlsConnector, }; @@ -26,19 +26,19 @@ where { pub async fn connect_https(stream: S, domain: &str) -> io::Result<TlsStream<S>> { static TLS_CONFIG: LazyLock<Arc<ClientConfig>> = LazyLock::new(|| { - let config = ClientConfig::builder() - .with_safe_default_cipher_suites() - .with_safe_default_kx_groups() - .with_protocol_versions(&[&rustls::version::TLS13]) - .unwrap() - .with_root_certificates(read_cert_store()) - .with_no_client_auth(); + let config = ClientConfig::builder_with_provider(Arc::new( + rustls::crypto::ring::default_provider(), + )) + .with_protocol_versions(&[&rustls::version::TLS13]) + .expect("ring crypt-prover should support TLS 1.3") + .with_root_certificates(read_cert_store()) + .with_no_client_auth(); Arc::new(config) }); let connector = TlsConnector::from(TLS_CONFIG.clone()); - let host = match ServerName::try_from(domain) { + let host = match ServerName::try_from(domain.to_owned()) { Ok(n) => n, Err(_) => { return Err(io::Error::new( @@ -58,8 +58,9 @@ fn read_cert_store() -> rustls::RootCertStore { let mut cert_store = rustls::RootCertStore::empty(); let certs = rustls_pemfile::certs(&mut std::io::BufReader::new(LE_ROOT_CERT)) + .collect::<Result<Vec<_>, _>>() .expect("Failed to parse pem file"); - let (num_certs_added, num_failures) = cert_store.add_parsable_certificates(&certs); + let (num_certs_added, num_failures) = cert_store.add_parsable_certificates(certs); if num_failures > 0 || num_certs_added != 1 { panic!("Failed to add root cert"); } diff --git a/mullvad-daemon/src/geoip.rs b/mullvad-daemon/src/geoip.rs index da2fb3e8db..815b83b13f 100644 --- a/mullvad-daemon/src/geoip.rs +++ b/mullvad-daemon/src/geoip.rs @@ -154,7 +154,7 @@ async fn send_location_request_internal( service: RequestServiceHandle, ) -> Result<AmIMullvad, Error> { let future_service = service.clone(); - let request = mullvad_api::rest::Request::get(uri)?; + let request = mullvad_api::rest::get(uri)?; future_service.request(request).await?.deserialize().await } diff --git a/test/Cargo.lock b/test/Cargo.lock index ab73938b6b..6209028fde 100644 --- a/test/Cargo.lock +++ b/test/Cargo.lock @@ -216,8 +216,8 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", "itoa", "matchit", @@ -228,7 +228,7 @@ dependencies = [ "rustversion", "serde", "sync_wrapper 1.0.1", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", ] @@ -242,8 +242,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", "mime", "pin-project-lite", @@ -572,16 +572,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] name = "core-foundation-sys" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -804,15 +794,6 @@ dependencies = [ ] [[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - -[[package]] name = "enum-as-inner" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1142,25 +1123,6 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" @@ -1170,7 +1132,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.1.0", + "http", "indexmap 2.2.6", "slab", "tokio", @@ -1290,17 +1252,6 @@ dependencies = [ [[package]] name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" @@ -1312,23 +1263,12 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http", ] [[package]] @@ -1339,8 +1279,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "pin-project-lite", ] @@ -1364,30 +1304,6 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.6", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" @@ -1395,9 +1311,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", - "http 1.1.0", - "http-body 1.0.1", + "h2", + "http", + "http-body", "httparse", "httpdate", "itoa", @@ -1409,35 +1325,21 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http 0.2.12", - "hyper 0.14.28", - "rustls 0.21.11", - "tokio", - "tokio-rustls 0.24.1", -] - -[[package]] -name = "hyper-rustls" version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http 1.1.0", - "hyper 1.4.1", + "http", + "hyper", "hyper-util", "log", - "rustls 0.23.13", + "rustls", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls", "tower-service", - "webpki-roots 0.26.6", + "webpki-roots", ] [[package]] @@ -1446,7 +1348,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "hyper 1.4.1", + "hyper", "hyper-util", "pin-project-lite", "tokio", @@ -1455,20 +1357,19 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "hyper 1.4.1", + "http", + "http-body", + "hyper", "pin-project-lite", "socket2 0.5.6", "tokio", - "tower", "tower-service", "tracing", ] @@ -1947,14 +1848,16 @@ dependencies = [ "cbindgen", "chrono", "futures", - "http 0.2.12", - "hyper 0.14.28", + "http", + "http-body-util", + "hyper", + "hyper-util", "ipnetwork", "libc", "log", "mullvad-fs", "mullvad-types", - "rustls-pemfile 1.0.4", + "rustls-pemfile", "serde", "serde_json", "shadowsocks", @@ -1962,8 +1865,9 @@ dependencies = [ "talpid-types", "thiserror", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", "tokio-socks", + "tower 0.5.1", "uuid", ] @@ -1996,7 +1900,7 @@ dependencies = [ "tokio", "tonic", "tonic-build", - "tower", + "tower 0.5.1", ] [[package]] @@ -2616,6 +2520,54 @@ dependencies = [ ] [[package]] +name = "quinn" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.5.6", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" +dependencies = [ + "libc", + "once_cell", + "socket2 0.5.6", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] name = "quote" version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2755,20 +2707,21 @@ checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" -version = "0.11.27" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ - "base64 0.21.7", + "base64 0.22.0", "bytes", - "encoding_rs", + "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.28", - "hyper-rustls 0.24.2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", "ipnet", "js-sys", "log", @@ -2776,22 +2729,23 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.11", - "rustls-pemfile 1.0.4", + "quinn", + "rustls", + "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", + "sync_wrapper 1.0.1", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.4", - "winreg", + "webpki-roots", + "windows-registry", ] [[package]] @@ -2851,6 +2805,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + +[[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2874,18 +2834,6 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" @@ -2894,22 +2842,13 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.102.8", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-pemfile" version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" @@ -2926,16 +2865,6 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustls-webpki" version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" @@ -2973,16 +2902,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3316,26 +3235,8 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", + "futures-core", ] [[package]] @@ -3473,7 +3374,7 @@ dependencies = [ "tokio-serial", "tokio-util", "tonic", - "tower", + "tower 0.5.1", "tun", "uuid", ] @@ -3487,17 +3388,17 @@ dependencies = [ "colored", "futures", "http-body-util", - "hyper 1.4.1", - "hyper-rustls 0.27.3", + "hyper", + "hyper-rustls", "hyper-util", "log", - "rustls-pemfile 2.1.3", + "rustls-pemfile", "serde", "serde_json", "tarpc", "thiserror", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls", "tokio-serde", "tokio-util", ] @@ -3654,21 +3555,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.11", - "tokio", -] - -[[package]] -name = "tokio-rustls" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.13", + "rustls", "rustls-pki-types", "tokio", ] @@ -3776,11 +3667,11 @@ dependencies = [ "axum", "base64 0.22.0", "bytes", - "h2 0.4.6", - "http 1.1.0", - "http-body 1.0.1", + "h2", + "http", + "http-body", "http-body-util", - "hyper 1.4.1", + "hyper", "hyper-timeout", "hyper-util", "percent-encoding", @@ -3789,7 +3680,7 @@ dependencies = [ "socket2 0.5.6", "tokio", "tokio-stream", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -3829,16 +3720,30 @@ dependencies = [ ] [[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + +[[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -4130,12 +4035,6 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[package]] -name = "webpki-roots" version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" @@ -4190,6 +4089,26 @@ dependencies = [ ] [[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] name = "windows-service" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4201,6 +4120,16 @@ dependencies = [ ] [[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] name = "windows-sys" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/test/Cargo.toml b/test/Cargo.toml index 52b2e0a5da..8c691719ec 100644 --- a/test/Cargo.toml +++ b/test/Cargo.toml @@ -56,7 +56,7 @@ tokio-serde = { version = "0.8.0", features = ["json"] } # Tonic and related crates tonic = "0.12.3" tonic-build = { version = "0.10.0", default-features = false } -tower = "0.4" +tower = "0.5.1" prost = "0.13.3" prost-types = "0.13.3" tarpc = { version = "0.30", features = ["tokio1", "serde-transport", "serde1"] } diff --git a/test/connection-checker/Cargo.toml b/test/connection-checker/Cargo.toml index a09292e426..730a57ca5a 100644 --- a/test/connection-checker/Cargo.toml +++ b/test/connection-checker/Cargo.toml @@ -15,6 +15,6 @@ clap = { workspace = true, features = ["derive"] } color-eyre = "0.6.2" eyre = "0.6.12" ping = "0.5.2" -reqwest = { version = "0.11.24", default-features = false, features = ["blocking", "rustls-tls", "json"] } +reqwest = { version = "0.12.7", default-features = false, features = ["blocking", "rustls-tls", "json"] } serde = { workspace = true, features = ["derive"] } socket2 = { version = "0.5.4", features = ["all"] } diff --git a/test/test-rpc/src/net.rs b/test/test-rpc/src/net.rs index 4f79aca8d5..4ef3b7cd1e 100644 --- a/test/test-rpc/src/net.rs +++ b/test/test-rpc/src/net.rs @@ -5,13 +5,19 @@ use http_body_util::{BodyExt, Full}; use hyper::Uri; use hyper_util::client::legacy::Client; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::{net::SocketAddr, sync::LazyLock, time::Duration}; +use std::{ + net::SocketAddr, + sync::{Arc, LazyLock}, + time::Duration, +}; use tokio_rustls::rustls::{self, ClientConfig}; const LE_ROOT_CERT: &[u8] = include_bytes!("../../../mullvad-api/le_root_cert.pem"); static CLIENT_CONFIG: LazyLock<ClientConfig> = LazyLock::new(|| { - ClientConfig::builder() + ClientConfig::builder_with_provider(Arc::new(rustls::crypto::ring::default_provider())) + .with_safe_default_protocol_versions() + .unwrap() .with_root_certificates(read_cert_store()) .with_no_client_auth() }); |
