1 use std
::{borrow::Cow, error::Error}
;
3 use async_trait
::async_trait
;
4 use bstr
::{BStr, BString, ByteVec}
;
5 use futures_io
::{AsyncRead, AsyncWrite}
;
6 use futures_lite
::AsyncWriteExt
;
7 use gix_packetline
::PacketLineRef
;
10 client
::{self, capabilities, git, Capabilities, SetServiceResponse}
,
14 impl<R
, W
> client
::TransportWithoutIO
for git
::Connection
<R
, W
>
17 W
: AsyncWrite
+ Unpin
,
21 write_mode
: client
::WriteMode
,
22 on_into_read
: client
::MessageKind
,
24 ) -> Result
<client
::RequestWriter
<'_
>, client
::Error
> {
25 Ok(client
::RequestWriter
::new_from_bufread(
27 Box
::new(self.line_provider
.as_read_without_sidebands()),
33 fn to_url(&self) -> Cow
<'_
, BStr
> {
34 self.custom_url
.as_ref().map_or_else(
36 let mut possibly_lossy_url
= self.path
.clone();
37 possibly_lossy_url
.insert_str(0, "file://");
38 Cow
::Owned(possibly_lossy_url
)
40 |url
| Cow
::Borrowed(url
.as_ref()),
44 fn connection_persists_across_multiple_requests(&self) -> bool
{
48 fn configure(&mut self, _config
: &dyn std
::any
::Any
) -> Result
<(), Box
<dyn Error
+ Send
+ Sync
+ '
static>> {
54 impl<R
, W
> client
::Transport
for git
::Connection
<R
, W
>
57 W
: AsyncWrite
+ Unpin
,
59 async
fn handshake
<'a
>(
62 extra_parameters
: &'a
[(&'a
str, Option
<&'a
str>)],
63 ) -> Result
<SetServiceResponse
<'_
>, client
::Error
> {
64 if self.mode
== git
::ConnectMode
::Daemon
{
65 let mut line_writer
= gix_packetline
::Writer
::new(&mut self.writer
).binary_mode();
67 .write_all(&git
::message
::connect(
71 self.virtual_host
.as_ref(),
75 line_writer
.flush().await?
;
78 let capabilities
::recv
::Outcome
{
81 protocol
: actual_protocol
,
82 } = Capabilities
::from_lines_with_version_detection(&mut self.line_provider
).await?
;
83 Ok(SetServiceResponse
{
91 impl<R
, W
> git
::Connection
<R
, W
>
94 W
: AsyncWrite
+ Unpin
,
96 /// Create a connection from the given `read` and `write`, asking for `desired_version` as preferred protocol
97 /// and the transfer of the repository at `repository_path`.
99 /// `virtual_host` along with a port to which to connect to, while `mode` determines the kind of endpoint to connect to.
100 /// If `trace` is `true`, all packetlines received or sent will be passed to the facilities of the `gix-trace` crate.
104 desired_version
: Protocol
,
105 repository_path
: impl Into
<BString
>,
106 virtual_host
: Option
<(impl Into
<String
>, Option
<u16>)>,
107 mode
: git
::ConnectMode
,
112 line_provider
: gix_packetline
::StreamingPeekableIter
::new(read
, &[PacketLineRef
::Flush
], trace
),
113 path
: repository_path
.into(),
114 virtual_host
: virtual_host
.map(|(h
, p
)| (h
.into(), p
)),
122 #[cfg(feature = "async-std")]
124 use std
::time
::Duration
;
126 use async_std
::net
::TcpStream
;
128 use crate::client
::{git, Error}
;
130 impl git
::Connection
<TcpStream
, TcpStream
> {
131 /// Create a new TCP connection using the `git` protocol of `desired_version`, and make a connection to `host`
132 /// at `port` for accessing the repository at `path` on the server side.
133 /// If `trace` is `true`, all packetlines received or sent will be passed to the facilities of the `gix-trace` crate.
134 pub async
fn new_tcp(
138 desired_version
: crate::Protocol
,
140 ) -> Result
<git
::Connection
<TcpStream
, TcpStream
>, Error
> {
141 let read
= async_std
::io
::timeout(
142 Duration
::from_secs(5),
143 TcpStream
::connect(&(host
, port
.unwrap_or(9418))),
146 let write
= read
.clone();
147 Ok(git
::Connection
::new(
153 git
::ConnectMode
::Daemon
,