fn exec_request(
        mut self,
        channel: ChannelId,
        data: &[u8],
        mut session: Session,
    ) -> Self::FutureUnit {
        let span = self.span.clone();

        let data = match std::str::from_utf8(data) {
            Ok(data) => data,
            Err(e) => return Box::pin(futures::future::err(e.into())),
        };
        // parses the given args in the same fashion as a POSIX shell
        let args = shlex::split(data);

        Box::pin(async move {
            debug!("exec {:?}", args);

            // if the client didn't send `GIT_PROTOCOL=version=2` as an environment
            // variable when connecting, we'll just close the connection
            if !self.is_git_protocol_v2 {
                anyhow::bail!("not git protocol v2");
            }

            let mut args = args.into_iter().flat_map(Vec::into_iter);

            // check the executable requested to be ran is the `git-upload-pack` we
            // expect. we're not actually going to execute this, but we'll pretend
            // to be it instead in `data`.
            if args.next().as_deref() != Some("git-upload-pack") {
                anyhow::bail!("not git-upload-pack");
            }

            // parse the requested organisation from the given path (the argument
            // given to `git-upload-pack`)
            if let Some(org) = args.next().filter(|v| v.as_str() != "/") {
                let org = org
                    .trim_start_matches('/')
                    .trim_end_matches('/')
                    .to_string();
                self.organisation = Some(org);
            } else {
                session.extended_data(channel, 1, CryptoVec::from_slice(indoc::indoc! {b"
                    \r\nNo organisation was given in the path part of the SSH URI. A chartered registry should be defined in your .cargo/config.toml as follows:
                        [registries]
                        chartered = {{ index = \"ssh://domain.to.registry.com/my-organisation\" }}\r\n
                "}));
                session.close(channel);
            }

            // preamble, sending our capabilities and what have you
            self.write(PktLine::Data(b"version 2\n"))?;
            self.write(PktLine::Data(AGENT.as_bytes()))?;
            self.write(PktLine::Data(b"ls-refs=unborn\n"))?;
            self.write(PktLine::Data(b"fetch=shallow wait-for-done\n"))?;
            self.write(PktLine::Data(b"server-option\n"))?;
            self.write(PktLine::Data(b"object-info\n"))?;
            self.write(PktLine::Flush)?;
            self.flush(&mut session, channel);

            Ok((self, session))
        }.instrument(tracing::info_span!(parent: span, "exec")))
    }
/// Initially when setting up the SSH connection, the remote Git client will send us an
/// exec request (instead of the usual shell request that is sent when invoking `ssh`).
///
/// The client will set `git-upload-pack` as the requested executable to run and also
/// sends the path that was appended to the end of the connection string defined in
/// cargo.
Initially when setting up the SSH connection, the remote Git client will send us an
exec request (instead of the usual shell request that is sent when invoking `ssh`).

The client will set `git-upload-pack` as the requested executable to run and also
sends the path that was appended to the end of the connection string defined in
cargo.
Initially when setting up the SSH connection the remote Git client will send us an exec request ( instead of the usual shell request that is sent when invoking ` ssh ` ) . The client will set ` git - upload - pack ` as the requested executable to run and also sends the path that was appended to the end of the connection string defined in cargo .
fn exec_request(
        mut self,
        channel: ChannelId,
        data: &[u8],
        mut session: Session,
    ) -> Self::FutureUnit {
        let span = self.span.clone();
        let data = match std::str::from_utf8(data) {
            Ok(data) => data,
            Err(e) => return Box::pin(futures::future::err(e.into())),
        };
        // parses the given args in the same fashion as a POSIX shell
        let args = shlex::split(data);
        Box::pin(async move {
            debug!("exec {:?}", args);
            // if the client didn't send `GIT_PROTOCOL=version=2` as an environment
            // variable when connecting, we'll just close the connection
            if !self.is_git_protocol_v2 {
                anyhow::bail!("not git protocol v2");
            }
            let mut args = args.into_iter().flat_map(Vec::into_iter);
            // check the executable requested to be ran is the `git-upload-pack` we
            // expect. we're not actually going to execute this, but we'll pretend
            // to be it instead in `data`.
            if args.next().as_deref() != Some("git-upload-pack") {
                anyhow::bail!("not git-upload-pack");
            }
            // parse the requested organisation from the given path (the argument
            // given to `git-upload-pack`)
            if let Some(org) = args.next().filter(|v| v.as_str() != "/") {
                let org = org
                    .trim_start_matches('/')
                    .trim_end_matches('/')
                    .to_string();
                self.organisation = Some(org);
            } else {
                session.extended_data(channel, 1, CryptoVec::from_slice(indoc::indoc! {b"
                    \r\nNo organisation was given in the path part of the SSH URI. A chartered registry should be defined in your .cargo/config.toml as follows:
                        [registries]
                        chartered = {{ index = \"ssh://domain.to.registry.com/my-organisation\" }}\r\n
                "}));
                session.close(channel);
            }
            // preamble, sending our capabilities and what have you
            self.write(PktLine::Data(b"version 2\n"))?;
            self.write(PktLine::Data(AGENT.as_bytes()))?;
            self.write(PktLine::Data(b"ls-refs=unborn\n"))?;
            self.write(PktLine::Data(b"fetch=shallow wait-for-done\n"))?;
            self.write(PktLine::Data(b"server-option\n"))?;
            self.write(PktLine::Data(b"object-info\n"))?;
            self.write(PktLine::Flush)?;
            self.flush(&mut session, channel);
            Ok((self, session))
        }.instrument(tracing::info_span!(parent: span, "exec")))
    }
fn exec_request ( mut self , channel : ChannelId , data : & [ u8 ] , mut session : Session , ) -> Self :: FutureUnit { let span = self . span . clone ( ) ; let data = match std :: str :: from_utf8 ( data ) { Ok ( data ) => data , Err ( e ) => return Box :: pin ( futures :: future :: err ( e . into ( ) ) ) , } ; // parses the given args in the same fashion as a POSIX shell let args = shlex :: split ( data ) ; Box :: pin ( async move { debug ! ( " " args ) ; // if the client didn't send `GIT_PROTOCOL=version=2` as an environment // variable when connecting, we'll just close the connection if ! self . is_git_protocol_v2 { anyhow :: bail ! ( " " ) ; } let mut args = args . into_iter ( ) . flat_map ( Vec :: into_iter ) ; // check the executable requested to be ran is the `git-upload-pack` we // expect. we're not actually going to execute this, but we'll pretend // to be it instead in `data`. if args . next ( ) . as_deref ( ) != Some ( " " ) { anyhow :: bail ! ( " " ) ; } // parse the requested organisation from the given path (the argument // given to `git-upload-pack`) if let Some ( org ) = args . next ( ) . filter ( | v | v . as_str ( ) != " " ) { let org = org . trim_start_matches ( '/' ) . trim_end_matches ( '/' ) . to_string ( ) ; self . organisation = Some ( org ) ; } else { session . extended_data ( channel , 1 , CryptoVec :: from_slice ( indoc :: indoc ! { b" \r \n \" \" \r \n " } ) ) ; session . close ( channel ) ; } // preamble, sending our capabilities and what have you self . write ( PktLine :: Data ( b" \n " ) ) ? ; self . write ( PktLine :: Data ( AGENT . as_bytes ( ) ) ) ? ; self . write ( PktLine :: Data ( b" \n " ) ) ? ; self . write ( PktLine :: Data ( b" \n " ) ) ? ; self . write ( PktLine :: Data ( b" \n " ) ) ? ; self . write ( PktLine :: Data ( b" \n " ) ) ? ; self . write ( PktLine :: Flush ) ? ; self . flush ( & mut session , channel ) ; Ok ( ( self , session ) ) } . instrument ( tracing :: info_span ! ( parent span " " ) ) ) }
Initially when setting up the SSH connection, the remote Git client will send us an
exec request (instead of the usual shell request that is sent when invoking `ssh`).
Initially when setting up the SSH connection the remote Git client will send us an exec request ( instead of the usual shell request that is sent when invoking ` ssh ` ) .
mut self
channel
ChannelId
data
&[u8]
session
Session
mut self
channel
ChannelId
data
&[u8]
session
Session