diff --git a/src/Downloader/ExceptionHelper.cs b/src/Downloader/ExceptionHelper.cs deleted file mode 100644 index f38884d4..00000000 --- a/src/Downloader/ExceptionHelper.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Net; -using System.Net.Security; -using System.Net.Sockets; -using System.Security.Cryptography.X509Certificates; - -namespace Downloader -{ - internal static class ExceptionHelper - { - internal static bool IsMomentumError(this Exception error) - { - if (error.HasSource("System.Net.Http", - "System.Net.Sockets", - "System.Net.Security")) - return true; - - if (error.HasTypeOf(typeof(WebException), typeof(SocketException))) - return true; - - return false; - } - - internal static bool HasTypeOf(this Exception exp, params Type[] types) - { - Exception innerException = exp; - while (innerException != null) - { - foreach (Type type in types) - { - if (innerException.GetType() == type) - return true; - } - - innerException = innerException.InnerException; - } - - return false; - } - - internal static bool HasSource(this Exception exp, params string[] sources) - { - Exception innerException = exp; - while (innerException != null) - { - foreach (string source in sources) - { - if (string.Equals(innerException.Source, source, StringComparison.OrdinalIgnoreCase)) - return true; - } - - innerException = innerException.InnerException; - } - - return false; - } - - /// - /// Sometime a server get certificate validation error - /// https://stackoverflow.com/questions/777607/the-remote-certificate-is-invalid-according-to-the-validation-procedure-using - /// - /// - /// - /// - /// - internal static bool CertificateValidationCallBack(object sender, - X509Certificate certificate, - X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - // If the certificate is a valid, signed certificate, return true. - if (sslPolicyErrors == SslPolicyErrors.None) - return true; - - // If there are errors in the certificate chain, look at each error to determine the cause. - if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) - { - if (chain?.ChainStatus != null) - { - foreach (X509ChainStatus status in chain.ChainStatus) - { - if (status.Status == X509ChainStatusFlags.NotTimeValid) - { - // If the error is for certificate expiration then it can be continued - return true; - } - else if ((certificate.Subject == certificate.Issuer) && - (status.Status == X509ChainStatusFlags.UntrustedRoot)) - { - // Self-signed certificates with an untrusted root are valid. - continue; - } - else if (status.Status != X509ChainStatusFlags.NoError) - { - // If there are any other errors in the certificate chain, the certificate is invalid, - // so the method returns false. - return false; - } - } - } - - // When processing reaches this line, the only errors in the certificate chain are - // untrusted root errors for self-signed certificates. These certificates are valid - // for default Exchange server installations, so return true. - return true; - } - else - { - // In all other cases, return false. - return false; - } - } - } -} diff --git a/src/Downloader/Extensions/Helpers/ExceptionHelper.cs b/src/Downloader/Extensions/Helpers/ExceptionHelper.cs new file mode 100644 index 00000000..cc5cf445 --- /dev/null +++ b/src/Downloader/Extensions/Helpers/ExceptionHelper.cs @@ -0,0 +1,112 @@ +using System; +using System.Net; +using System.Net.Security; +using System.Net.Sockets; +using System.Security.Cryptography.X509Certificates; + +namespace Downloader.Extensions.Helpers; + +internal static class ExceptionHelper +{ + internal static bool IsMomentumError(this Exception error) + { + if (error.HasSource("System.Net.Http", + "System.Net.Sockets", + "System.Net.Security")) + return true; + + if (error.HasTypeOf(typeof(WebException), typeof(SocketException))) + return true; + + return false; + } + + internal static bool HasTypeOf(this Exception exp, params Type[] types) + { + Exception innerException = exp; + while (innerException != null) + { + foreach (Type type in types) + { + if (innerException.GetType() == type) + return true; + } + + innerException = innerException.InnerException; + } + + return false; + } + + internal static bool HasSource(this Exception exp, params string[] sources) + { + Exception innerException = exp; + while (innerException != null) + { + foreach (string source in sources) + { + if (string.Equals(innerException.Source, source, StringComparison.OrdinalIgnoreCase)) + return true; + } + + innerException = innerException.InnerException; + } + + return false; + } + + /// + /// Sometime a server get certificate validation error + /// https://stackoverflow.com/questions/777607/the-remote-certificate-is-invalid-according-to-the-validation-procedure-using + /// + /// + /// + /// + /// + internal static bool CertificateValidationCallBack(object sender, + X509Certificate certificate, + X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + // If the certificate is a valid, signed certificate, return true. + if (sslPolicyErrors == SslPolicyErrors.None) + return true; + + // If there are errors in the certificate chain, look at each error to determine the cause. + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) + { + if (chain?.ChainStatus != null) + { + foreach (X509ChainStatus status in chain.ChainStatus) + { + if (status.Status == X509ChainStatusFlags.NotTimeValid) + { + // If the error is for certificate expiration then it can be continued + return true; + } + else if (certificate.Subject == certificate.Issuer && + status.Status == X509ChainStatusFlags.UntrustedRoot) + { + // Self-signed certificates with an untrusted root are valid. + continue; + } + else if (status.Status != X509ChainStatusFlags.NoError) + { + // If there are any other errors in the certificate chain, the certificate is invalid, + // so the method returns false. + return false; + } + } + } + + // When processing reaches this line, the only errors in the certificate chain are + // untrusted root errors for self-signed certificates. These certificates are valid + // for default Exchange server installations, so return true. + return true; + } + else + { + // In all other cases, return false. + return false; + } + } +} diff --git a/src/Downloader/Extensions/Helpers/FileHelper.cs b/src/Downloader/Extensions/Helpers/FileHelper.cs new file mode 100644 index 00000000..80ad13b1 --- /dev/null +++ b/src/Downloader/Extensions/Helpers/FileHelper.cs @@ -0,0 +1,73 @@ +using System; +using System.IO; + +namespace Downloader.Extensions.Helpers; + +internal static class FileHelper +{ + public static Stream CreateFile(string filename) + { + string directory = Path.GetDirectoryName(filename); + if (string.IsNullOrWhiteSpace(directory)) + { + return Stream.Null; + } + + if (Directory.Exists(directory) == false) + { + Directory.CreateDirectory(directory); + } + + return new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); + } + public static string GetTempFile() + { + return GetTempFile(Path.GetTempPath(), string.Empty); + } + public static string GetTempFile(string baseDirectory, string fileExtension) + { + if (string.IsNullOrWhiteSpace(baseDirectory)) + { + baseDirectory = Path.GetTempPath(); + } + + string filename = Path.Combine(baseDirectory, Guid.NewGuid().ToString("N") + fileExtension); + CreateFile(filename).Dispose(); + + return filename; + } + + public static long GetAvailableFreeSpaceOnDisk(string directory) + { + try + { + var drive = new DriveInfo(directory); + if (drive.IsReady) + { + return drive.AvailableFreeSpace; + } + + return 0L; + } + catch (ArgumentException) + { + // null or use UNC (\\server\share) paths not supported. + return 0L; + } + } + + public static void ThrowIfNotEnoughSpace(long actualNeededSize, params string[] directories) + { + if (directories != null) + { + foreach (string directory in directories) + { + var availableFreeSpace = GetAvailableFreeSpaceOnDisk(directory); + if (availableFreeSpace > 0 && availableFreeSpace < actualNeededSize) + { + throw new IOException($"There is not enough space on the disk `{directory}` with {availableFreeSpace} bytes"); + } + } + } + } +} \ No newline at end of file diff --git a/src/Downloader/FileHelper.cs b/src/Downloader/FileHelper.cs deleted file mode 100644 index 0a4db164..00000000 --- a/src/Downloader/FileHelper.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.IO; - -namespace Downloader -{ - internal static class FileHelper - { - public static Stream CreateFile(string filename) - { - string directory = Path.GetDirectoryName(filename); - if (string.IsNullOrWhiteSpace(directory)) - { - return Stream.Null; - } - - if (Directory.Exists(directory) == false) - { - Directory.CreateDirectory(directory); - } - - return new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); - } - public static string GetTempFile() - { - return GetTempFile(Path.GetTempPath(), string.Empty); - } - public static string GetTempFile(string baseDirectory, string fileExtension) - { - if (string.IsNullOrWhiteSpace(baseDirectory)) - { - baseDirectory = Path.GetTempPath(); - } - - string filename = Path.Combine(baseDirectory, Guid.NewGuid().ToString("N") + fileExtension); - CreateFile(filename).Dispose(); - - return filename; - } - - public static long GetAvailableFreeSpaceOnDisk(string directory) - { - try - { - var drive = new DriveInfo(directory); - if (drive.IsReady) - { - return drive.AvailableFreeSpace; - } - - return 0L; - } - catch (ArgumentException) - { - // null or use UNC (\\server\share) paths not supported. - return 0L; - } - } - - public static void ThrowIfNotEnoughSpace(long actualNeededSize, params string[] directories) - { - if (directories != null) - { - foreach (string directory in directories) - { - var availableFreeSpace = GetAvailableFreeSpaceOnDisk(directory); - if (availableFreeSpace > 0 && availableFreeSpace < actualNeededSize) - { - throw new IOException($"There is not enough space on the disk `{directory}` with {availableFreeSpace} bytes"); - } - } - } - } - } -} \ No newline at end of file