Skip to content

Commit

Permalink
fix: make it possible to parse handshakes without newlines in packetl…
Browse files Browse the repository at this point in the history
…ines #(639)
  • Loading branch information
Byron committed Dec 4, 2022
1 parent 7ab7c24 commit 4927adf
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 4 deletions.
30 changes: 26 additions & 4 deletions git-transport/src/client/capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ impl Capabilities {
#[cfg(feature = "blocking-client")]
///
pub mod recv {
use bstr::ByteVec;
use std::io;
use std::io::Read;

use crate::{client, client::Capabilities, Protocol};

Expand Down Expand Up @@ -204,7 +204,18 @@ pub mod recv {
capabilities: {
let mut rd = rd.as_read();
let mut buf = Vec::new();
rd.read_to_end(&mut buf)?;
while let Some(line) = rd.read_data_line() {
let line = line??;
match line.as_bstr() {
Some(line) => {
buf.push_str(line);
if buf.last() != Some(&b'\n') {
buf.push(b'\n');
}
}
None => break,
}
}
Capabilities::from_lines(buf.into())?
},
refs: None,
Expand All @@ -220,9 +231,9 @@ pub mod recv {
///
pub mod recv {
use futures_io::AsyncRead;
use futures_lite::AsyncReadExt;

use crate::{client, client::Capabilities, Protocol};
use bstr::ByteVec;

/// Success outcome of [`Capabilities::from_lines_with_version_detection`].
pub struct Outcome<'a> {
Expand Down Expand Up @@ -272,7 +283,18 @@ pub mod recv {
capabilities: {
let mut rd = rd.as_read();
let mut buf = Vec::new();
rd.read_to_end(&mut buf).await?;
while let Some(line) = rd.read_data_line().await {
let line = line??;
match line.as_bstr() {
Some(line) => {
buf.push_str(line);
if buf.last() != Some(&b'\n') {
buf.push(b'\n');
}
}
None => break,
}
}
Capabilities::from_lines(buf.into())?
},
refs: None,
Expand Down
59 changes: 59 additions & 0 deletions git-transport/tests/client/blocking_io/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,65 @@ fn handshake_and_lsrefs_and_fetch_v2() -> crate::Result {
handshake_and_lsrefs_and_fetch_v2_impl("v2/http-handshake.response")
}

#[test]
fn handshake_and_lsrefs_and_fetch_v2_googlesource() -> crate::Result {
let (_server, mut c) = mock::serve_and_connect(
"v2/http-no-newlines-handshake.response",
"path/not/important/due/to/mock",
Protocol::V2,
)?;
assert!(
!c.connection_persists_across_multiple_requests(),
"http connections are never stateful"
);
let SetServiceResponse {
actual_protocol,
capabilities,
refs,
} = c.handshake(Service::UploadPack, &[("value-only", None), ("key", Some("value"))])?;
assert_eq!(actual_protocol, Protocol::V2);
assert!(
refs.is_none(),
"refs are only returned in V1, as V2 favors a separate command (with more options)"
);
assert_eq!(
capabilities
.iter()
.map(|v| {
(
v.name().to_owned(),
v.values().map(|v| v.map(ToOwned::to_owned).collect::<Vec<_>>()),
)
})
.collect::<Vec<_>>(),
[
("ls-refs", None),
(
"fetch",
Some(
&[
"filter",
"ref-in-want",
"sideband-all",
"packfile-uris",
"wait-for-done",
"shallow"
][..]
)
),
("server-option", None),
("session-id", None),
]
.iter()
.map(|(k, v)| (
k.as_bytes().into(),
v.map(|v| v.iter().map(|v| v.as_bytes().into()).collect::<Vec<_>>())
))
.collect::<Vec<_>>()
);
Ok(())
}

#[test]
fn handshake_and_lsrefs_and_fetch_v2_service_announced() -> crate::Result {
handshake_and_lsrefs_and_fetch_v2_impl("v2/http-handshake-service-announced.response")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
HTTP/1.1 200 OK
Cache-Control: no-cache, max-age=0, must-revalidate
Content-Length: 136
Content-Security-Policy-Report-Only: script-src 'nonce-3J1VJWYTKuii1QtanCSwhA' 'unsafe-inline' 'strict-dynamic' https: http: 'unsafe-eval';object-src 'none';base-uri 'self';report-uri https://csp.withgoogle.com/csp/gerritcodereview/1
Content-Type: application/x-git-upload-pack-advertisement
Expires: Fri, 01 Jan 1980 00:00:00 GMT
Pragma: no-cache
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0
Date: Sun, 04 Dec 2022 10:16:06 GMT
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"

000dversion 2000bls-refs004dfetch=filter ref-in-want sideband-all packfile-uris wait-for-done shallow0011server-option000esession-id0000

0 comments on commit 4927adf

Please sign in to comment.