From 9ee5f41ca59d025c496c6baace61c47eb6beccfc Mon Sep 17 00:00:00 2001 From: Owen Krueger Date: Thu, 30 Jun 2022 10:52:32 -0500 Subject: [PATCH 1/4] Add IBaseClient for BaseClient and ISftpClient to inherit from --- src/Renci.SshNet/BaseClient.cs | 6 +- src/Renci.SshNet/IBaseClient.cs | 104 ++++++++++++++++++++++++++++++++ src/Renci.SshNet/ISftpClient.cs | 2 +- 3 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 src/Renci.SshNet/IBaseClient.cs diff --git a/src/Renci.SshNet/BaseClient.cs b/src/Renci.SshNet/BaseClient.cs index 4e0975b09..a83f16871 100644 --- a/src/Renci.SshNet/BaseClient.cs +++ b/src/Renci.SshNet/BaseClient.cs @@ -13,7 +13,7 @@ namespace Renci.SshNet /// /// Serves as base class for client implementations, provides common client functionality. /// - public abstract class BaseClient : IDisposable + public abstract class BaseClient : IDisposable, IBaseClient { /// /// Holds value indicating whether the connection info is owned by this client. @@ -387,7 +387,7 @@ private void Session_HostKeyReceived(object sender, HostKeyEventArgs e) } } -#region IDisposable Members + #region IDisposable Members private bool _isDisposed; @@ -446,7 +446,7 @@ protected void CheckDisposed() Dispose(false); } -#endregion + #endregion /// /// Stops the keep-alive timer, and waits until all timer callbacks have been diff --git a/src/Renci.SshNet/IBaseClient.cs b/src/Renci.SshNet/IBaseClient.cs new file mode 100644 index 000000000..c11adb4f6 --- /dev/null +++ b/src/Renci.SshNet/IBaseClient.cs @@ -0,0 +1,104 @@ +using Renci.SshNet.Common; +using System; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Renci.SshNet +{ + /// + /// Serves as base class for client implementations, provides common client functionality. + /// + public interface IBaseClient + { + /// + /// Gets the connection info. + /// + /// + /// The connection info. + /// + /// The method was called after the client was disposed. + ConnectionInfo ConnectionInfo { get; } + + /// + /// Gets a value indicating whether this client is connected to the server. + /// + /// + /// true if this client is connected; otherwise, false. + /// + /// The method was called after the client was disposed. + bool IsConnected { get; } + + /// + /// Gets or sets the keep-alive interval. + /// + /// + /// The keep-alive interval. Specify negative one (-1) milliseconds to disable the + /// keep-alive. This is the default value. + /// + /// The method was called after the client was disposed. + TimeSpan KeepAliveInterval { get; set; } + + /// + /// Occurs when an error occurred. + /// + /// + /// + /// + event EventHandler ErrorOccurred; + + /// + /// Occurs when host key received. + /// + /// + /// + /// + event EventHandler HostKeyReceived; + + /// + /// Connects client to the server. + /// + /// The client is already connected. + /// The method was called after the client was disposed. + /// Socket connection to the SSH server or proxy server could not be established, or an error occurred while resolving the hostname. + /// SSH session could not be established. + /// Authentication of SSH session failed. + /// Failed to establish proxy connection. + void Connect(); + + /// + /// Asynchronously connects client to the server. + /// + /// The to observe. + /// A that represents the asynchronous connect operation. + /// + /// The client is already connected. + /// The method was called after the client was disposed. + /// Socket connection to the SSH server or proxy server could not be established, or an error occurred while resolving the hostname. + /// SSH session could not be established. + /// Authentication of SSH session failed. + /// Failed to establish proxy connection. + Task ConnectAsync(CancellationToken cancellationToken); + + /// + /// Disconnects client from the server. + /// + /// The method was called after the client was disposed. + void Disconnect(); + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + void Dispose(); + + /// + /// Sends a keep-alive message to the server. + /// + /// + /// Use to configure the client to send a keep-alive at regular + /// intervals. + /// + /// The method was called after the client was disposed. + void SendKeepAlive(); + } +} \ No newline at end of file diff --git a/src/Renci.SshNet/ISftpClient.cs b/src/Renci.SshNet/ISftpClient.cs index dc2d2c899..29e54c20e 100644 --- a/src/Renci.SshNet/ISftpClient.cs +++ b/src/Renci.SshNet/ISftpClient.cs @@ -14,7 +14,7 @@ namespace Renci.SshNet /// /// Implementation of the SSH File Transfer Protocol (SFTP) over SSH. /// - public interface ISftpClient : IDisposable + public interface ISftpClient : IBaseClient, IDisposable { /// /// Gets or sets the maximum size of the buffer in bytes. From 6bc23f9ec6f9faeb115bef1ae7fc7004eb0ce546 Mon Sep 17 00:00:00 2001 From: Owen Krueger Date: Thu, 30 Jun 2022 11:04:24 -0500 Subject: [PATCH 2/4] Check FEATURE_TAP --- src/Renci.SshNet/IBaseClient.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Renci.SshNet/IBaseClient.cs b/src/Renci.SshNet/IBaseClient.cs index c11adb4f6..bd9518ac4 100644 --- a/src/Renci.SshNet/IBaseClient.cs +++ b/src/Renci.SshNet/IBaseClient.cs @@ -2,7 +2,9 @@ using System; using System.Net.Sockets; using System.Threading; +#if FEATURE_TAP using System.Threading.Tasks; +#endif namespace Renci.SshNet { @@ -66,6 +68,7 @@ public interface IBaseClient /// Failed to establish proxy connection. void Connect(); +#if FEATURE_TAP /// /// Asynchronously connects client to the server. /// @@ -79,6 +82,7 @@ public interface IBaseClient /// Authentication of SSH session failed. /// Failed to establish proxy connection. Task ConnectAsync(CancellationToken cancellationToken); +#endif /// /// Disconnects client from the server. From 78a61b2ff23250aa6cae1037bef4c2ab2050b0ea Mon Sep 17 00:00:00 2001 From: Owen Krueger Date: Thu, 30 Jun 2022 14:07:37 -0500 Subject: [PATCH 3/4] Return ISftFile in ListDirectoryAsync --- src/Renci.SshNet/BaseClient.cs | 2 +- src/Renci.SshNet/ISftpClient.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Renci.SshNet/BaseClient.cs b/src/Renci.SshNet/BaseClient.cs index a83f16871..754396108 100644 --- a/src/Renci.SshNet/BaseClient.cs +++ b/src/Renci.SshNet/BaseClient.cs @@ -13,7 +13,7 @@ namespace Renci.SshNet /// /// Serves as base class for client implementations, provides common client functionality. /// - public abstract class BaseClient : IDisposable, IBaseClient + public abstract class BaseClient : IBaseClient, IDisposable { /// /// Holds value indicating whether the connection info is owned by this client. diff --git a/src/Renci.SshNet/ISftpClient.cs b/src/Renci.SshNet/ISftpClient.cs index 29e54c20e..eda042eff 100644 --- a/src/Renci.SshNet/ISftpClient.cs +++ b/src/Renci.SshNet/ISftpClient.cs @@ -720,7 +720,7 @@ public interface ISftpClient : IBaseClient, IDisposable /// Permission to list the contents of the directory was denied by the remote host. -or- A SSH command was denied by the server. /// A SSH error where is the message from the remote host. /// The method was called after the client was disposed. - Task> ListDirectoryAsync(string path, CancellationToken cancellationToken); + Task> ListDirectoryAsync(string path, CancellationToken cancellationToken); #endif /// From 3a4feb2f2090f03f26aa7aaafac4f6c412ec20d0 Mon Sep 17 00:00:00 2001 From: Owen Krueger Date: Thu, 30 Jun 2022 14:10:28 -0500 Subject: [PATCH 4/4] Change the return type on the implement method as well --- src/Renci.SshNet/SftpClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index d33e21816..a7ce34538 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -552,7 +552,7 @@ public IEnumerable ListDirectory(string path, Action listCallbac /// Permission to list the contents of the directory was denied by the remote host. -or- A SSH command was denied by the server. /// A SSH error where is the message from the remote host. /// The method was called after the client was disposed. - public async Task> ListDirectoryAsync(string path, CancellationToken cancellationToken) + public async Task> ListDirectoryAsync(string path, CancellationToken cancellationToken) { base.CheckDisposed(); if (path == null)