Skip to content

Commit 76332f3

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into net10
2 parents 5a59ac9 + 821f958 commit 76332f3

File tree

60 files changed

+1582
-5921
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1582
-5921
lines changed

src/Renci.SshNet/Common/Extensions.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Globalization;
66
#if !NET
77
using System.IO;
8+
using System.Threading.Tasks;
89
#endif
910
using System.Net;
1011
using System.Net.Sockets;
@@ -393,6 +394,29 @@ internal static void ReadExactly(this Stream stream, byte[] buffer, int offset,
393394
totalRead += read;
394395
}
395396
}
397+
398+
internal static Task<T> WaitAsync<T>(this Task<T> task, CancellationToken cancellationToken)
399+
{
400+
if (task.IsCompleted || !cancellationToken.CanBeCanceled)
401+
{
402+
return task;
403+
}
404+
405+
return WaitCore();
406+
407+
async Task<T> WaitCore()
408+
{
409+
TaskCompletionSource<T> tcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
410+
411+
using var reg = cancellationToken.Register(
412+
() => tcs.TrySetCanceled(cancellationToken),
413+
useSynchronizationContext: false);
414+
415+
var completedTask = await Task.WhenAny(task, tcs.Task).ConfigureAwait(false);
416+
417+
return await completedTask.ConfigureAwait(false);
418+
}
419+
}
396420
#endif
397421
}
398422
}
Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using System;
2-
#if NETFRAMEWORK
3-
using System.Runtime.Serialization;
4-
#endif // NETFRAMEWORK
1+
#nullable enable
2+
using System;
53

64
namespace Renci.SshNet.Common
75
{
@@ -10,7 +8,7 @@ namespace Renci.SshNet.Common
108
/// </summary>
119
#if NETFRAMEWORK
1210
[Serializable]
13-
#endif // NETFRAMEWORK
11+
#endif
1412
public class NetConfServerException : SshException
1513
{
1614
/// <summary>
@@ -23,34 +21,27 @@ public NetConfServerException()
2321
/// <summary>
2422
/// Initializes a new instance of the <see cref="NetConfServerException"/> class.
2523
/// </summary>
26-
/// <param name="message">The message.</param>
27-
public NetConfServerException(string message)
24+
/// <inheritdoc cref="Exception(string)" path="/param"/>
25+
public NetConfServerException(string? message)
2826
: base(message)
2927
{
3028
}
3129

3230
/// <summary>
3331
/// Initializes a new instance of the <see cref="NetConfServerException"/> class.
3432
/// </summary>
35-
/// <param name="message">The message.</param>
36-
/// <param name="innerException">The inner exception.</param>
37-
public NetConfServerException(string message, Exception innerException)
33+
/// <inheritdoc cref="Exception(string, Exception)" path="/param"/>
34+
public NetConfServerException(string? message, Exception? innerException)
3835
: base(message, innerException)
3936
{
4037
}
4138

4239
#if NETFRAMEWORK
43-
/// <summary>
44-
/// Initializes a new instance of the <see cref="NetConfServerException"/> class.
45-
/// </summary>
46-
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
47-
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
48-
/// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <see langword="null"/>.</exception>
49-
/// <exception cref="SerializationException">The class name is <see langword="null"/> or <see cref="Exception.HResult"/> is zero (0). </exception>
50-
protected NetConfServerException(SerializationInfo info, StreamingContext context)
40+
/// <inheritdoc/>
41+
protected NetConfServerException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
5142
: base(info, context)
5243
{
5344
}
54-
#endif // NETFRAMEWORK
45+
#endif
5546
}
5647
}
Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using System;
2-
#if NETFRAMEWORK
3-
using System.Runtime.Serialization;
4-
#endif // NETFRAMEWORK
1+
#nullable enable
2+
using System;
53

64
namespace Renci.SshNet.Common
75
{
@@ -10,7 +8,7 @@ namespace Renci.SshNet.Common
108
/// </summary>
119
#if NETFRAMEWORK
1210
[Serializable]
13-
#endif // NETFRAMEWORK
11+
#endif
1412
public class ProxyException : SshException
1513
{
1614
/// <summary>
@@ -23,34 +21,27 @@ public ProxyException()
2321
/// <summary>
2422
/// Initializes a new instance of the <see cref="ProxyException"/> class.
2523
/// </summary>
26-
/// <param name="message">The message.</param>
27-
public ProxyException(string message)
24+
/// <inheritdoc cref="Exception(string)" path="/param"/>
25+
public ProxyException(string? message)
2826
: base(message)
2927
{
3028
}
3129

3230
/// <summary>
3331
/// Initializes a new instance of the <see cref="ProxyException"/> class.
3432
/// </summary>
35-
/// <param name="message">The message.</param>
36-
/// <param name="innerException">The inner exception.</param>
37-
public ProxyException(string message, Exception innerException)
33+
/// <inheritdoc cref="Exception(string, Exception)" path="/param"/>
34+
public ProxyException(string? message, Exception? innerException)
3835
: base(message, innerException)
3936
{
4037
}
4138

4239
#if NETFRAMEWORK
43-
/// <summary>
44-
/// Initializes a new instance of the <see cref="ProxyException"/> class.
45-
/// </summary>
46-
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
47-
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
48-
/// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <see langword="null"/>.</exception>
49-
/// <exception cref="SerializationException">The class name is <see langword="null"/> or <see cref="Exception.HResult"/> is zero (0).</exception>
50-
protected ProxyException(SerializationInfo info, StreamingContext context)
40+
/// <inheritdoc/>
41+
protected ProxyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
5142
: base(info, context)
5243
{
5344
}
54-
#endif // NETFRAMEWORK
45+
#endif
5546
}
5647
}
Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
using System;
2-
#if NETFRAMEWORK
3-
using System.Runtime.Serialization;
4-
#endif // NETFRAMEWORK
1+
#nullable enable
2+
using System;
53

64
namespace Renci.SshNet.Common
75
{
86
/// <summary>
9-
/// The exception that is thrown when SCP error occurred.
7+
/// The exception that is thrown when an SCP error occurs.
108
/// </summary>
119
#if NETFRAMEWORK
1210
[Serializable]
13-
#endif // NETFRAMEWORK
11+
#endif
1412
public class ScpException : SshException
1513
{
1614
/// <summary>
@@ -23,34 +21,27 @@ public ScpException()
2321
/// <summary>
2422
/// Initializes a new instance of the <see cref="ScpException"/> class.
2523
/// </summary>
26-
/// <param name="message">The message.</param>
27-
public ScpException(string message)
24+
/// <inheritdoc cref="Exception(string)" path="/param"/>
25+
public ScpException(string? message)
2826
: base(message)
2927
{
3028
}
3129

3230
/// <summary>
3331
/// Initializes a new instance of the <see cref="ScpException"/> class.
3432
/// </summary>
35-
/// <param name="message">The message.</param>
36-
/// <param name="innerException">The inner exception.</param>
37-
public ScpException(string message, Exception innerException)
33+
/// <inheritdoc cref="Exception(string, Exception)" path="/param"/>
34+
public ScpException(string? message, Exception? innerException)
3835
: base(message, innerException)
3936
{
4037
}
4138

4239
#if NETFRAMEWORK
43-
/// <summary>
44-
/// Initializes a new instance of the <see cref="ScpException"/> class.
45-
/// </summary>
46-
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
47-
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
48-
/// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <see langword="null"/>.</exception>
49-
/// <exception cref="SerializationException">The class name is <see langword="null"/> or <see cref="Exception.HResult"/> is zero (0). </exception>
50-
protected ScpException(SerializationInfo info, StreamingContext context)
40+
/// <inheritdoc/>
41+
protected ScpException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
5142
: base(info, context)
5243
{
5344
}
54-
#endif // NETFRAMEWORK
45+
#endif
5546
}
5647
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#nullable enable
2+
using System;
3+
4+
using Renci.SshNet.Sftp;
5+
6+
namespace Renci.SshNet.Common
7+
{
8+
/// <summary>
9+
/// The exception that is thrown when an error occurs in the SFTP layer.
10+
/// </summary>
11+
#if NETFRAMEWORK
12+
[Serializable]
13+
#endif
14+
public class SftpException : SshException
15+
{
16+
/// <summary>
17+
/// Gets the status code that is associated with this exception.
18+
/// </summary>
19+
public StatusCode StatusCode { get; }
20+
21+
/// <summary>
22+
/// Initializes a new instance of the <see cref="SftpException"/> class.
23+
/// </summary>
24+
/// <param name="statusCode">The status code that indicates the error that occurred.</param>
25+
public SftpException(StatusCode statusCode)
26+
: this(statusCode, message: null, innerException: null)
27+
{
28+
}
29+
30+
/// <summary>
31+
/// Initializes a new instance of the <see cref="SftpException"/> class.
32+
/// </summary>
33+
/// <param name="statusCode">The status code that indicates the error that occurred.</param>
34+
/// <param name="message">The error message that explains the reason for the exception.</param>
35+
public SftpException(StatusCode statusCode, string? message)
36+
: this(statusCode, message, innerException: null)
37+
{
38+
}
39+
40+
/// <summary>
41+
/// Initializes a new instance of the <see cref="SftpException"/> class.
42+
/// </summary>
43+
/// <param name="statusCode">The status code that indicates the error that occurred.</param>
44+
/// <param name="message">The error message that explains the reason for the exception.</param>
45+
/// <param name="innerException">The exception that is the cause of the current exception.</param>
46+
public SftpException(StatusCode statusCode, string? message, Exception? innerException)
47+
: base(string.IsNullOrEmpty(message) ? GetDefaultMessage(statusCode) : message, innerException)
48+
{
49+
StatusCode = statusCode;
50+
}
51+
52+
private protected static string GetDefaultMessage(StatusCode statusCode)
53+
{
54+
#pragma warning disable IDE0072 // Add missing cases
55+
return statusCode switch
56+
{
57+
StatusCode.Ok => "The operation completed successfully.",
58+
StatusCode.NoSuchFile => "A reference was made to a file that does not exist.",
59+
StatusCode.PermissionDenied => "The user does not have sufficient permissions to perform the operation.",
60+
StatusCode.Failure => "An error occurred, but no specific error code exists to describe the failure.",
61+
StatusCode.BadMessage => "A badly formatted packet or SFTP protocol incompatibility was detected.",
62+
StatusCode.OperationUnsupported => "An attempt was made to perform an operation which is not supported.",
63+
_ => statusCode.ToString()
64+
};
65+
#pragma warning restore IDE0072 // Add missing cases
66+
}
67+
68+
#if NETFRAMEWORK
69+
/// <inheritdoc/>
70+
protected SftpException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
71+
: base(info, context)
72+
{
73+
}
74+
#endif
75+
}
76+
}

0 commit comments

Comments
 (0)