Skip to content

Commit adbb68e

Browse files
authored
Add UploadFileAsync override with canOverride (#1750)
fixes #1734
1 parent 4648e0a commit adbb68e

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

src/Renci.SshNet/ISftpClient.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,22 @@ public interface ISftpClient : IBaseClient
11331133
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
11341134
Task UploadFileAsync(Stream input, string path, CancellationToken cancellationToken = default);
11351135

1136+
/// <summary>
1137+
/// Asynchronously uploads a <see cref="Stream"/> to a remote file path.
1138+
/// </summary>
1139+
/// <param name="input">The <see cref="Stream"/> to write to the remote path.</param>
1140+
/// <param name="path">The remote file path to write to.</param>
1141+
/// <param name="canOverride">Whether the remote file can be overwritten if it already exists.</param>
1142+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
1143+
/// <returns>A <see cref="Task"/> that represents the asynchronous upload operation.</returns>
1144+
/// <exception cref="ArgumentNullException"><paramref name="input"/> or <paramref name="path"/> is <see langword="null"/>.</exception>
1145+
/// <exception cref="ArgumentException"><paramref name="path" /> is empty or contains only whitespace characters.</exception>
1146+
/// <exception cref="SshConnectionException">Client is not connected.</exception>
1147+
/// <exception cref="SftpPermissionDeniedException">Permission to upload the file was denied by the remote host. <para>-or-</para> An SSH command was denied by the server.</exception>
1148+
/// <exception cref="SshException">An SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
1149+
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
1150+
Task UploadFileAsync(Stream input, string path, bool canOverride, CancellationToken cancellationToken = default);
1151+
11361152
/// <summary>
11371153
/// Writes the specified byte array to the specified file, and closes the file.
11381154
/// </summary>

src/Renci.SshNet/SftpClient.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,15 +1077,32 @@ public void UploadFile(Stream input, string path, bool canOverride, Action<ulong
10771077

10781078
/// <inheritdoc />
10791079
public Task UploadFileAsync(Stream input, string path, CancellationToken cancellationToken = default)
1080+
{
1081+
return UploadFileAsync(input, path, canOverride: true, cancellationToken);
1082+
}
1083+
1084+
/// <inheritdoc />
1085+
public Task UploadFileAsync(Stream input, string path, bool canOverride, CancellationToken cancellationToken = default)
10801086
{
10811087
ArgumentNullException.ThrowIfNull(input);
10821088
ArgumentException.ThrowIfNullOrWhiteSpace(path);
10831089
CheckDisposed();
10841090

1091+
var flags = Flags.Write | Flags.Truncate;
1092+
1093+
if (canOverride)
1094+
{
1095+
flags |= Flags.CreateNewOrOpen;
1096+
}
1097+
else
1098+
{
1099+
flags |= Flags.CreateNew;
1100+
}
1101+
10851102
return InternalUploadFile(
10861103
input,
10871104
path,
1088-
Flags.Write | Flags.Truncate | Flags.CreateNewOrOpen,
1105+
flags,
10891106
asyncResult: null,
10901107
uploadCallback: null,
10911108
isAsync: true,

test/Renci.SshNet.IntegrationTests/OldIntegrationTests/SftpClientTest.Upload.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ public async Task Test_Sftp_Upload_And_Download_Async_1MB_File()
7474
await sftp.UploadFileAsync(file, remoteFileName).ConfigureAwait(false);
7575
}
7676

77+
// uploading again should not throw because of the default canOverride = true
78+
using (var file = File.OpenRead(uploadedFileName))
79+
{
80+
await sftp.UploadFileAsync(file, remoteFileName).ConfigureAwait(false);
81+
}
82+
83+
// uploading with canOverride = false should throw because the file already exists
84+
using (var file = File.OpenRead(uploadedFileName))
85+
{
86+
await Assert.ThrowsAsync<SftpException>(async () => await sftp.UploadFileAsync(file, remoteFileName, canOverride: false).ConfigureAwait(false));
87+
}
88+
7789
var downloadedFileName = Path.GetTempFileName();
7890

7991
using (var file = File.OpenWrite(downloadedFileName))

0 commit comments

Comments
 (0)