summaryrefslogtreecommitdiffstats
path: root/vendor/gix-protocol/src/fetch
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/gix-protocol/src/fetch
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-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.rs10
-rw-r--r--vendor/gix-protocol/src/fetch/arguments/blocking_io.rs10
-rw-r--r--vendor/gix-protocol/src/fetch/arguments/mod.rs6
-rw-r--r--vendor/gix-protocol/src/fetch/response/async_io.rs15
-rw-r--r--vendor/gix-protocol/src/fetch/response/blocking_io.rs19
-rw-r--r--vendor/gix-protocol/src/fetch/tests.rs11
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,
}