From 9835e2ae736235810b4ea1c162ca5e65c547e770 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:50 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- .../src/client/async_io/bufread_ext.rs | 23 ++++++++-- .../src/client/blocking_io/bufread_ext.rs | 23 ++++++++-- .../src/client/blocking_io/connect.rs | 9 ++-- .../gix-transport/src/client/blocking_io/file.rs | 2 +- .../src/client/blocking_io/http/mod.rs | 51 +++++++++++++--------- .../src/client/blocking_io/http/traits.rs | 2 +- .../src/client/blocking_io/ssh/mod.rs | 1 + .../src/client/blocking_io/ssh/tests.rs | 22 +++++++--- vendor/gix-transport/src/client/capabilities.rs | 2 +- vendor/gix-transport/src/client/non_io_types.rs | 13 ++---- 10 files changed, 97 insertions(+), 51 deletions(-) (limited to 'vendor/gix-transport/src/client') diff --git a/vendor/gix-transport/src/client/async_io/bufread_ext.rs b/vendor/gix-transport/src/client/async_io/bufread_ext.rs index abe206b8a..2b4362fc9 100644 --- a/vendor/gix-transport/src/client/async_io/bufread_ext.rs +++ b/vendor/gix-transport/src/client/async_io/bufread_ext.rs @@ -5,7 +5,7 @@ use std::{ use async_trait::async_trait; use futures_io::{AsyncBufRead, AsyncRead}; -use gix_packetline::PacketLineRef; +use gix_packetline::{read::ProgressAction, PacketLineRef}; use crate::{ client::{Error, MessageKind}, @@ -15,7 +15,7 @@ use crate::{ /// A function `f(is_error, text)` receiving progress or error information. /// As it is not a future itself, it must not block. If IO is performed within the function, be sure to spawn /// it onto an executor. -pub type HandleProgress = Box; +pub type HandleProgress = Box ProgressAction>; /// This trait exists to get a version of a `gix_packetline::Provider` without type parameters, /// but leave support for reading lines directly without forcing them through `String`. @@ -34,6 +34,12 @@ pub trait ReadlineBufRead: AsyncBufRead { async fn readline( &mut self, ) -> Option, gix_packetline::decode::Error>>>; + + /// Read a line similar to `BufRead::read_line()`, but assure it doesn't try to find newlines + /// which might concatenate multiple distinct packet lines. + /// + /// Making this a trait method allows to handle differences between async and blocking. + async fn readline_str(&mut self, line: &mut String) -> io::Result; } /// Provide even more access to the underlying packet reader. @@ -58,6 +64,9 @@ impl<'a, T: ReadlineBufRead + ?Sized + 'a + Unpin> ReadlineBufRead for Box { async fn readline(&mut self) -> Option, gix_packetline::decode::Error>>> { self.deref_mut().readline().await } + async fn readline_str(&mut self, line: &mut String) -> io::Result { + self.deref_mut().readline_str(line).await + } } #[async_trait(?Send)] @@ -80,10 +89,15 @@ impl<'a, T: ExtendedBufRead + ?Sized + 'a + Unpin> ExtendedBufRead for Box { } #[async_trait(?Send)] -impl ReadlineBufRead for gix_packetline::read::WithSidebands<'_, T, for<'b> fn(bool, &'b [u8])> { +impl ReadlineBufRead + for gix_packetline::read::WithSidebands<'_, T, for<'b> fn(bool, &'b [u8]) -> ProgressAction> +{ async fn readline(&mut self) -> Option, gix_packetline::decode::Error>>> { self.read_data_line().await } + async fn readline_str(&mut self, line: &mut String) -> io::Result { + self.read_line_to_string(line).await + } } #[async_trait(?Send)] @@ -91,6 +105,9 @@ impl<'a, T: AsyncRead + Unpin> ReadlineBufRead for gix_packetline::read::WithSid async fn readline(&mut self) -> Option, gix_packetline::decode::Error>>> { self.read_data_line().await } + async fn readline_str(&mut self, line: &mut String) -> io::Result { + self.read_line_to_string(line).await + } } #[async_trait(?Send)] diff --git a/vendor/gix-transport/src/client/blocking_io/bufread_ext.rs b/vendor/gix-transport/src/client/blocking_io/bufread_ext.rs index 5842ddd3d..3513a7fd5 100644 --- a/vendor/gix-transport/src/client/blocking_io/bufread_ext.rs +++ b/vendor/gix-transport/src/client/blocking_io/bufread_ext.rs @@ -3,14 +3,14 @@ use std::{ ops::{Deref, DerefMut}, }; -use gix_packetline::PacketLineRef; +use gix_packetline::{read::ProgressAction, PacketLineRef}; use crate::{ client::{Error, MessageKind}, Protocol, }; /// A function `f(is_error, text)` receiving progress or error information. -pub type HandleProgress = Box; +pub type HandleProgress = Box ProgressAction>; /// This trait exists to get a version of a `gix_packetline::Provider` without type parameters, /// but leave support for reading lines directly without forcing them through `String`. @@ -28,6 +28,12 @@ pub trait ReadlineBufRead: io::BufRead { fn readline( &mut self, ) -> Option, gix_packetline::decode::Error>>>; + + /// Read a line similar to `BufRead::read_line()`, but assure it doesn't try to find newlines + /// which might concatenate multiple distinct packet lines. + /// + /// Making this a trait method allows to handle differences between async and blocking. + fn readline_str(&mut self, line: &mut String) -> io::Result; } /// Provide even more access to the underlying packet reader. @@ -50,6 +56,9 @@ impl<'a, T: ReadlineBufRead + ?Sized + 'a> ReadlineBufRead for Box { fn readline(&mut self) -> Option, gix_packetline::decode::Error>>> { ReadlineBufRead::readline(self.deref_mut()) } + fn readline_str(&mut self, line: &mut String) -> io::Result { + ReadlineBufRead::readline_str(self.deref_mut(), line) + } } impl<'a, T: ExtendedBufRead + ?Sized + 'a> ExtendedBufRead for Box { @@ -70,16 +79,24 @@ impl<'a, T: ExtendedBufRead + ?Sized + 'a> ExtendedBufRead for Box { } } -impl ReadlineBufRead for gix_packetline::read::WithSidebands<'_, T, fn(bool, &[u8])> { +impl ReadlineBufRead for gix_packetline::read::WithSidebands<'_, T, fn(bool, &[u8]) -> ProgressAction> { fn readline(&mut self) -> Option, gix_packetline::decode::Error>>> { self.read_data_line() } + + fn readline_str(&mut self, line: &mut String) -> io::Result { + self.read_line_to_string(line) + } } impl<'a, T: io::Read> ReadlineBufRead for gix_packetline::read::WithSidebands<'a, T, HandleProgress> { fn readline(&mut self) -> Option, gix_packetline::decode::Error>>> { self.read_data_line() } + + fn readline_str(&mut self, line: &mut String) -> io::Result { + self.read_line_to_string(line) + } } impl<'a, T: io::Read> ExtendedBufRead for gix_packetline::read::WithSidebands<'a, T, HandleProgress> { diff --git a/vendor/gix-transport/src/client/blocking_io/connect.rs b/vendor/gix-transport/src/client/blocking_io/connect.rs index de3334f18..5bdb5319e 100644 --- a/vendor/gix-transport/src/client/blocking_io/connect.rs +++ b/vendor/gix-transport/src/client/blocking_io/connect.rs @@ -23,7 +23,7 @@ pub(crate) mod function { Ok(match url.scheme { gix_url::Scheme::Ext(_) => return Err(Error::UnsupportedScheme(url.scheme)), gix_url::Scheme::File => { - if url.user().is_some() || url.host().is_some() || url.port.is_some() { + if url.user().is_some() || url.password().is_some() || url.host().is_some() || url.port.is_some() { return Err(Error::UnsupportedUrlTokens { url: url.to_bstring(), scheme: url.scheme, @@ -59,10 +59,9 @@ pub(crate) mod function { #[cfg(not(any(feature = "http-client-curl", feature = "http-client-reqwest")))] gix_url::Scheme::Https | gix_url::Scheme::Http => return Err(Error::CompiledWithoutHttp(url.scheme)), #[cfg(any(feature = "http-client-curl", feature = "http-client-reqwest"))] - gix_url::Scheme::Https | gix_url::Scheme::Http => Box::new(crate::client::http::connect( - &url.to_bstring().to_string(), - options.version, - )), + gix_url::Scheme::Https | gix_url::Scheme::Http => { + Box::new(crate::client::http::connect(url, options.version)) + } }) } } diff --git a/vendor/gix-transport/src/client/blocking_io/file.rs b/vendor/gix-transport/src/client/blocking_io/file.rs index d80fe55df..d60b70c6e 100644 --- a/vendor/gix-transport/src/client/blocking_io/file.rs +++ b/vendor/gix-transport/src/client/blocking_io/file.rs @@ -71,7 +71,7 @@ impl SpawnProcessOnDemand { } fn new_local(path: BString, version: Protocol) -> SpawnProcessOnDemand { SpawnProcessOnDemand { - url: gix_url::Url::from_parts_as_alternative_form(gix_url::Scheme::File, None, None, None, path.clone()) + url: gix_url::Url::from_parts(gix_url::Scheme::File, None, None, None, None, path.clone(), true) .expect("valid url"), path, ssh_cmd: None, diff --git a/vendor/gix-transport/src/client/blocking_io/http/mod.rs b/vendor/gix-transport/src/client/blocking_io/http/mod.rs index d88d6bf26..64cc892d8 100644 --- a/vendor/gix-transport/src/client/blocking_io/http/mod.rs +++ b/vendor/gix-transport/src/client/blocking_io/http/mod.rs @@ -45,9 +45,10 @@ pub mod options { dyn FnMut(gix_credentials::helper::Action) -> gix_credentials::protocol::Result + Send + Sync; /// Possible settings for the `http.followRedirects` configuration option. - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum FollowRedirects { /// Follow only the first redirect request, most suitable for typical git requests. + #[default] Initial, /// Follow all redirect requests from the server unconditionally All, @@ -55,16 +56,11 @@ pub mod options { None, } - impl Default for FollowRedirects { - fn default() -> Self { - FollowRedirects::Initial - } - } - /// The way to configure a proxy for authentication if a username is present in the configured proxy. - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum ProxyAuthMethod { /// Automatically pick a suitable authentication method. + #[default] AnyAuth, ///HTTP basic authentication. Basic, @@ -76,12 +72,6 @@ pub mod options { Ntlm, } - impl Default for ProxyAuthMethod { - fn default() -> Self { - ProxyAuthMethod::AnyAuth - } - } - /// Available SSL version numbers. #[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)] #[allow(missing_docs)] @@ -133,7 +123,7 @@ pub mod options { #[derive(Default, Clone)] pub struct Options { /// Headers to be added to every request. - /// They are applied unconditionally and are expected to be valid as they occour in an HTTP request, like `header: value`, without newlines. + /// They are applied unconditionally and are expected to be valid as they occur in an HTTP request, like `header: value`, without newlines. /// /// Refers to `http.extraHeader` multi-var. pub extra_headers: Vec, @@ -217,26 +207,40 @@ pub struct Transport { impl Transport { /// Create a new instance with `http` as implementation to communicate to `url` using the given `desired_version`. /// Note that we will always fallback to other versions as supported by the server. - pub fn new_http(http: H, url: &str, desired_version: Protocol) -> Self { + pub fn new_http(http: H, url: gix_url::Url, desired_version: Protocol) -> Self { + let identity = url + .user() + .zip(url.password()) + .map(|(user, pass)| gix_sec::identity::Account { + username: user.to_string(), + password: pass.to_string(), + }); Transport { - url: url.to_owned(), + url: url.to_bstring().to_string(), user_agent_header: concat!("User-Agent: git/oxide-", env!("CARGO_PKG_VERSION")), desired_version, actual_version: Default::default(), service: None, http, line_provider: None, - identity: None, + identity, } } } +impl Transport { + /// Returns the identity that the transport uses when connecting to the remote. + pub fn identity(&self) -> Option<&gix_sec::identity::Account> { + self.identity.as_ref() + } +} + #[cfg(any(feature = "http-client-curl", feature = "http-client-reqwest"))] impl Transport { /// Create a new instance to communicate to `url` using the given `desired_version` of the `git` protocol. /// /// Note that the actual implementation depends on feature toggles. - pub fn new(url: &str, desired_version: Protocol) -> Self { + pub fn new(url: gix_url::Url, desired_version: Protocol) -> Self { Self::new_http(Impl::default(), url, desired_version) } } @@ -472,6 +476,11 @@ impl ReadlineBufRead for HeadersThenBody std::io::Result { + self.handle_headers()?; + self.body.readline_str(line) + } } impl ExtendedBufRead for HeadersThenBody { @@ -497,13 +506,13 @@ impl ExtendedBufRead for HeadersThenBody(http: H, url: &str, desired_version: Protocol) -> Transport { +pub fn connect_http(http: H, url: gix_url::Url, desired_version: Protocol) -> Transport { Transport::new_http(http, url, desired_version) } /// Connect to the given `url` via HTTP/S using the `desired_version` of the `git` protocol. #[cfg(any(feature = "http-client-curl", feature = "http-client-reqwest"))] -pub fn connect(url: &str, desired_version: Protocol) -> Transport { +pub fn connect(url: gix_url::Url, desired_version: Protocol) -> Transport { Transport::new(url, desired_version) } diff --git a/vendor/gix-transport/src/client/blocking_io/http/traits.rs b/vendor/gix-transport/src/client/blocking_io/http/traits.rs index 5b163f892..52176fecc 100644 --- a/vendor/gix-transport/src/client/blocking_io/http/traits.rs +++ b/vendor/gix-transport/src/client/blocking_io/http/traits.rs @@ -84,7 +84,7 @@ impl From> for GetResponse { } /// A trait to abstract the HTTP operations needed to power all git interactions: read via GET and write via POST. -/// Note that 401 must be turned into `std::io::Error(PermissionDenied)`, and other non-success http stati must be transformed +/// Note that 401 must be turned into `std::io::Error(PermissionDenied)`, and other non-success http statuses must be transformed /// into `std::io::Error(Other)` #[allow(clippy::type_complexity)] pub trait Http { diff --git a/vendor/gix-transport/src/client/blocking_io/ssh/mod.rs b/vendor/gix-transport/src/client/blocking_io/ssh/mod.rs index 63e4dc817..7c042dc28 100644 --- a/vendor/gix-transport/src/client/blocking_io/ssh/mod.rs +++ b/vendor/gix-transport/src/client/blocking_io/ssh/mod.rs @@ -86,6 +86,7 @@ pub mod connect { /// /// The `desired_version` is the preferred protocol version when establishing the connection, but note that it can be /// downgraded by servers not supporting it. +#[allow(clippy::result_large_err)] pub fn connect( url: gix_url::Url, desired_version: Protocol, diff --git a/vendor/gix-transport/src/client/blocking_io/ssh/tests.rs b/vendor/gix-transport/src/client/blocking_io/ssh/tests.rs index 27c661bd8..f0820d14e 100644 --- a/vendor/gix-transport/src/client/blocking_io/ssh/tests.rs +++ b/vendor/gix-transport/src/client/blocking_io/ssh/tests.rs @@ -126,7 +126,7 @@ mod program_kind { &["ssh", "-o", "SendEnv=GIT_PROTOCOL", "host"][..], ), ] { - assert_eq!(call_args(ProgramKind::Ssh, url, protocol), quoted(expected)); + assert_eq!(call_args(ProgramKind::Ssh, url, protocol), joined(expected)); } } @@ -134,14 +134,14 @@ mod program_kind { fn tortoise_plink_has_batch_command() { assert_eq!( call_args(ProgramKind::TortoisePlink, "ssh://user@host:42/p", Protocol::V2), - quoted(&["tortoiseplink.exe", "-batch", "-P", "42", "user@host"]) + joined(&["tortoiseplink.exe", "-batch", "-P", "42", "user@host"]) ); } #[test] fn port_for_all() { for kind in [ProgramKind::TortoisePlink, ProgramKind::Plink, ProgramKind::Putty] { - assert!(call_args(kind, "ssh://user@host:43/p", Protocol::V2).ends_with(r#""-P" "43" "user@host""#)); + assert!(call_args(kind, "ssh://user@host:43/p", Protocol::V2).ends_with("-P 43 user@host")); } } @@ -153,7 +153,7 @@ mod program_kind { } assert_eq!( call_args(ProgramKind::Simple, "ssh://user@host/p", Protocol::V2), - quoted(&["simple", "user@host"]), + joined(&["simple", "user@host"]), "simple can only do simple invocations" ); } @@ -191,8 +191,8 @@ mod program_kind { Ok(()) } - fn quoted(input: &[&str]) -> String { - input.iter().map(|s| format!("\"{s}\"")).collect::>().join(" ") + fn joined(input: &[&str]) -> String { + input.to_vec().join(" ") } fn try_call( kind: ProgramKind, @@ -207,7 +207,15 @@ mod program_kind { try_call(kind, url, version).expect("no error") } fn call_args(kind: ProgramKind, url: &str, version: Protocol) -> String { - format!("{:?}", std::process::Command::from(call(kind, url, version))) + let cmd = std::process::Command::from(call(kind, url, version)); + format!( + "{} {}", + cmd.get_program().to_string_lossy(), + cmd.get_args() + .map(|arg| arg.to_string_lossy().into_owned()) + .collect::>() + .join(" ") + ) } type Result = std::result::Result<(), ssh::invocation::Error>; diff --git a/vendor/gix-transport/src/client/capabilities.rs b/vendor/gix-transport/src/client/capabilities.rs index 4c10dc100..05185edae 100644 --- a/vendor/gix-transport/src/client/capabilities.rs +++ b/vendor/gix-transport/src/client/capabilities.rs @@ -24,7 +24,7 @@ pub enum Error { /// A structure to represent multiple [capabilities][Capability] or features supported by the server. #[derive(Debug, Clone, Default)] -#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Capabilities { data: BString, value_sep: u8, diff --git a/vendor/gix-transport/src/client/non_io_types.rs b/vendor/gix-transport/src/client/non_io_types.rs index a207f7f0b..807b22a8f 100644 --- a/vendor/gix-transport/src/client/non_io_types.rs +++ b/vendor/gix-transport/src/client/non_io_types.rs @@ -1,6 +1,6 @@ /// Configure how the [`RequestWriter`][crate::client::RequestWriter] behaves when writing bytes. -#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] -#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum WriteMode { /// Each [write()][std::io::Write::write()] call writes the bytes verbatim as one or more packet lines. /// @@ -11,19 +11,14 @@ pub enum WriteMode { /// /// This mode also indicates that the lines written fit into memory, hence the transport may chose to not stream it but to buffer it /// instead. This is relevant for some transports, like the one for HTTP. + #[default] OneLfTerminatedLinePerWriteCall, } -impl Default for WriteMode { - fn default() -> Self { - WriteMode::OneLfTerminatedLinePerWriteCall - } -} - /// The kind of packet line to write when transforming a [`RequestWriter`][crate::client::RequestWriter] into an /// [`ExtendedBufRead`][crate::client::ExtendedBufRead]. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] -#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum MessageKind { /// A `flush` packet. Flush, -- cgit v1.2.3