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