diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/gix-protocol/src/fetch | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-protocol/src/fetch')
-rw-r--r-- | vendor/gix-protocol/src/fetch/arguments/async_io.rs | 10 | ||||
-rw-r--r-- | vendor/gix-protocol/src/fetch/arguments/blocking_io.rs | 10 | ||||
-rw-r--r-- | vendor/gix-protocol/src/fetch/arguments/mod.rs | 6 | ||||
-rw-r--r-- | vendor/gix-protocol/src/fetch/response/async_io.rs | 15 | ||||
-rw-r--r-- | vendor/gix-protocol/src/fetch/response/blocking_io.rs | 19 | ||||
-rw-r--r-- | vendor/gix-protocol/src/fetch/tests.rs | 11 |
6 files changed, 52 insertions, 19 deletions
diff --git a/vendor/gix-protocol/src/fetch/arguments/async_io.rs b/vendor/gix-protocol/src/fetch/arguments/async_io.rs index fc876d02c..e92d8faab 100644 --- a/vendor/gix-protocol/src/fetch/arguments/async_io.rs +++ b/vendor/gix-protocol/src/fetch/arguments/async_io.rs @@ -9,7 +9,7 @@ impl Arguments { &mut self, transport: &'a mut T, add_done_argument: bool, - ) -> Result<Box<dyn client::ExtendedBufRead + Unpin + 'a>, client::Error> { + ) -> Result<Box<dyn client::ExtendedBufRead<'a> + Unpin + 'a>, client::Error> { if self.haves.is_empty() { assert!(add_done_argument, "If there are no haves, is_done must be true."); } @@ -19,8 +19,11 @@ impl Arguments { transport.connection_persists_across_multiple_requests(), add_done_argument, )?; - let mut line_writer = - transport.request(client::WriteMode::OneLfTerminatedLinePerWriteCall, on_into_read)?; + let mut line_writer = transport.request( + client::WriteMode::OneLfTerminatedLinePerWriteCall, + on_into_read, + self.trace, + )?; let had_args = !self.args.is_empty(); for arg in self.args.drain(..) { line_writer.write_all(&arg).await?; @@ -47,6 +50,7 @@ impl Arguments { Command::Fetch.as_str(), self.features.iter().filter(|(_, v)| v.is_some()).cloned(), Some(std::mem::replace(&mut self.args, retained_state).into_iter()), + self.trace, ) .await } diff --git a/vendor/gix-protocol/src/fetch/arguments/blocking_io.rs b/vendor/gix-protocol/src/fetch/arguments/blocking_io.rs index c946d46e1..0852f5a88 100644 --- a/vendor/gix-protocol/src/fetch/arguments/blocking_io.rs +++ b/vendor/gix-protocol/src/fetch/arguments/blocking_io.rs @@ -10,7 +10,7 @@ impl Arguments { &mut self, transport: &'a mut T, add_done_argument: bool, - ) -> Result<Box<dyn client::ExtendedBufRead + Unpin + 'a>, client::Error> { + ) -> Result<Box<dyn client::ExtendedBufRead<'a> + Unpin + 'a>, client::Error> { if self.haves.is_empty() { assert!(add_done_argument, "If there are no haves, is_done must be true."); } @@ -20,8 +20,11 @@ impl Arguments { transport.connection_persists_across_multiple_requests(), add_done_argument, )?; - let mut line_writer = - transport.request(client::WriteMode::OneLfTerminatedLinePerWriteCall, on_into_read)?; + let mut line_writer = transport.request( + client::WriteMode::OneLfTerminatedLinePerWriteCall, + on_into_read, + self.trace, + )?; let had_args = !self.args.is_empty(); for arg in self.args.drain(..) { line_writer.write_all(&arg)?; @@ -47,6 +50,7 @@ impl Arguments { Command::Fetch.as_str(), self.features.iter().filter(|(_, v)| v.is_some()).cloned(), Some(std::mem::replace(&mut self.args, retained_state).into_iter()), + self.trace, ) } } diff --git a/vendor/gix-protocol/src/fetch/arguments/mod.rs b/vendor/gix-protocol/src/fetch/arguments/mod.rs index 50145bb15..8ad391d5f 100644 --- a/vendor/gix-protocol/src/fetch/arguments/mod.rs +++ b/vendor/gix-protocol/src/fetch/arguments/mod.rs @@ -23,6 +23,8 @@ pub struct Arguments { features_for_first_want: Option<Vec<String>>, #[cfg(any(feature = "async-client", feature = "blocking-client"))] version: gix_transport::Protocol, + + trace: bool, } impl Arguments { @@ -194,8 +196,9 @@ impl Arguments { } /// Create a new instance to help setting up arguments to send to the server as part of a `fetch` operation /// for which `features` are the available and configured features to use. + /// If `trace` is `true`, all packetlines received or sent will be passed to the facilities of the `gix-trace` crate. #[cfg(any(feature = "async-client", feature = "blocking-client"))] - pub fn new(version: gix_transport::Protocol, features: Vec<crate::command::Feature>) -> Self { + pub fn new(version: gix_transport::Protocol, features: Vec<crate::command::Feature>, trace: bool) -> Self { use crate::Command; let has = |name: &str| features.iter().any(|f| f.0 == name); let filter = has("filter"); @@ -242,6 +245,7 @@ impl Arguments { ref_in_want, deepen_since, features_for_first_want, + trace, } } } diff --git a/vendor/gix-protocol/src/fetch/response/async_io.rs b/vendor/gix-protocol/src/fetch/response/async_io.rs index c510a1ad4..547881331 100644 --- a/vendor/gix-protocol/src/fetch/response/async_io.rs +++ b/vendor/gix-protocol/src/fetch/response/async_io.rs @@ -10,7 +10,7 @@ use crate::fetch::{ async fn parse_v2_section<T>( line: &mut String, - reader: &mut (impl client::ExtendedBufRead + Unpin), + reader: &mut (impl client::ExtendedBufRead<'_> + Unpin), res: &mut Vec<T>, parse: impl Fn(&str) -> Result<T, response::Error>, ) -> Result<bool, response::Error> { @@ -37,10 +37,16 @@ impl Response { /// and if `true` we will keep parsing until we get a pack as the client already signalled to the server that it's done. /// This way of doing things allows us to exploit knowledge about more recent versions of the protocol, which keeps code easier /// and more localized without having to support all the cruft that there is. + /// + /// `wants_to_negotiate` should be `false` for clones which is when we don't have sent any haves. The reason for this flag to exist + /// is to predict how to parse V1 output only, and neither `client_expects_pack` nor `wants_to_negotiate` are relevant for V2. + /// This ugliness is in place to avoid having to resort to an [an even more complex ugliness](https://github.com/git/git/blob/9e49351c3060e1fa6e0d2de64505b7becf157f28/fetch-pack.c#L583-L594) + /// that `git` has to use to predict how many acks are supposed to be read. We also genuinely hope that this covers it all…. pub async fn from_line_reader( version: Protocol, - reader: &mut (impl client::ExtendedBufRead + Unpin), + reader: &mut (impl client::ExtendedBufRead<'_> + Unpin), client_expects_pack: bool, + wants_to_negotiate: bool, ) -> Result<Response, response::Error> { match version { Protocol::V0 | Protocol::V1 => { @@ -89,7 +95,10 @@ impl Response { ); // When the server sends ready, we know there is going to be a pack so no need to stop early. saw_ready |= matches!(acks.last(), Some(Acknowledgement::Ready)); - if let Some(Acknowledgement::Nak) = acks.last().filter(|_| !client_expects_pack && !saw_ready) { + if let Some(Acknowledgement::Nak) = acks.last().filter(|_| !client_expects_pack || !saw_ready) { + if !wants_to_negotiate { + continue; + } break 'lines false; } }; diff --git a/vendor/gix-protocol/src/fetch/response/blocking_io.rs b/vendor/gix-protocol/src/fetch/response/blocking_io.rs index 309f5a7c5..08460ae39 100644 --- a/vendor/gix-protocol/src/fetch/response/blocking_io.rs +++ b/vendor/gix-protocol/src/fetch/response/blocking_io.rs @@ -8,9 +8,9 @@ use crate::fetch::{ Response, }; -fn parse_v2_section<T>( +fn parse_v2_section<'a, T>( line: &mut String, - reader: &mut impl client::ExtendedBufRead, + reader: &mut impl client::ExtendedBufRead<'a>, res: &mut Vec<T>, parse: impl Fn(&str) -> Result<T, response::Error>, ) -> Result<bool, response::Error> { @@ -37,10 +37,16 @@ impl Response { /// and if `true` we will keep parsing until we get a pack as the client already signalled to the server that it's done. /// This way of doing things allows us to exploit knowledge about more recent versions of the protocol, which keeps code easier /// and more localized without having to support all the cruft that there is. - pub fn from_line_reader( + /// + /// `wants_to_negotiate` should be `false` for clones which is when we don't have sent any haves. The reason for this flag to exist + /// is to predict how to parse V1 output only, and neither `client_expects_pack` nor `wants_to_negotiate` are relevant for V2. + /// This ugliness is in place to avoid having to resort to an [an even more complex ugliness](https://github.com/git/git/blob/9e49351c3060e1fa6e0d2de64505b7becf157f28/fetch-pack.c#L583-L594) + /// that `git` has to use to predict how many acks are supposed to be read. We also genuinely hope that this covers it all…. + pub fn from_line_reader<'a>( version: Protocol, - reader: &mut impl client::ExtendedBufRead, + reader: &mut impl client::ExtendedBufRead<'a>, client_expects_pack: bool, + wants_to_negotiate: bool, ) -> Result<Response, response::Error> { match version { Protocol::V0 | Protocol::V1 => { @@ -85,7 +91,10 @@ impl Response { assert_ne!(reader.readline_str(&mut line)?, 0, "consuming a peeked line works"); // When the server sends ready, we know there is going to be a pack so no need to stop early. saw_ready |= matches!(acks.last(), Some(Acknowledgement::Ready)); - if let Some(Acknowledgement::Nak) = acks.last().filter(|_| !client_expects_pack && !saw_ready) { + if let Some(Acknowledgement::Nak) = acks.last().filter(|_| !client_expects_pack || !saw_ready) { + if !wants_to_negotiate { + continue; + } break 'lines false; } }; diff --git a/vendor/gix-protocol/src/fetch/tests.rs b/vendor/gix-protocol/src/fetch/tests.rs index 93cf6e8db..e3c46f57e 100644 --- a/vendor/gix-protocol/src/fetch/tests.rs +++ b/vendor/gix-protocol/src/fetch/tests.rs @@ -6,11 +6,11 @@ mod arguments { use crate::fetch; fn arguments_v1(features: impl IntoIterator<Item = &'static str>) -> fetch::Arguments { - fetch::Arguments::new(Protocol::V1, features.into_iter().map(|n| (n, None)).collect()) + fetch::Arguments::new(Protocol::V1, features.into_iter().map(|n| (n, None)).collect(), false) } fn arguments_v2(features: impl IntoIterator<Item = &'static str>) -> fetch::Arguments { - fetch::Arguments::new(Protocol::V2, features.into_iter().map(|n| (n, None)).collect()) + fetch::Arguments::new(Protocol::V2, features.into_iter().map(|n| (n, None)).collect(), false) } struct Transport<T> { @@ -40,8 +40,9 @@ mod arguments { &mut self, write_mode: WriteMode, on_into_read: MessageKind, + trace: bool, ) -> Result<RequestWriter<'_>, Error> { - self.inner.request(write_mode, on_into_read) + self.inner.request(write_mode, on_into_read, trace) } fn to_url(&self) -> Cow<'_, BStr> { @@ -97,8 +98,9 @@ mod arguments { &mut self, write_mode: WriteMode, on_into_read: MessageKind, + trace: bool, ) -> Result<RequestWriter<'_>, Error> { - self.inner.request(write_mode, on_into_read) + self.inner.request(write_mode, on_into_read, trace) } fn to_url(&self) -> Cow<'_, BStr> { @@ -145,6 +147,7 @@ mod arguments { b"does/not/matter".as_bstr().to_owned(), None::<(&str, _)>, gix_transport::client::git::ConnectMode::Process, // avoid header to be sent + false, ), stateful, } |