From db6897deef55dce73dd416892450fe7acb85bdce Mon Sep 17 00:00:00 2001 From: "IngSoft, Patrick Thoma" Date: Fri, 13 Oct 2023 16:48:14 +0200 Subject: [PATCH 1/6] Enable ListDirectoryAsync for .NET Framework --- .../Classes/SftpClientTest.ListDirectory.cs | 23 +- src/Renci.SshNet/Renci.SshNet.csproj | 4 + src/Renci.SshNet/SftpClient.cs | 275 ++++++++---------- 3 files changed, 145 insertions(+), 157 deletions(-) diff --git a/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs b/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs index ceafd4c50..63afb33bb 100644 --- a/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs +++ b/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs @@ -1,9 +1,12 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + using Renci.SshNet.Common; using Renci.SshNet.Tests.Properties; -using System.Diagnostics; - namespace Renci.SshNet.Tests.Classes { /// @@ -25,5 +28,19 @@ public void Test_Sftp_ListDirectory_Without_Connecting() } } } + + [TestMethod] + [TestCategory("Sftp")] + [ExpectedException(typeof(SshConnectionException))] + public async Task Test_Sftp_ListDirectoryAsync_Without_Connecting() + { + using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + { + await foreach (var file in sftp.ListDirectoryAsync(".", CancellationToken.None)) + { + Debug.WriteLine(file.FullName); + } + } + } } } diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index e55911d55..324e3722a 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -13,6 +13,10 @@ + + + + FEATURE_SOCKET_TAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_EAP;FEATURE_DNS_SYNC;FEATURE_DNS_APM;FEATURE_DNS_TAP diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 877fed092..03c60c630 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -1,18 +1,17 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.IO; using System.Globalization; +using System.IO; using System.Net; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; +using System.Threading.Tasks; + using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Sftp; -using System.Threading.Tasks; -#if FEATURE_ASYNC_ENUMERABLE -using System.Runtime.CompilerServices; -#endif + namespace Renci.SshNet { @@ -23,12 +22,6 @@ public class SftpClient : BaseClient, ISftpClient { private static readonly Encoding Utf8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); - /// - /// Holds the instance that is used to communicate to the - /// SFTP server. - /// - private ISftpSession _sftpSession; - /// /// Holds the operation timeout. /// @@ -126,12 +119,7 @@ public string WorkingDirectory { CheckDisposed(); - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - return _sftpSession.WorkingDirectory; + return SftpSession is null ? throw new SshConnectionException("Client not connected.") : SftpSession.WorkingDirectory; } } @@ -146,12 +134,7 @@ public int ProtocolVersion { CheckDisposed(); - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - return (int) _sftpSession.ProtocolVersion; + return SftpSession is null ? throw new SshConnectionException("Client not connected.") : (int) SftpSession.ProtocolVersion; } } @@ -161,10 +144,7 @@ public int ProtocolVersion /// /// The current SFTP session. /// - internal ISftpSession SftpSession - { - get { return _sftpSession; } - } + internal ISftpSession SftpSession { get; private set; } #region Constructors @@ -188,7 +168,6 @@ public SftpClient(ConnectionInfo connectionInfo) /// is null. /// is invalid. -or- is null or contains only whitespace characters. /// is not within and . - [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] public SftpClient(string host, int port, string username, string password) : this(new PasswordConnectionInfo(host, port, username, password), ownsConnectionInfo: true) { @@ -217,7 +196,6 @@ public SftpClient(string host, string username, string password) /// is null. /// is invalid. -or- is nunullll or contains only whitespace characters. /// is not within and . - [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] public SftpClient(string host, int port, string username, params IPrivateKeySource[] keyFiles) : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), ownsConnectionInfo: true) { @@ -291,12 +269,12 @@ public void ChangeDirectory(string path) throw new ArgumentNullException(nameof(path)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - _sftpSession.ChangeDirectory(path); + SftpSession.ChangeDirectory(path); } /// @@ -334,14 +312,14 @@ public void CreateDirectory(string path) throw new ArgumentException(path); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - _sftpSession.RequestMkDir(fullPath); + SftpSession.RequestMkDir(fullPath); } /// @@ -363,14 +341,14 @@ public void DeleteDirectory(string path) throw new ArgumentException("path"); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - _sftpSession.RequestRmDir(fullPath); + SftpSession.RequestRmDir(fullPath); } /// @@ -392,14 +370,14 @@ public void DeleteFile(string path) throw new ArgumentException("path"); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - _sftpSession.RequestRemove(fullPath); + SftpSession.RequestRemove(fullPath); } /// @@ -423,15 +401,15 @@ public async Task DeleteFileAsync(string path, CancellationToken cancellationTok throw new ArgumentException("path"); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); - await _sftpSession.RequestRemoveAsync(fullPath, cancellationToken).ConfigureAwait(false); + var fullPath = await SftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); + await SftpSession.RequestRemoveAsync(fullPath, cancellationToken).ConfigureAwait(false); } /// @@ -475,16 +453,16 @@ public async Task RenameFileAsync(string oldPath, string newPath, CancellationTo throw new ArgumentNullException(nameof(newPath)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - var oldFullPath = await _sftpSession.GetCanonicalPathAsync(oldPath, cancellationToken).ConfigureAwait(false); - var newFullPath = await _sftpSession.GetCanonicalPathAsync(newPath, cancellationToken).ConfigureAwait(false); - await _sftpSession.RequestRenameAsync(oldFullPath, newFullPath, cancellationToken).ConfigureAwait(false); + var oldFullPath = await SftpSession.GetCanonicalPathAsync(oldPath, cancellationToken).ConfigureAwait(false); + var newFullPath = await SftpSession.GetCanonicalPathAsync(newPath, cancellationToken).ConfigureAwait(false); + await SftpSession.RequestRenameAsync(oldFullPath, newFullPath, cancellationToken).ConfigureAwait(false); } /// @@ -512,22 +490,22 @@ public void RenameFile(string oldPath, string newPath, bool isPosix) throw new ArgumentNullException(nameof(newPath)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var oldFullPath = _sftpSession.GetCanonicalPath(oldPath); + var oldFullPath = SftpSession.GetCanonicalPath(oldPath); - var newFullPath = _sftpSession.GetCanonicalPath(newPath); + var newFullPath = SftpSession.GetCanonicalPath(newPath); if (isPosix) { - _sftpSession.RequestPosixRename(oldFullPath, newFullPath); + SftpSession.RequestPosixRename(oldFullPath, newFullPath); } else { - _sftpSession.RequestRename(oldFullPath, newFullPath); + SftpSession.RequestRename(oldFullPath, newFullPath); } } @@ -555,16 +533,16 @@ public void SymbolicLink(string path, string linkPath) throw new ArgumentException("linkPath"); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - var linkFullPath = _sftpSession.GetCanonicalPath(linkPath); + var linkFullPath = SftpSession.GetCanonicalPath(linkPath); - _sftpSession.RequestSymLink(fullPath, linkFullPath); + SftpSession.RequestSymLink(fullPath, linkFullPath); } /// @@ -587,7 +565,6 @@ public IEnumerable ListDirectory(string path, Action listCallbac return InternalListDirectory(path, listCallback); } -#if FEATURE_ASYNC_ENUMERABLE /// /// Asynchronously enumerates the files in remote directory. /// @@ -611,16 +588,16 @@ public async IAsyncEnumerable ListDirectoryAsync(string path, [Enumer throw new ArgumentNullException(nameof(path)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); + var fullPath = await SftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); - var handle = await _sftpSession.RequestOpenDirAsync(fullPath, cancellationToken).ConfigureAwait(false); + var handle = await SftpSession.RequestOpenDirAsync(fullPath, cancellationToken).ConfigureAwait(false); try { var basePath = (fullPath[fullPath.Length - 1] == '/') ? @@ -629,7 +606,7 @@ public async IAsyncEnumerable ListDirectoryAsync(string path, [Enumer while (true) { - var files = await _sftpSession.RequestReadDirAsync(handle, cancellationToken).ConfigureAwait(false); + var files = await SftpSession.RequestReadDirAsync(handle, cancellationToken).ConfigureAwait(false); if (files is null) { break; @@ -637,16 +614,15 @@ public async IAsyncEnumerable ListDirectoryAsync(string path, [Enumer foreach (var file in files) { - yield return new SftpFile(_sftpSession, basePath + file.Key, file.Value); + yield return new SftpFile(SftpSession, basePath + file.Key, file.Value); } } } finally { - await _sftpSession.RequestCloseAsync(handle, cancellationToken).ConfigureAwait(false); + await SftpSession.RequestCloseAsync(handle, cancellationToken).ConfigureAwait(false); } } -#endif //FEATURE_ASYNC_ENUMERABLE /// /// Begins an asynchronous operation of retrieving list of files in remote directory. @@ -726,16 +702,16 @@ public ISftpFile Get(string path) throw new ArgumentNullException(nameof(path)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - var attributes = _sftpSession.RequestLStat(fullPath); + var attributes = SftpSession.RequestLStat(fullPath); - return new SftpFile(_sftpSession, fullPath, attributes); + return new SftpFile(SftpSession, fullPath, attributes); } /// @@ -759,12 +735,12 @@ public bool Exists(string path) throw new ArgumentException("path"); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); // using SSH_FXP_REALPATH is not an alternative as the SFTP specification has not always // been clear on how the server should respond when the specified path is not present on @@ -785,7 +761,7 @@ public bool Exists(string path) try { - _ = _sftpSession.RequestLStat(fullPath); + _ = SftpSession.RequestLStat(fullPath); return true; } catch (SftpPathNotFoundException) @@ -1133,10 +1109,10 @@ public IAsyncResult BeginUploadFile(Stream input, string path, bool canOverride, try { InternalUploadFile(input, path, flags, asyncResult, offset => - { - asyncResult.Update(offset); - uploadCallback?.Invoke(offset); - }); + { + asyncResult.Update(offset); + uploadCallback?.Invoke(offset); + }); asyncResult.SetAsCompleted(exception: null, completedSynchronously: false); } @@ -1188,14 +1164,14 @@ public SftpFileSytemInformation GetStatus(string path) throw new ArgumentNullException(nameof(path)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - return _sftpSession.RequestStatVfs(fullPath); + return SftpSession.RequestStatVfs(fullPath); } /// @@ -1219,15 +1195,15 @@ public async Task GetStatusAsync(string path, Cancella throw new ArgumentNullException(nameof(path)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); - return await _sftpSession.RequestStatVfsAsync(fullPath, cancellationToken).ConfigureAwait(false); + var fullPath = await SftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); + return await SftpSession.RequestStatVfsAsync(fullPath, cancellationToken).ConfigureAwait(false); } #region File Methods @@ -1363,12 +1339,9 @@ public StreamWriter AppendText(string path, Encoding encoding) { CheckDisposed(); - if (encoding is null) - { - throw new ArgumentNullException(nameof(encoding)); - } - - return new StreamWriter(new SftpFileStream(_sftpSession, path, FileMode.Append, FileAccess.Write, (int) _bufferSize), encoding); + return encoding is null + ? throw new ArgumentNullException(nameof(encoding)) + : new StreamWriter(new SftpFileStream(SftpSession, path, FileMode.Append, FileAccess.Write, (int) _bufferSize), encoding); } /// @@ -1389,7 +1362,7 @@ public SftpFileStream Create(string path) { CheckDisposed(); - return new SftpFileStream(_sftpSession, path, FileMode.Create, FileAccess.ReadWrite, (int) _bufferSize); + return new SftpFileStream(SftpSession, path, FileMode.Create, FileAccess.ReadWrite, (int) _bufferSize); } /// @@ -1411,7 +1384,7 @@ public SftpFileStream Create(string path, int bufferSize) { CheckDisposed(); - return new SftpFileStream(_sftpSession, path, FileMode.Create, FileAccess.ReadWrite, bufferSize); + return new SftpFileStream(SftpSession, path, FileMode.Create, FileAccess.ReadWrite, bufferSize); } /// @@ -1580,7 +1553,7 @@ public SftpFileStream Open(string path, FileMode mode, FileAccess access) { CheckDisposed(); - return new SftpFileStream(_sftpSession, path, mode, access, (int) _bufferSize); + return new SftpFileStream(SftpSession, path, mode, access, (int) _bufferSize); } /// @@ -1606,14 +1579,14 @@ public Task OpenAsync(string path, FileMode mode, FileAccess acc throw new ArgumentNullException(nameof(path)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - return SftpFileStream.OpenAsync(_sftpSession, path, mode, access, (int)_bufferSize, cancellationToken); + return SftpFileStream.OpenAsync(SftpSession, path, mode, access, (int) _bufferSize, cancellationToken); } /// @@ -1663,7 +1636,7 @@ public SftpFileStream OpenWrite(string path) { CheckDisposed(); - return new SftpFileStream(_sftpSession, path, FileMode.OpenOrCreate, FileAccess.Write, (int) _bufferSize); + return new SftpFileStream(SftpSession, path, FileMode.OpenOrCreate, FileAccess.Write, (int) _bufferSize); } /// @@ -2046,14 +2019,14 @@ public SftpFileAttributes GetAttributes(string path) { CheckDisposed(); - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - return _sftpSession.RequestLStat(fullPath); + return SftpSession.RequestLStat(fullPath); } /// @@ -2068,14 +2041,14 @@ public void SetAttributes(string path, SftpFileAttributes fileAttributes) { CheckDisposed(); - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - _sftpSession.RequestSetStat(fullPath, fileAttributes); + SftpSession.RequestSetStat(fullPath, fileAttributes); } // Please don't forget this when you implement these methods: is null. @@ -2106,17 +2079,11 @@ public void SetAttributes(string path, SftpFileAttributes fileAttributes) /// If a problem occurs while copying the file public IEnumerable SynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern) { - if (sourcePath is null) - { - throw new ArgumentNullException(nameof(sourcePath)); - } - - if (string.IsNullOrWhiteSpace(destinationPath)) - { - throw new ArgumentException("destinationPath"); - } - - return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asynchResult: null); + return sourcePath is null + ? throw new ArgumentNullException(nameof(sourcePath)) + : string.IsNullOrWhiteSpace(destinationPath) + ? throw new ArgumentException("destinationPath") + : InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asynchResult: null); } /// @@ -2148,18 +2115,18 @@ public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destin var asyncResult = new SftpSynchronizeDirectoriesAsyncResult(asyncCallback, state); ThreadAbstraction.ExecuteThread(() => + { + try { - try - { - var result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult); + var result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult); - asyncResult.SetAsCompleted(result, completedSynchronously: false); - } - catch (Exception exp) - { - asyncResult.SetAsCompleted(exp, completedSynchronously: false); - } - }); + asyncResult.SetAsCompleted(result, completedSynchronously: false); + } + catch (Exception exp) + { + asyncResult.SetAsCompleted(exp, completedSynchronously: false); + } + }); return asyncResult; } @@ -2284,14 +2251,14 @@ private IEnumerable InternalListDirectory(string path, Action li throw new ArgumentNullException(nameof(path)); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - var handle = _sftpSession.RequestOpenDir(fullPath); + var handle = SftpSession.RequestOpenDir(fullPath); var basePath = fullPath; @@ -2302,13 +2269,13 @@ private IEnumerable InternalListDirectory(string path, Action li var result = new List(); - var files = _sftpSession.RequestReadDir(handle); + var files = SftpSession.RequestReadDir(handle); while (files is not null) { foreach (var f in files) { - result.Add(new SftpFile(_sftpSession, + result.Add(new SftpFile(SftpSession, string.Format(CultureInfo.InvariantCulture, "{0}{1}", basePath, f.Key), f.Value)); } @@ -2320,10 +2287,10 @@ private IEnumerable InternalListDirectory(string path, Action li ThreadAbstraction.ExecuteThread(() => listCallback(result.Count)); } - files = _sftpSession.RequestReadDir(handle); + files = SftpSession.RequestReadDir(handle); } - _sftpSession.RequestClose(handle); + SftpSession.RequestClose(handle); return result; } @@ -2350,14 +2317,14 @@ private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncR throw new ArgumentException("path"); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - using (var fileReader = ServiceFactory.CreateSftpFileReader(fullPath, _sftpSession, _bufferSize)) + using (var fileReader = ServiceFactory.CreateSftpFileReader(fullPath, SftpSession, _bufferSize)) { var totalBytesRead = 0UL; @@ -2414,19 +2381,19 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo throw new ArgumentException("path"); } - if (_sftpSession is null) + if (SftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = _sftpSession.GetCanonicalPath(path); + var fullPath = SftpSession.GetCanonicalPath(path); - var handle = _sftpSession.RequestOpen(fullPath, flags); + var handle = SftpSession.RequestOpen(fullPath, flags); ulong offset = 0; // create buffer of optimal length - var buffer = new byte[_sftpSession.CalculateOptimalWriteLength(_bufferSize, handle)]; + var buffer = new byte[SftpSession.CalculateOptimalWriteLength(_bufferSize, handle)]; var bytesRead = input.Read(buffer, 0, buffer.Length); var expectedResponses = 0; @@ -2444,21 +2411,21 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo { var writtenBytes = offset + (ulong) bytesRead; - _sftpSession.RequestWrite(handle, offset, buffer, offset: 0, bytesRead, wait: null, s => + SftpSession.RequestWrite(handle, offset, buffer, offset: 0, bytesRead, wait: null, s => + { + if (s.StatusCode == StatusCodes.Ok) { - if (s.StatusCode == StatusCodes.Ok) + _ = Interlocked.Decrement(ref expectedResponses); + _ = responseReceivedWaitHandle.Set(); + + // Call callback to report number of bytes written + if (uploadCallback is not null) { - _ = Interlocked.Decrement(ref expectedResponses); - _ = responseReceivedWaitHandle.Set(); - - // Call callback to report number of bytes written - if (uploadCallback is not null) - { - // Execute callback on different thread - ThreadAbstraction.ExecuteThread(() => uploadCallback(writtenBytes)); - } + // Execute callback on different thread + ThreadAbstraction.ExecuteThread(() => uploadCallback(writtenBytes)); } - }); + } + }); _ = Interlocked.Increment(ref expectedResponses); @@ -2469,12 +2436,12 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo else if (expectedResponses > 0) { // Wait for expectedResponses to change - _sftpSession.WaitOnHandle(responseReceivedWaitHandle, _operationTimeout); + SftpSession.WaitOnHandle(responseReceivedWaitHandle, _operationTimeout); } } while (expectedResponses > 0 || bytesRead > 0); - _sftpSession.RequestClose(handle); + SftpSession.RequestClose(handle); } /// @@ -2484,7 +2451,7 @@ protected override void OnConnected() { base.OnConnected(); - _sftpSession = CreateAndConnectToSftpSession(); + SftpSession = CreateAndConnectToSftpSession(); } /// @@ -2496,10 +2463,10 @@ protected override void OnDisconnecting() // disconnect, dispose and dereference the SFTP session since we create a new SFTP session // on each connect - var sftpSession = _sftpSession; + var sftpSession = SftpSession; if (sftpSession is not null) { - _sftpSession = null; + SftpSession = null; sftpSession.Dispose(); } } @@ -2514,10 +2481,10 @@ protected override void Dispose(bool disposing) if (disposing) { - var sftpSession = _sftpSession; + var sftpSession = SftpSession; if (sftpSession is not null) { - _sftpSession = null; + SftpSession = null; sftpSession.Dispose(); } } From 68f1640959382551a2ae809f897742a6983239f3 Mon Sep 17 00:00:00 2001 From: "IngSoft, Patrick Thoma" Date: Fri, 13 Oct 2023 16:55:04 +0200 Subject: [PATCH 2/6] Deactivated Visual Studios cleanup on save. --- src/Renci.SshNet/ISftpClient.cs | 2 - src/Renci.SshNet/SftpClient.cs | 221 ++++++++++++++++++-------------- 2 files changed, 125 insertions(+), 98 deletions(-) diff --git a/src/Renci.SshNet/ISftpClient.cs b/src/Renci.SshNet/ISftpClient.cs index 29f958d9f..b79a22793 100644 --- a/src/Renci.SshNet/ISftpClient.cs +++ b/src/Renci.SshNet/ISftpClient.cs @@ -700,7 +700,6 @@ public interface ISftpClient : IBaseClient, IDisposable /// The method was called after the client was disposed. IEnumerable ListDirectory(string path, Action listCallback = null); -#if FEATURE_ASYNC_ENUMERABLE /// /// Asynchronously enumerates the files in remote directory. /// @@ -716,7 +715,6 @@ public interface ISftpClient : IBaseClient, IDisposable /// A SSH error where is the message from the remote host. /// The method was called after the client was disposed. IAsyncEnumerable ListDirectoryAsync(string path, CancellationToken cancellationToken); -#endif //FEATURE_ASYNC_ENUMERABLE /// /// Opens a on the specified path with read/write access. diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 03c60c630..99fc3da02 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -1,17 +1,16 @@ using System; using System.Collections.Generic; -using System.Globalization; +using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Globalization; using System.Net; -using System.Runtime.CompilerServices; using System.Text; using System.Threading; -using System.Threading.Tasks; - using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Sftp; - +using System.Threading.Tasks; +using System.Runtime.CompilerServices; namespace Renci.SshNet { @@ -22,6 +21,12 @@ public class SftpClient : BaseClient, ISftpClient { private static readonly Encoding Utf8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); + /// + /// Holds the instance that is used to communicate to the + /// SFTP server. + /// + private ISftpSession _sftpSession; + /// /// Holds the operation timeout. /// @@ -119,7 +124,12 @@ public string WorkingDirectory { CheckDisposed(); - return SftpSession is null ? throw new SshConnectionException("Client not connected.") : SftpSession.WorkingDirectory; + if (_sftpSession is null) + { + throw new SshConnectionException("Client not connected."); + } + + return _sftpSession.WorkingDirectory; } } @@ -134,7 +144,12 @@ public int ProtocolVersion { CheckDisposed(); - return SftpSession is null ? throw new SshConnectionException("Client not connected.") : (int) SftpSession.ProtocolVersion; + if (_sftpSession is null) + { + throw new SshConnectionException("Client not connected."); + } + + return (int) _sftpSession.ProtocolVersion; } } @@ -144,7 +159,10 @@ public int ProtocolVersion /// /// The current SFTP session. /// - internal ISftpSession SftpSession { get; private set; } + internal ISftpSession SftpSession + { + get { return _sftpSession; } + } #region Constructors @@ -168,6 +186,7 @@ public SftpClient(ConnectionInfo connectionInfo) /// is null. /// is invalid. -or- is null or contains only whitespace characters. /// is not within and . + [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] public SftpClient(string host, int port, string username, string password) : this(new PasswordConnectionInfo(host, port, username, password), ownsConnectionInfo: true) { @@ -196,6 +215,7 @@ public SftpClient(string host, string username, string password) /// is null. /// is invalid. -or- is nunullll or contains only whitespace characters. /// is not within and . + [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] public SftpClient(string host, int port, string username, params IPrivateKeySource[] keyFiles) : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), ownsConnectionInfo: true) { @@ -269,12 +289,12 @@ public void ChangeDirectory(string path) throw new ArgumentNullException(nameof(path)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - SftpSession.ChangeDirectory(path); + _sftpSession.ChangeDirectory(path); } /// @@ -312,14 +332,14 @@ public void CreateDirectory(string path) throw new ArgumentException(path); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - SftpSession.RequestMkDir(fullPath); + _sftpSession.RequestMkDir(fullPath); } /// @@ -341,14 +361,14 @@ public void DeleteDirectory(string path) throw new ArgumentException("path"); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - SftpSession.RequestRmDir(fullPath); + _sftpSession.RequestRmDir(fullPath); } /// @@ -370,14 +390,14 @@ public void DeleteFile(string path) throw new ArgumentException("path"); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - SftpSession.RequestRemove(fullPath); + _sftpSession.RequestRemove(fullPath); } /// @@ -401,15 +421,15 @@ public async Task DeleteFileAsync(string path, CancellationToken cancellationTok throw new ArgumentException("path"); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - var fullPath = await SftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); - await SftpSession.RequestRemoveAsync(fullPath, cancellationToken).ConfigureAwait(false); + var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); + await _sftpSession.RequestRemoveAsync(fullPath, cancellationToken).ConfigureAwait(false); } /// @@ -453,16 +473,16 @@ public async Task RenameFileAsync(string oldPath, string newPath, CancellationTo throw new ArgumentNullException(nameof(newPath)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - var oldFullPath = await SftpSession.GetCanonicalPathAsync(oldPath, cancellationToken).ConfigureAwait(false); - var newFullPath = await SftpSession.GetCanonicalPathAsync(newPath, cancellationToken).ConfigureAwait(false); - await SftpSession.RequestRenameAsync(oldFullPath, newFullPath, cancellationToken).ConfigureAwait(false); + var oldFullPath = await _sftpSession.GetCanonicalPathAsync(oldPath, cancellationToken).ConfigureAwait(false); + var newFullPath = await _sftpSession.GetCanonicalPathAsync(newPath, cancellationToken).ConfigureAwait(false); + await _sftpSession.RequestRenameAsync(oldFullPath, newFullPath, cancellationToken).ConfigureAwait(false); } /// @@ -490,22 +510,22 @@ public void RenameFile(string oldPath, string newPath, bool isPosix) throw new ArgumentNullException(nameof(newPath)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var oldFullPath = SftpSession.GetCanonicalPath(oldPath); + var oldFullPath = _sftpSession.GetCanonicalPath(oldPath); - var newFullPath = SftpSession.GetCanonicalPath(newPath); + var newFullPath = _sftpSession.GetCanonicalPath(newPath); if (isPosix) { - SftpSession.RequestPosixRename(oldFullPath, newFullPath); + _sftpSession.RequestPosixRename(oldFullPath, newFullPath); } else { - SftpSession.RequestRename(oldFullPath, newFullPath); + _sftpSession.RequestRename(oldFullPath, newFullPath); } } @@ -533,16 +553,16 @@ public void SymbolicLink(string path, string linkPath) throw new ArgumentException("linkPath"); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - var linkFullPath = SftpSession.GetCanonicalPath(linkPath); + var linkFullPath = _sftpSession.GetCanonicalPath(linkPath); - SftpSession.RequestSymLink(fullPath, linkFullPath); + _sftpSession.RequestSymLink(fullPath, linkFullPath); } /// @@ -588,16 +608,16 @@ public async IAsyncEnumerable ListDirectoryAsync(string path, [Enumer throw new ArgumentNullException(nameof(path)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - var fullPath = await SftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); + var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); - var handle = await SftpSession.RequestOpenDirAsync(fullPath, cancellationToken).ConfigureAwait(false); + var handle = await _sftpSession.RequestOpenDirAsync(fullPath, cancellationToken).ConfigureAwait(false); try { var basePath = (fullPath[fullPath.Length - 1] == '/') ? @@ -606,7 +626,7 @@ public async IAsyncEnumerable ListDirectoryAsync(string path, [Enumer while (true) { - var files = await SftpSession.RequestReadDirAsync(handle, cancellationToken).ConfigureAwait(false); + var files = await _sftpSession.RequestReadDirAsync(handle, cancellationToken).ConfigureAwait(false); if (files is null) { break; @@ -614,13 +634,13 @@ public async IAsyncEnumerable ListDirectoryAsync(string path, [Enumer foreach (var file in files) { - yield return new SftpFile(SftpSession, basePath + file.Key, file.Value); + yield return new SftpFile(_sftpSession, basePath + file.Key, file.Value); } } } finally { - await SftpSession.RequestCloseAsync(handle, cancellationToken).ConfigureAwait(false); + await _sftpSession.RequestCloseAsync(handle, cancellationToken).ConfigureAwait(false); } } @@ -702,16 +722,16 @@ public ISftpFile Get(string path) throw new ArgumentNullException(nameof(path)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - var attributes = SftpSession.RequestLStat(fullPath); + var attributes = _sftpSession.RequestLStat(fullPath); - return new SftpFile(SftpSession, fullPath, attributes); + return new SftpFile(_sftpSession, fullPath, attributes); } /// @@ -735,12 +755,12 @@ public bool Exists(string path) throw new ArgumentException("path"); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); // using SSH_FXP_REALPATH is not an alternative as the SFTP specification has not always // been clear on how the server should respond when the specified path is not present on @@ -761,7 +781,7 @@ public bool Exists(string path) try { - _ = SftpSession.RequestLStat(fullPath); + _ = _sftpSession.RequestLStat(fullPath); return true; } catch (SftpPathNotFoundException) @@ -1164,14 +1184,14 @@ public SftpFileSytemInformation GetStatus(string path) throw new ArgumentNullException(nameof(path)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - return SftpSession.RequestStatVfs(fullPath); + return _sftpSession.RequestStatVfs(fullPath); } /// @@ -1195,15 +1215,15 @@ public async Task GetStatusAsync(string path, Cancella throw new ArgumentNullException(nameof(path)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - var fullPath = await SftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); - return await SftpSession.RequestStatVfsAsync(fullPath, cancellationToken).ConfigureAwait(false); + var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false); + return await _sftpSession.RequestStatVfsAsync(fullPath, cancellationToken).ConfigureAwait(false); } #region File Methods @@ -1339,9 +1359,12 @@ public StreamWriter AppendText(string path, Encoding encoding) { CheckDisposed(); - return encoding is null - ? throw new ArgumentNullException(nameof(encoding)) - : new StreamWriter(new SftpFileStream(SftpSession, path, FileMode.Append, FileAccess.Write, (int) _bufferSize), encoding); + if (encoding is null) + { + throw new ArgumentNullException(nameof(encoding)); + } + + return new StreamWriter(new SftpFileStream(_sftpSession, path, FileMode.Append, FileAccess.Write, (int) _bufferSize), encoding); } /// @@ -1362,7 +1385,7 @@ public SftpFileStream Create(string path) { CheckDisposed(); - return new SftpFileStream(SftpSession, path, FileMode.Create, FileAccess.ReadWrite, (int) _bufferSize); + return new SftpFileStream(_sftpSession, path, FileMode.Create, FileAccess.ReadWrite, (int) _bufferSize); } /// @@ -1384,7 +1407,7 @@ public SftpFileStream Create(string path, int bufferSize) { CheckDisposed(); - return new SftpFileStream(SftpSession, path, FileMode.Create, FileAccess.ReadWrite, bufferSize); + return new SftpFileStream(_sftpSession, path, FileMode.Create, FileAccess.ReadWrite, bufferSize); } /// @@ -1553,7 +1576,7 @@ public SftpFileStream Open(string path, FileMode mode, FileAccess access) { CheckDisposed(); - return new SftpFileStream(SftpSession, path, mode, access, (int) _bufferSize); + return new SftpFileStream(_sftpSession, path, mode, access, (int) _bufferSize); } /// @@ -1579,14 +1602,14 @@ public Task OpenAsync(string path, FileMode mode, FileAccess acc throw new ArgumentNullException(nameof(path)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } cancellationToken.ThrowIfCancellationRequested(); - return SftpFileStream.OpenAsync(SftpSession, path, mode, access, (int) _bufferSize, cancellationToken); + return SftpFileStream.OpenAsync(_sftpSession, path, mode, access, (int) _bufferSize, cancellationToken); } /// @@ -1636,7 +1659,7 @@ public SftpFileStream OpenWrite(string path) { CheckDisposed(); - return new SftpFileStream(SftpSession, path, FileMode.OpenOrCreate, FileAccess.Write, (int) _bufferSize); + return new SftpFileStream(_sftpSession, path, FileMode.OpenOrCreate, FileAccess.Write, (int) _bufferSize); } /// @@ -2019,14 +2042,14 @@ public SftpFileAttributes GetAttributes(string path) { CheckDisposed(); - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - return SftpSession.RequestLStat(fullPath); + return _sftpSession.RequestLStat(fullPath); } /// @@ -2041,14 +2064,14 @@ public void SetAttributes(string path, SftpFileAttributes fileAttributes) { CheckDisposed(); - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - SftpSession.RequestSetStat(fullPath, fileAttributes); + _sftpSession.RequestSetStat(fullPath, fileAttributes); } // Please don't forget this when you implement these methods: is null. @@ -2079,11 +2102,17 @@ public void SetAttributes(string path, SftpFileAttributes fileAttributes) /// If a problem occurs while copying the file public IEnumerable SynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern) { - return sourcePath is null - ? throw new ArgumentNullException(nameof(sourcePath)) - : string.IsNullOrWhiteSpace(destinationPath) - ? throw new ArgumentException("destinationPath") - : InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asynchResult: null); + if (sourcePath is null) + { + throw new ArgumentNullException(nameof(sourcePath)); + } + + if (string.IsNullOrWhiteSpace(destinationPath)) + { + throw new ArgumentException("destinationPath"); + } + + return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asynchResult: null); } /// @@ -2251,14 +2280,14 @@ private IEnumerable InternalListDirectory(string path, Action li throw new ArgumentNullException(nameof(path)); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - var handle = SftpSession.RequestOpenDir(fullPath); + var handle = _sftpSession.RequestOpenDir(fullPath); var basePath = fullPath; @@ -2269,13 +2298,13 @@ private IEnumerable InternalListDirectory(string path, Action li var result = new List(); - var files = SftpSession.RequestReadDir(handle); + var files = _sftpSession.RequestReadDir(handle); while (files is not null) { foreach (var f in files) { - result.Add(new SftpFile(SftpSession, + result.Add(new SftpFile(_sftpSession, string.Format(CultureInfo.InvariantCulture, "{0}{1}", basePath, f.Key), f.Value)); } @@ -2287,10 +2316,10 @@ private IEnumerable InternalListDirectory(string path, Action li ThreadAbstraction.ExecuteThread(() => listCallback(result.Count)); } - files = SftpSession.RequestReadDir(handle); + files = _sftpSession.RequestReadDir(handle); } - SftpSession.RequestClose(handle); + _sftpSession.RequestClose(handle); return result; } @@ -2317,14 +2346,14 @@ private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncR throw new ArgumentException("path"); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - using (var fileReader = ServiceFactory.CreateSftpFileReader(fullPath, SftpSession, _bufferSize)) + using (var fileReader = ServiceFactory.CreateSftpFileReader(fullPath, _sftpSession, _bufferSize)) { var totalBytesRead = 0UL; @@ -2381,19 +2410,19 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo throw new ArgumentException("path"); } - if (SftpSession is null) + if (_sftpSession is null) { throw new SshConnectionException("Client not connected."); } - var fullPath = SftpSession.GetCanonicalPath(path); + var fullPath = _sftpSession.GetCanonicalPath(path); - var handle = SftpSession.RequestOpen(fullPath, flags); + var handle = _sftpSession.RequestOpen(fullPath, flags); ulong offset = 0; // create buffer of optimal length - var buffer = new byte[SftpSession.CalculateOptimalWriteLength(_bufferSize, handle)]; + var buffer = new byte[_sftpSession.CalculateOptimalWriteLength(_bufferSize, handle)]; var bytesRead = input.Read(buffer, 0, buffer.Length); var expectedResponses = 0; @@ -2411,7 +2440,7 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo { var writtenBytes = offset + (ulong) bytesRead; - SftpSession.RequestWrite(handle, offset, buffer, offset: 0, bytesRead, wait: null, s => + _sftpSession.RequestWrite(handle, offset, buffer, offset: 0, bytesRead, wait: null, s => { if (s.StatusCode == StatusCodes.Ok) { @@ -2436,12 +2465,12 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo else if (expectedResponses > 0) { // Wait for expectedResponses to change - SftpSession.WaitOnHandle(responseReceivedWaitHandle, _operationTimeout); + _sftpSession.WaitOnHandle(responseReceivedWaitHandle, _operationTimeout); } } while (expectedResponses > 0 || bytesRead > 0); - SftpSession.RequestClose(handle); + _sftpSession.RequestClose(handle); } /// @@ -2451,7 +2480,7 @@ protected override void OnConnected() { base.OnConnected(); - SftpSession = CreateAndConnectToSftpSession(); + _sftpSession = CreateAndConnectToSftpSession(); } /// @@ -2463,10 +2492,10 @@ protected override void OnDisconnecting() // disconnect, dispose and dereference the SFTP session since we create a new SFTP session // on each connect - var sftpSession = SftpSession; + var sftpSession = _sftpSession; if (sftpSession is not null) { - SftpSession = null; + _sftpSession = null; sftpSession.Dispose(); } } @@ -2481,10 +2510,10 @@ protected override void Dispose(bool disposing) if (disposing) { - var sftpSession = SftpSession; + var sftpSession = _sftpSession; if (sftpSession is not null) { - SftpSession = null; + _sftpSession = null; sftpSession.Dispose(); } } From 231e747ab1387a4f1f9b01bbfff422fe247c891c Mon Sep 17 00:00:00 2001 From: "IngSoft, Patrick Thoma" Date: Fri, 13 Oct 2023 17:02:57 +0200 Subject: [PATCH 3/6] Test moved to separate file --- .../Classes/SftpClientTest.ListDirectory.cs | 18 ------------ .../SftpClientTest.ListDirectoryAsync.cs | 29 +++++++++++++++++++ 2 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectoryAsync.cs diff --git a/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs b/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs index 63afb33bb..f44016ecb 100644 --- a/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs +++ b/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs @@ -1,9 +1,5 @@ using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Renci.SshNet.Common; using Renci.SshNet.Tests.Properties; @@ -28,19 +24,5 @@ public void Test_Sftp_ListDirectory_Without_Connecting() } } } - - [TestMethod] - [TestCategory("Sftp")] - [ExpectedException(typeof(SshConnectionException))] - public async Task Test_Sftp_ListDirectoryAsync_Without_Connecting() - { - using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) - { - await foreach (var file in sftp.ListDirectoryAsync(".", CancellationToken.None)) - { - Debug.WriteLine(file.FullName); - } - } - } } } diff --git a/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectoryAsync.cs b/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectoryAsync.cs new file mode 100644 index 000000000..c800452eb --- /dev/null +++ b/src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectoryAsync.cs @@ -0,0 +1,29 @@ +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Renci.SshNet.Common; +using Renci.SshNet.Tests.Properties; + +namespace Renci.SshNet.Tests.Classes +{ + /// + /// Implementation of the SSH File Transfer Protocol (SFTP) over SSH. + /// + public partial class SftpClientTest + { + [TestMethod] + [TestCategory("Sftp")] + [ExpectedException(typeof(SshConnectionException))] + public async Task Test_Sftp_ListDirectoryAsync_Without_ConnectingAsync() + { + using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + { + await foreach (var file in sftp.ListDirectoryAsync(".", CancellationToken.None)) + { + Debug.WriteLine(file.FullName); + } + } + } + } +} From aedc32fd2801ecc6792ad53dd3791cc6c2165932 Mon Sep 17 00:00:00 2001 From: "IngSoft, Patrick Thoma" Date: Sat, 14 Oct 2023 07:27:17 +0200 Subject: [PATCH 4/6] Added condition to "Microsoft.Bcl.AsyncInterfaces" reference. --- src/Renci.SshNet/Renci.SshNet.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index 324e3722a..05f8220a1 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -13,7 +13,7 @@ - + From 2beb0c6d262a0a36b00b1be3d55b335318d6d24b Mon Sep 17 00:00:00 2001 From: "IngSoft, Patrick Thoma" Date: Sat, 14 Oct 2023 07:34:12 +0200 Subject: [PATCH 5/6] Undo intentation. --- src/Renci.SshNet/SftpClient.cs | 50 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 99fc3da02..ae8ba29af 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -1129,10 +1129,10 @@ public IAsyncResult BeginUploadFile(Stream input, string path, bool canOverride, try { InternalUploadFile(input, path, flags, asyncResult, offset => - { - asyncResult.Update(offset); - uploadCallback?.Invoke(offset); - }); + { + asyncResult.Update(offset); + uploadCallback?.Invoke(offset); + }); asyncResult.SetAsCompleted(exception: null, completedSynchronously: false); } @@ -2144,18 +2144,18 @@ public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destin var asyncResult = new SftpSynchronizeDirectoriesAsyncResult(asyncCallback, state); ThreadAbstraction.ExecuteThread(() => - { - try { - var result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult); + try + { + var result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult); - asyncResult.SetAsCompleted(result, completedSynchronously: false); - } - catch (Exception exp) - { - asyncResult.SetAsCompleted(exp, completedSynchronously: false); - } - }); + asyncResult.SetAsCompleted(result, completedSynchronously: false); + } + catch (Exception exp) + { + asyncResult.SetAsCompleted(exp, completedSynchronously: false); + } + }); return asyncResult; } @@ -2441,20 +2441,20 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo var writtenBytes = offset + (ulong) bytesRead; _sftpSession.RequestWrite(handle, offset, buffer, offset: 0, bytesRead, wait: null, s => - { - if (s.StatusCode == StatusCodes.Ok) { - _ = Interlocked.Decrement(ref expectedResponses); - _ = responseReceivedWaitHandle.Set(); - - // Call callback to report number of bytes written - if (uploadCallback is not null) + if (s.StatusCode == StatusCodes.Ok) { - // Execute callback on different thread - ThreadAbstraction.ExecuteThread(() => uploadCallback(writtenBytes)); + _ = Interlocked.Decrement(ref expectedResponses); + _ = responseReceivedWaitHandle.Set(); + + // Call callback to report number of bytes written + if (uploadCallback is not null) + { + // Execute callback on different thread + ThreadAbstraction.ExecuteThread(() => uploadCallback(writtenBytes)); + } } - } - }); + }); _ = Interlocked.Increment(ref expectedResponses); From 27bce46bc4eabfaaf796f742efe35142ff0f5190 Mon Sep 17 00:00:00 2001 From: "IngSoft, Patrick Thoma" Date: Sat, 14 Oct 2023 07:45:23 +0200 Subject: [PATCH 6/6] Removed unused constant. --- src/Renci.SshNet/Renci.SshNet.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index 05f8220a1..4ccf6c72e 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -20,8 +20,4 @@ FEATURE_SOCKET_TAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_EAP;FEATURE_DNS_SYNC;FEATURE_DNS_APM;FEATURE_DNS_TAP - - - $(DefineConstants);FEATURE_ASYNC_ENUMERABLE -