Skip to content

Commit 93917cb

Browse files
committed
Merge branch 'main' into fetch-pack
Conflicts: git-transport/src/client/blocking_io/http/mod.rs
2 parents 5a6c102 + 6c9d18b commit 93917cb

File tree

12 files changed

+88
-17
lines changed

12 files changed

+88
-17
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ check: ## Build all code in suitable configurations
115115
&& cargo check --features blocking-client \
116116
&& cargo check --features async-client \
117117
&& cargo check --features async-client,async-std \
118+
&& cargo check --features http-client \
118119
&& cargo check --features http-client-curl
119120
cd git-transport && if cargo check --all-features 2>/dev/null; then false; else true; fi
120121
cd git-protocol && cargo check \

git-discover/tests/upwards/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ fn cross_fs() -> crate::Result {
182182
use std::{os::unix::fs::symlink, process::Command};
183183

184184
use git_discover::upwards::Options;
185+
if git_testtools::is_ci::cached() {
186+
// Don't run on CI as it's too slow there, resource busy, it fails more often than it succeeds by now.
187+
return Ok(());
188+
}
185189

186190
let top_level_repo = git_testtools::scripted_fixture_repo_writable("make_basic_repo.sh")?;
187191

git-object/src/object/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,14 @@ impl<'a> ObjectRef<'a> {
180180
/// Deserialize an object from a loose serialisation
181181
pub fn from_loose(data: &'a [u8]) -> Result<ObjectRef<'a>, LooseDecodeError> {
182182
let (kind, size, offset) = loose_header(data)?;
183-
Ok(Self::from_bytes(kind, &data[offset..][..size])?)
183+
184+
let body = &data[offset..]
185+
.get(..size)
186+
.ok_or(LooseHeaderDecodeError::InvalidHeader {
187+
message: "object data was shorter than its size declared in the header",
188+
})?;
189+
190+
Ok(Self::from_bytes(kind, body)?)
184191
}
185192

186193
/// Deserialize an object of `kind` from the given `data`.

git-object/tests/loose.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use bstr::ByteSlice;
2-
use git_object::{decode, encode, Kind};
2+
use git_object::{decode, encode, Kind, ObjectRef};
33

44
#[test]
55
fn all() -> Result<(), Box<dyn std::error::Error>> {
@@ -18,3 +18,11 @@ fn all() -> Result<(), Box<dyn std::error::Error>> {
1818
}
1919
Ok(())
2020
}
21+
22+
#[test]
23+
fn shorter_than_advertised() {
24+
assert_eq!(
25+
ObjectRef::from_loose(b"tree 1000\x00").unwrap_err().to_string(),
26+
"object data was shorter than its size declared in the header"
27+
);
28+
}

git-transport/Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ default = []
2020

2121
## If set, blocking implementations of the typical git transports become available in `crate::client`
2222
blocking-client = ["git-packetline/blocking-io"]
23-
## Implies `blocking-client`, and adds support for the http and https transports using the Rust bindings for `libcurl`.
24-
http-client-curl = ["curl", "base64", "git-features/io-pipe", "blocking-client"]
23+
## Implies `blocking-client`, and adds support for the http and https transports.
24+
http-client = ["base64", "git-features/io-pipe", "blocking-client"]
25+
## Implies `http-client`, and adds support for the http and https transports using the Rust bindings for `libcurl`.
26+
http-client-curl = ["curl", "http-client"]
2527
## If set, an async implementations of the git transports becomes available in `crate::client`.
2628
## Suitable for implementing your own transports while using git's way of communication, typically in conjunction with a custom server.
2729
## **Note** that the _blocking_ client has a wide range of available transports, with the _async_ version of it supporting only the TCP based `git` transport leaving you
@@ -62,11 +64,13 @@ futures-io = { version = "0.3.16", optional = true }
6264
futures-lite = { version = "1.12.0", optional = true }
6365
pin-project-lite = { version = "0.2.6", optional = true }
6466

67+
# for http-client
68+
base64 = { version = "0.13.0", optional = true }
69+
6570
# for http-client-curl
6671
# zlib-ng-compat doesn't force zlib-ng
6772
curl = { version = "0.4", optional = true, features = ["static-curl", "static-ssl", "zlib-ng-compat"] }
6873
thiserror = "1.0.26"
69-
base64 = { version = "0.13.0", optional = true }
7074

7175
## If used in conjunction with `async-client`, the `connect()` method will be come available along with supporting the git protocol over TCP,
7276
## where the TCP stream is created using this crate.

git-transport/src/client/blocking_io/http/mod.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,41 @@ pub struct Transport<H: Http> {
3535
identity: Option<git_sec::identity::Account>,
3636
}
3737

38-
impl Transport<Impl> {
39-
/// Create a new instance to communicate to `url` using the given `desired_version` of the `git` protocol.
40-
pub fn new(url: &str, desired_version: Protocol) -> Self {
38+
impl<H: Http> Transport<H> {
39+
/// Create a new instance with `http` as implementation to communicate to `url` using the given `desired_version` of the `git` protocol.
40+
pub fn new_http(http: H, url: &str, desired_version: Protocol) -> Self {
4141
Transport {
4242
url: url.to_owned(),
4343
user_agent_header: concat!("User-Agent: git/oxide-", env!("CARGO_PKG_VERSION")),
4444
desired_version,
4545
actual_version: desired_version,
4646
supported_versions: [desired_version],
4747
service: None,
48-
http: Impl::default(),
48+
http,
4949
line_provider: None,
5050
identity: None,
5151
}
5252
}
5353
}
5454

55+
#[cfg(feature = "http-client-curl")]
56+
impl Transport<Impl> {
57+
/// Create a new instance to communicate to `url` using the given `desired_version` of the `git` protocol.
58+
///
59+
/// Note that the actual implementation depends on feature toggles.
60+
pub fn new(url: &str, desired_version: Protocol) -> Self {
61+
Self::new_http(Impl::default(), url, desired_version)
62+
}
63+
}
64+
5565
impl<H: Http> Transport<H> {
5666
fn check_content_type(service: Service, kind: &str, headers: <H as Http>::Headers) -> Result<(), client::Error> {
57-
let wanted_content_type = format!("Content-Type: application/x-{}-{}", service.as_str(), kind);
67+
let wanted_content_type = format!("content-type: application/x-{}-{}", service.as_str(), kind);
5868
if !headers
5969
.lines()
6070
.collect::<Result<Vec<_>, _>>()?
6171
.iter()
62-
.any(|l| l == &wanted_content_type)
72+
.any(|l| l.to_lowercase() == wanted_content_type)
6373
{
6474
return Err(client::Error::Http(Error::Detail {
6575
description: format!(
@@ -289,7 +299,14 @@ impl<H: Http, B: ExtendedBufRead + Unpin> ExtendedBufRead for HeadersThenBody<H,
289299
}
290300
}
291301

302+
/// Connect to the given `url` via HTTP/S using the `desired_version` of the `git` protocol, with `http` as implementation.
303+
#[cfg(all(feature = "http-client", not(feature = "http-client-curl")))]
304+
pub fn connect_http<H: Http>(http: H, url: &str, desired_version: Protocol) -> Transport<H> {
305+
Transport::new_http(http, url, desired_version)
306+
}
307+
292308
/// Connect to the given `url` via HTTP/S using the `desired_version` of the `git` protocol.
309+
#[cfg(feature = "http-client-curl")]
293310
pub fn connect(url: &str, desired_version: Protocol) -> Transport<Impl> {
294311
Transport::new(url, desired_version)
295312
}

git-transport/src/client/blocking_io/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub mod connect;
44
///
55
pub mod file;
66
///
7-
#[cfg(feature = "http-client-curl")]
7+
#[cfg(feature = "http-client")]
88
pub mod http;
99

1010
mod bufread_ext;

git-transport/src/client/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub use traits::TransportWithoutIO;
1010

1111
#[cfg(feature = "blocking-client")]
1212
mod blocking_io;
13-
#[cfg(all(feature = "blocking-client", feature = "http-client-curl"))]
13+
#[cfg(feature = "http-client")]
1414
pub use blocking_io::http;
1515
#[cfg(feature = "blocking-client")]
1616
pub use blocking_io::{

git-transport/src/client/non_io_types.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ mod error {
5858
use bstr::BString;
5959

6060
use crate::client::capabilities;
61-
#[cfg(feature = "http-client-curl")]
61+
#[cfg(feature = "http-client")]
6262
use crate::client::http;
6363

64-
#[cfg(feature = "http-client-curl")]
64+
#[cfg(feature = "http-client")]
6565
type HttpError = http::Error;
66-
#[cfg(not(feature = "http-client-curl"))]
66+
#[cfg(not(feature = "http-client"))]
6767
type HttpError = std::convert::Infallible;
6868

6969
/// The error used in most methods of the [`client`][crate::client] module

git-transport/tests/client/blocking_io/http/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,3 +455,15 @@ Git-Protocol: version=2
455455
);
456456
Ok(())
457457
}
458+
459+
#[test]
460+
fn check_content_type_is_case_insensitive() -> crate::Result {
461+
let (_server, mut client) = mock::serve_and_connect(
462+
"v2/http-handshake-lowercase-headers.response",
463+
"path/not/important/due/to/mock",
464+
Protocol::V2,
465+
)?;
466+
let result = client.handshake(Service::UploadPack, &[]);
467+
assert!(result.is_ok());
468+
Ok(())
469+
}

0 commit comments

Comments
 (0)