From b484d880234588f572ae48cd9d7d501165f5b251 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Thu, 19 Dec 2024 17:37:12 +0100 Subject: [PATCH] feat(client): use max http version of client by default instead of http 1.1 --- client/src/middleware/redirect.rs | 17 +++++++++++++++-- client/src/request.rs | 10 +++++++++- client/src/service.rs | 10 ++++++++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/client/src/middleware/redirect.rs b/client/src/middleware/redirect.rs index 5f85e713..289c9956 100644 --- a/client/src/middleware/redirect.rs +++ b/client/src/middleware/redirect.rs @@ -28,12 +28,25 @@ where type Error = Error; async fn call(&self, req: ServiceRequest<'r, 'c>) -> Result { - let ServiceRequest { req, client, timeout } = req; + let ServiceRequest { + req, + client, + timeout, + version, + } = req; let mut headers = req.headers().clone(); let mut method = req.method().clone(); let mut uri = req.uri().clone(); loop { - let mut res = self.service.call(ServiceRequest { req, client, timeout }).await?; + let mut res = self + .service + .call(ServiceRequest { + req, + client, + timeout, + version, + }) + .await?; match res.status() { StatusCode::MOVED_PERMANENTLY | StatusCode::FOUND | StatusCode::SEE_OTHER => { if method != Method::HEAD { diff --git a/client/src/request.rs b/client/src/request.rs index c45df7d6..64f7a411 100644 --- a/client/src/request.rs +++ b/client/src/request.rs @@ -19,6 +19,7 @@ use crate::{ /// builder type for [http::Request] with extended functionalities. pub struct RequestBuilder<'a, M = marker::Http> { pub(crate) req: http::Request, + version: Option, err: Vec, client: &'a Client, timeout: Duration, @@ -101,6 +102,7 @@ impl<'a, M> RequestBuilder<'a, M> { { Self { req: req.map(BoxBody::new), + version: None, err: Vec::new(), client, timeout: client.timeout_config.request_timeout, @@ -111,6 +113,7 @@ impl<'a, M> RequestBuilder<'a, M> { pub(crate) fn mutate_marker(self) -> RequestBuilder<'a, M2> { RequestBuilder { req: self.req, + version: self.version, err: self.err, client: self.client, timeout: self.timeout, @@ -122,6 +125,7 @@ impl<'a, M> RequestBuilder<'a, M> { pub(crate) async fn _send(self) -> Result { let Self { mut req, + version, err, client, timeout, @@ -136,6 +140,7 @@ impl<'a, M> RequestBuilder<'a, M> { .service .call(ServiceRequest { req: &mut req, + version, client, timeout, }) @@ -172,7 +177,9 @@ impl<'a, M> RequestBuilder<'a, M> { /// Set HTTP version of this request. /// - /// By default request's HTTP version depends on network stream + /// By default request's HTTP version will use the maximum version supported by the client. + /// If the network does not support the version, the client will downgrade to the highest + /// version supported by the network. /// /// # Panic /// - when received a version beyond the range crate is able to handle. @@ -195,6 +202,7 @@ impl<'a, M> RequestBuilder<'a, M> { /// ``` pub fn version(mut self, version: Version) -> Self { crate::builder::version_check(version); + self.version = Some(version); *self.req.version_mut() = version; self } diff --git a/client/src/service.rs b/client/src/service.rs index 0751f7c3..5588ffae 100644 --- a/client/src/service.rs +++ b/client/src/service.rs @@ -66,6 +66,7 @@ where /// [RequestBuilder]: crate::request::RequestBuilder pub struct ServiceRequest<'r, 'c> { pub req: &'r mut Request, + pub version: Option, pub client: &'c Client, pub timeout: Duration, } @@ -85,14 +86,19 @@ pub(crate) fn base_service() -> HttpService { #[cfg(any(feature = "http1", feature = "http2", feature = "http3"))] use crate::{error::TimeoutError, timeout::Timeout}; - let ServiceRequest { req, client, timeout } = req; + let ServiceRequest { + req, + version, + client, + timeout, + } = req; let uri = Uri::try_parse(req.uri())?; // temporary version to record possible version downgrade/upgrade happens when making connections. // alpn protocol and alt-svc header are possible source of version change. #[allow(unused_mut)] - let mut version = req.version(); + let mut version = version.unwrap_or(client.max_http_version); let mut connect = Connect::new(uri);