async_ssh2_russh/sftp.rs
1//! SFTP support for the `async_ssh2_russh` crate.
2
3use russh::client::Handler;
4#[doc(no_inline)]
5pub use russh_sftp::client::error::Error as SftpError;
6use russh_sftp::client::SftpSession;
7
8use crate::{AsyncChannel, AsyncSession, SshError};
9
10impl<H: 'static + Handler> AsyncSession<H> {
11 /// Opens an SFTP channel.
12 ///
13 /// Equivalent to [`AsyncSession::open_channel()`] followed by requesting the SFTP subsystem:
14 /// ```rust,ignore
15 /// channel.request_subsystem(true, "sftp").await?;
16 /// ```
17 #[cfg(feature = "sftp")]
18 pub async fn open_sftp(&self) -> Result<SftpSession, SshOrSftpError> {
19 let channel = self.open_channel().await?;
20 channel.request_subsystem(true, "sftp").await?;
21 let sftp = channel.sftp().await?;
22 Ok(sftp)
23 }
24}
25
26impl AsyncChannel {
27 /// Starst an SFTP session on this channel.
28 ///
29 /// Make sure this channel was opened with [`AsyncSession::open_sftp`], or if not, make sure to
30 /// request the SFTP subsystem before calling this:
31 /// ```rust,ignore
32 /// channel.request_subsystem(true, "sftp").await.unwrap();
33 /// ```
34 #[cfg(feature = "sftp")]
35 pub async fn sftp(&self) -> Result<SftpSession, SftpError> {
36 SftpSession::new(tokio::io::join(self.stdout(), self.stdin())).await
37 }
38}
39
40/// Error enum containing either an [`SshError`] or [`SftpError`].
41///
42/// This is used to unify error handling for SSH and SFTP operations.
43#[derive(Debug, thiserror::Error)]
44pub enum SshOrSftpError {
45 /// SSH error.
46 #[error("SSH Error: {0}")]
47 Ssh(#[from] SshError),
48 /// SFTP error.
49 #[error("SFTP Error: {0}")]
50 Sftp(#[from] SftpError),
51}